Chinaunix首页 | 论坛 | 博客
  • 博客访问: 111829
  • 博文数量: 19
  • 博客积分: 1716
  • 博客等级: 上尉
  • 技术积分: 275
  • 用 户 组: 普通用户
  • 注册时间: 2010-02-25 14:03
文章分类

全部博文(19)

文章存档

2011年(8)

2010年(11)

我的朋友

分类: C/C++

2010-09-21 13:54:30

文件

C程序,将文件看做是连续字节序列,其中每个字节都可以单独读取.这个与UNIX环境中的文件结构是一致的.ANSI C为了与其他的OS环境兼容(比如Windows),提供了两种文件视图文本视图和二进制视图.

文本视图和二进制视图

二进制视图中,文件中的每个字节都可以为程序访问.但文本视图中,程序中看到的内容与文件的内容可能不同.

例如MS-DOS文本文件用"\r\n"来表示行尾; Macintosh文本文件中用"\r"表示行尾; C程序使用"\n"表示行尾. So,如果C程序以文本视图模式处理一个MS-DOS文本文件,在读取文件时,就会将"\r\n"转换为"\n",在写入文件时,就会将"\n"转换为"\r\n". Macintosh同理.

说白了,两种视图的实现是一样的,只是在处理行尾或处理文件结尾时有点不同而已.采用某种视图打开文件时,注意一下就是了.

文件结尾和换行

文件读取数据的程序需要在达到文件结尾时停止.当到达文件结尾时,"getc()"函数会返回一个特殊值EOF.所以C程序只有在读取超出文件结尾后,才会发现文件的结尾.

为了避免读取空文件带来的问题,应该对文件输入使用入口条件循环(使用whilefor,避免使用do...while)如下设计:

    int ch;      // Watching EOF

    FILE* fp;

    fp = fopen ("_FileName", "_Mode");

    ch = getc (fp);

 

    while (ch != EOF)

    {

        putchar (ch);

        ch = getc (fp);

    }

    int ch;        // Watching EOF

    FILE* fp;

    fp = fopen ("_FileName", "_Mode");

    while ((ch = getc (fp)) != EOF)

    {

        putchar (ch);

    }

 

 

上面的例子可以看做是一个框架,来进行文件结尾的判断.ANSI C的两种模式,对于文件结尾有不同的解释.

如果文件以文本模式打开,C可以认出EOF标志文件结尾.如果以二进制模式打开,就会把EOF当做是文件中的一个字符.真正的文件结尾还在后面.文件的结尾,可能紧跟着EOF,当然,也可能用空字符弹不文件使其大小为256(或其他数)的倍数.DOS下不打印空字符.程序中包含了防止程序打印EOF字符的代码.

MS-DOS的文本文件用二进制模式和文本模式打开,C程序将看到下面的内容:

二进制模式打开文件C程序看到的内容:

line1\r\n

line2\r\n

line3\r\n

^Z

文本模式打开文件C程序看到的内容:

line1\n

line2\n

line3\n

^Z

 

下面是一个例子,用于逆序输出一个文件的内容.

    #include 

    #include 

    #define CNTL_Z '\032' /* DOS Text File End Of File Flag */

    #define SLEN   50

    int main (void)

    {

        unsigned char file[SLEN];

        unsigned char ch;

        FILE           *fp;

        unsigned long count;

        unsigned long last;

        puts ("Enter Name Of File To Be Processed : ");

        gets (file);

        if ((fp = fopen (file, "rb")) == NULL)

        {

            printf ("Reverse Can't Open %s .\n", file);

            exit (1);

        }

        fseek (fp, 0L, SEEK_END);   /* Locate To End Of File */

        last = ftell (fp);

        for (count = 1L; count <= last; count++)

        {

            fseek (fp, -count, SEEK_END);  /* Back 1 Byte */

            ch = getc (fp);

            if (ch != CNTL_Z && ch != '\r')

            {

                putchar (ch);

            }

    #if defined MAC || defined WIN32

            /* Macintosh || Windows */

            if (ch == '\r')

            {

                putchar ('\n');

            }

            else

            {

                putchar (ch);

            }

    #endif

            putchar ('\n');

            fclose (fp);

            return 0;

        }

    }

阅读(1538) | 评论(0) | 转发(0) |
0

上一篇:Rtmp中的对话通道

下一篇:lseek和空洞文件

给主人留下些什么吧!~~