`
isiqi
  • 浏览: 16760279 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

fgetc, EOF 及其它

阅读更多

在另一个贴子中,我与一些朋友对 getc 展开了一些讨论. 由于觉得楼主最终未能明白
我的意思,所以我把我个人的看法总结出来,写在这里.我不太擅长说明,但已经尽力了.
任何人转本贴, 请务必把本人的名字写在显眼的位置. (win_hate)

约定编译器为 gcc2/x86:
所以 char, unsigned char 为 8 位, int 为 32 位

请参考 http://bbs.chinaunix.net/forum/23/20031223/229236.html

(1) 字节的读取

在正常的情况下, getc 以 unsigned char 的方式读取文件流, 扩张为一个整数,并返
回. 换言之, getc 从文件流中取一个字节, 并加上24个零,成为一个小于256的整数,
然后返回.

int c;
while ((c = fgetc (rfp))!= -1) // -1就是 EOF
fputc (c, wfp);

上面 fputc 中的 c 虽然是整数, 但在 fputc 将其写入文件流之前, 又把整数的高24位
去掉了, 因此 fgetc, putc 配合能够实现文件复制. 到目前为止, 把 c 定义为
char仍然是可行的, 但下面我们将看到,把 c 定义为 int 是为正确判段文件是否结束.

(2) 判断文件结束.

多数人认为文件中有一个EOF,用于表示文件的结尾. 但这个观点实际上是错误的,在文
件所包含的数据中,并没有什么文件结束符. 对getc 而言, 如果不能从文件中读取,
则返回一个整数 -1,这就是所谓的EOF. 返回 EOF 无非是出现了两种情况,一是文件已
经读完; 二是文件读取出错,反正是读不下去了.

请注意: 在正常读取的情况下, 返回的整数均小于256, 即0x0~0xFF. 而读不出返回的
是 0xFFFFFFFF. 但, 假如你用fputc把 0xFFFFFFFF 往文件里头写, 高24位被屏蔽,写入的将
是 0xFF. // lixforalpha 请注意这一点

(3) 0xFF 会使我们混淆吗?

不会, 前提是, 接收返回值的 c 要按原型定义为 int.

如果下一个读取的字符将为 0xFF, 则

int c;
c = fgetc (rfp); // c = 0x000000FF;
if (c != -1) // 当然不等, -1 是 0xFFFFFFFF
fputc (wfp); // 噢, OXFF 复制成功.

字符0xFF, 其本身并不是EOF.

(4) 将 c 定义 char

假定下一个读取的字符为 0xFF 则

char c;
c = fgetc (rfp); // fgetc(rfp)的值为 0x000000FF, 暗中降为字节, c = 0xFF
if (c != -1) // 字符与整数比较? c 被带符号(signed)扩展为0xFFFFFFFF, 喔噢,
条件成立,文件复制提前退出.

while ((c=fgetc(rfp))!=EOF) 中的判别条件成立, 文件复制结束! 意外中止.

(5) 将 c 定义为 unsigned char;

当读到文件末尾, 返回 EOF 也就是 -1 时,

unsigned char c;
c = fgetc (rfp); // fgetc (rfp)的值为EOF,即-1,即0xFFFFFFFF, 降格为字节, c=0xFF
if ( c!= -1) // c 被扩展为 0x000000FF, 永远不回等于 0xFFFFFFFF

所以这次虽然能正确复制 0xFF, 但却不能判断文件结束. 事实上,在 c 为 uchar 时,
c != -1 是永远成立的, 一个高质量的编译器, 比如 gcc会在编译时指出这一点.

(6) 为何需要feof?
FILE *fp;
fp 指向一个很复杂的数据结构, feof 是通过这个结构中的标志来判断文件是否结束的.
如果文件用 fgetc 读取, 刚好把最后一个字符读出时, fp 中的EOF标志不会打开,这时
用feof判断,将会得到文件尚未结束的结论.

fgetc 返回 -1 时, 我们仍无法确信文件已经结束, 因为可能是读取错误! 这时我们
需要 feof 和 ferror.

转自:http://bbs.chinaunix.net/viewthread.php?tid=233220

分享到:
评论

相关推荐

    C语言 文件操作(fopen, fclose, fputc, fgetc, feof)

    在C语言中,文件操作是程序与外部存储设备交互的重要方式。本文将深入探讨如何使用C语言中的几个关键...实际应用中,可能还需要结合其他函数和技巧,如文件指针的传递、多线程下的文件操作等,来满足更复杂的编程需求。

    第13讲6.2.14 读取文件屏幕显示.doc

    除了`fgetc()`,还可以使用其他函数如`fgets()`、`fread()`等来读取文件内容。`fgets()`可以一次读取一整行,而`fread()`通常用于二进制文件的读取,它们在处理大块数据时更为高效。不过,`fgetc()`更适合逐个字符地...

    stm32c8t6实现串口输入输出

    完成函数定义后,需要在`main.c`或者其他合适的地方包含这些重定向函数,并在`stdio.h`中指定`fputc`和`fgetc`的实现,如下所示: ```c #include // 先定义其他头文件和相关变量... void _write(int file, char ...

    13.第十三章 文件.txt

    打开文件,是建立文件的各种有关信息,并使文件指针指向该文件,以便进行其他操作。关闭文件则断开指针与文件之间的联系。 1.打开文件(fopen函数) 原型:FILE *fopen(char *filename, char *mode); ...

    C语言文件操作函数大全

    如果已到文件尾则返回非零值,其他情况返回0。 返回值:返回非零值代表已到达文件尾。 5. fflush函数:更新缓冲区 函数原型:int fflush(FILE *stream); 函数说明:fflush函数会强迫将缓冲区内的数据写回参数...

    feof fp 是什么意思

    例如,当`fgetc`或其他读取函数返回`EOF`时,可能是由于文件结束,也可能是因为读取过程中发生了错误。因此,正确的方法是在检查`feof`之前先检查读取函数的返回值。 总之,`feof(fp)`是C++Builder中处理文件I/O时...

    常用C语言文件操作函数大全1

    例如,如果文件流已经遇到错误,但你还希望继续处理其他文件,`clearerr()`就很有用。 2. `fclose()`:此函数用于关闭之前使用`fopen()`打开的文件。它会将缓冲区中的数据写入文件,并释放系统分配的文件资源。如果...

    实验8 文件实验1

    正确的做法是在while循环条件中将`fgetc(fp)`与`EOF`的比较放在外面,即`while((ch=fgetc(fp)) != EOF)`。另外,题目还要求使用`freopen`进行输入输出重定向,这允许我们将标准输入重定向到文件,或将标准输出重定向...

    常用C语言文件操作函数大全.doc

    返回值:返回非零值代表已到达文件尾,其他情况返回0。 作用:检测文件是否已经到达尾部,以便进行后续操作。 5. fflush() 函数 函数说明:fflush()函数会强迫将缓冲区内的数据写回参数stream指定的文件中。 ...

    关于C语言词法分析器的源代码

    - **实现**:使用`fgetc`函数读取字符,根据字符类型分别处理数字、标识符、关键字以及其他特殊符号。 #### 3. 关键字搜索 ```c int search(char *temp) { for (int i = 0; i ; i++) { if (!strcmp(reserve_...

    c语言函数大全

    C语言函数是编程过程中的重要组成部分,它们提供了一系列的功能,帮助开发者进行文件操作、输入输出以及其他数据处理。这里我们将详细探讨几个与文件操作相关的C语言函数。 1. `clearerr()`:这个函数用于清除文件...

    c语言文件读写操作代码.pdf

    4. **内存管理**:在读取文件时,应注意缓冲区的大小,避免读取的数据超出缓冲区大小,从而导致程序崩溃或其他问题。 #### 四、小结 本文详细介绍了C语言中进行文件读写的常用函数及其用法,这些函数可以帮助...

    C++ 的各种文件读写操作总结

    ### C++ 的各种文件读写操作总结 #### 一、基于C的文件操作 在C++编程中,尤其是在使用C++Builder...接下来的文章中,我们将继续探讨其他类型的文件操作技术,包括基于C++的标准库方法、基于Windows API的方法等。

    C语言第十章文件PPT课件.pptx

    `fgetc()`函数则用于从文件读取一个字符,返回值是读取的字符或EOF(-1)。这两个函数在处理字符输入输出时非常实用,例如在示例代码中,程序会读取用户输入的字符直到遇到"#",并将这些字符写入指定的文件。 除此...

    C,C++ 文件读写操作

    fgetc()函数则从文件读取一个字符,原型为 int fgetc(FILE *stream),返回读取的字符,如果到达文件末尾或发生错误,返回 EOF。 4.fseek() 和 ftell() fseek()用于改变文件位置指针,原型为 int fseek(FILE *stream...

    C程序设计文件的输入输出PPT课件.pptx

    关闭文件后,原文件指针可以重新打开其他文件。 6. **字符读取函数 `fgetc()`**: - `fgetc(fp)`函数从`fp`指向的文件读取一个字符,类似`getchar()`。成功读取返回读取的字符,遇到文件结束返回EOF。例如,`ch = ...

    常用C语言文件操作函数大全

    - **功能**: `fclose`用于关闭通过`fopen`或其他文件打开函数打开的文件。调用此函数时,会先将缓冲区中的任何待写入的数据刷新到磁盘上,然后释放与文件相关的所有资源。 - **返回值**: 如果关闭操作成功,`fclose`...

    C语言统计文本字数

    在C语言中,统计文本字数是一项基本的文件操作任务,它涉及到文件的打开、读取、处理以及关闭等步骤。下面将详细讲解如何利用C语言实现这一...通过理解这些基本概念和方法,你可以轻松地扩展到其他类型的文件操作任务。

Global site tag (gtag.js) - Google Analytics