Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1780976
  • 博文数量: 413
  • 博客积分: 8399
  • 博客等级: 中将
  • 技术积分: 4325
  • 用 户 组: 普通用户
  • 注册时间: 2011-06-09 10:44
文章分类

全部博文(413)

文章存档

2015年(1)

2014年(18)

2013年(39)

2012年(163)

2011年(192)

分类: C/C++

2011-11-18 13:26:53

在 上看到一转载的文章“EOF是什么?”文章的原网址为:/blog/2011/11/eof.html
其中后面有很多的回复。仔细读读,很有理会。
我也给出了自己的理解。
我任为iSayme的说法是正确的:

应该是这样吧:
首先肯定的是返回值都是int型的。
如果读二进制读到-1,则其实读到的是0xff,fgetc返回时将其转为int型即0x00ff,对于int型来说,0x00ff不等于-1;
如果fgetc返回值是-1,则说明返回的是int型的-1即0xffff;


man fgetc如下:
fgetc() reads the next character from stream and returns it as an unsigned char cast to an int, or EOF on end of file or error.
另外我提到K&R中提到一个相关的经典bug:
  1. char      c;

  2. while((c = fgetc(stdin)) != EOF)
  3.        putchar(c);
这里fgetc(stdin)返回时,由unsigned char 转换到 int型,然后在赋值操作 c = fgetc(stdin) 时又由 int 转换到了char型。最后在 c 与 EOF比较时,又由 char 转换到 int型。

但是问题来了,在 c 与 EOF的比较时,可能会出现bug:
1)如果系统的char默认是signed char,那么没有问题,因为当fgetc(stdin)读到EOF时,c = 0xff, 然后在与EOF比较时,作为 signed char 的 c 转换到int: (int)c = 0xffff == EOF,可以正确的表示读取到了文件末尾的概念。
2)但是,如果系统的char默认是unsigned char,那么就有问题,因为当fgetc(stdin)读到EOF时,c = 0xff, 然后在与EOF比较时,作为 unsigned char 的 c 转换到int: (int)c = 0xff != EOF,不能正确的表示读取到了文件末尾的概念。所以导致了死循环。

给出一段验证代码:

  1. #include
  2. int main()
  3. {
  4.       signed char sc = 0xff;
  5.       unsigned char uc = 0xff;
  6.       int i = sc;
  7.       int j = uc;
  8.       int eof = -1; // END OF FILE

  9.       printf("i = %d = 0x%x\n", i, i);
  10.       printf("j = %d = 0x%x\n", j, j);
  11.       printf("sc == eof: %d\n", (sc == eof));
  12.       printf("uc == eof: %d\n", (uc == eof));

  13.       return 0;
  14. }

运行结果:

  1. digdeep@ubuntu:~/uulp$ ./char
  2. i = -1 = 0xffffffff
  3. j = 255 = 0xff
  4. sc == eof: 1
  5. uc == eof: 0


阅读(1080) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~