对于标准库函数 fgets 和 getc 的疑问
<The C Programming Language>一书中提到了标准库中fgets函数的实现代码.如下:程序代码:
char* fgets(char *s, int n, FILE *iop) { register int c; register char *cs; cs = s; while(--n > 0 && (c = getc(iop)) != EOF ) if((*cs++ = c) == '\n') break; *cs = '\0'; return (c == EOF && cs == s) ? NULL : s; }
我写了一段测试fgets的代码,如下:
程序代码:
#include<stdio.h> int main() { FILE* fin; char *p = NULL; char s[100]; fin = fopen("Test.in","r"); /*test.in 文件中内容为 第一行:Hello 第二行:World 第三行:123*/ p = fgets(s,6,fin); /*p是为了测试fgets函数返回的是NULL还是数组s[100]的地址*/ printf("%s\n%x\n%x\n",s,s,p); /*三个输出分别是 读入的字符串, 字符串地址, fgets返回的值(char*型)*/ system("pause"); return 0; }
输出截图:
我的疑惑如下:
❤为什么测试代码中fgets函数的返回值就是输入参数s的值.因为按照<The C Programming Language>一书中提到的fgets的返回语句是这么写的
return (c == EOF && cs == s) ? NULL : s;
而我的测试语句是
fin = fopen("Test.in","r"); /*test.in 文件中内容为 第一行:Hello 第二行:World 第三行:123*/ p = fgets(s,6,fin); /*p是为了测试fgets函数返回的是NULL还是数组s[100]的地址*/
按我的理解,fgets函数应该是读到了Test.in文件中的Hello这5个字符(第一行末尾的换行符没有读入)到数组s[]中,并且在其后添加了'\0'. 而此时fgets并没有读到文件尾,所以fgets定义中用到的c=getc(iop)这一句c应该不等于EOF.因此,返回语句
return (c == EOF && cs == s) ? NULL : s;中c == EOF的值为0, 即fgets返回值应该为NULL. 可是我上面的输出结果显示,fgets的返回值是数组s[]的首地址,并不是我想的NULL,这也就是说,fgets返回的是s而不是NULL.
我是哪里错了嘛?
❤关于getc返回值何时为EOF,我在书中只找到这样的说明:"如果到达文件尾或者出现错误,该函数将返回EOF". 我上面的例子应该不是到达文件尾,那么难道是出错了??
❤我是在win7 64bit VS2010环境下测试的,又或者这是因为vs中的fgets函数不是按标准库的方法实现,而是略有出入,所以导致了上面的结果?我才疏学浅,找到了fgets的定义,无奈表示看不懂.像这样: 似乎看不到具体的定义.T_T
恳请各位不吝赐教,在此先谢过啦!~
[ 本帖最后由 mxd000000 于 2014-11-17 20:06 编辑 ]