而((c = getc(file))!= EOF)循环不会停止执行
我无法弄清楚为什么我的while循环不起作用。 代码在没有它的情况下正常工作……代码的目的是在bin文件中查找秘密消息。 所以我得到了代码来找到这些字母,但现在当我试图让它循环到文件的末尾时,它不起作用。 我是新来的。 我究竟做错了什么?
main(){ FILE* message; int i, start; long int size; char keep[1]; message = fopen("c:\\myFiles\\Message.dat", "rb"); if(message == NULL){ printf("There was a problem reading the file. \n"); exit(-1); } //the first 4 bytes contain an int that tells how many subsequent bytes you can throw away fread(&start, sizeof(int), 1, message); printf("%i \n", start); //#of first 4 bytes was 280 fseek(message, start, SEEK_CUR); //skip 280 bytes keep[0] = fgetc(message); //get next character, keep it printf("%c", keep[0]); //print character while( (keep[0] = getc(message)) != EOF) { fread(&start, sizeof(int), 1, message); fseek(message, start, SEEK_CUR); keep[0] = fgetc(message); printf("%c", keep[0]); } fclose(message); system("pause"); }
编辑:
在调试器中查看我的代码之后,看起来在while循环中使用“getc”会将所有内容都抛弃。 我通过创建一个名为letter的新char来修复它,然后用以下代码替换我的代码:
fread(&start, sizeof(int), 1, message); fseek(message, start, SEEK_CUR); while( (letter = getc(message)) != EOF) { printf("%c", letter); fread(&start, sizeof(int), 1, message); fseek(message, start, SEEK_CUR); }
它现在就像一个魅力。 当然欢迎任何更多的建议。 感谢大家。
getc()
及其亲属的返回值是int
,而不是char
。
如果将getc()
的结果赋给char
,则返回EOF
时会发生以下两种情况之一:
- 如果plain
char
是无符号的,那么EOF将转换为0xFF,并且0xFF!= EOF,因此循环永远不会终止。 - 如果普通
char
被签名,则EOF相当于一个有效字符(在8859-1代码集中,即ÿ,y-umlaut,U + 00FF,带有DIAERESIS的LATIN SMALL LETTER Y),并且您的循环可能会提前终止。
鉴于您遇到的问题,我们可以暂时猜测您将普通char
作为无符号类型。
getc()
等返回int
是它们必须返回可以适合char
每个可能值以及不同的值EOF。 在C标准中,它说:
ISO / IEC 9899:2011§7.21.7.1fgetc
fgetc()
函数
int fgetc(FILE *stream);
如果未设置stream指向的输入流的文件结束指示符并且存在下一个字符,则
fgetc
函数将该字符作为转换为int
的unsigned char
获取…如果设置了流的文件结束指示符,或者流位于文件结尾,则设置流的文件结束指示符,并且
fgetc
函数返回EOF。
类似的措辞适用于getc()
函数和getchar()
函数:它们的定义与fgetc()
函数类似,只是如果将getc()
实现为宏,则可能需要使用文件流参数自由。通常不会授予标准宏 – 具体来说,流参数表达式可能会被多次评估,因此调用具有副作用的getc()
( getc(fp++)
)非常愚蠢(但更改为fgetc()
并且它将是安全的,但仍然古怪)。
在你的循环中,你可以使用:
int c; while ((c = getc(message)) != EOF) { keep[0] = c;
这保留了keep[0]
的赋值; 我不确定你真的需要它。
你应该检查对fgets()
, getc()
, fread()
的其他调用,以确保你得到你期望的输入。 特别是在输入时,你真的不能跳过这些检查。 如果你没有虔诚地检查返回状态,你的代码很可能会崩溃,或者只是“出错”。
getc()
可能返回256个不同的char
值,并存储在一个char
变量中,如keep[0]
(是的,我疯狂地过度使用)。 要可靠地检测文件结尾, EOF
必须具有与所有文件不同的值。 这就是为什么getc()
返回int
而不是char
:因为EOF
的第257个不同值不适合char
。
因此,您需要将getc()
返回的值存储在int
,直到您针对EOF
检查:
int tmpc; while( (tmpc = getc(message)) != EOF) { keep[0] = tmpc; ...