我不明白为什么我的 while 循环不起作用。没有它,代码也能正常工作……代码的目的是在 bin 文件中查找 secret 消息。所以我得到了找到字母的代码,但是现在当我试图让它循环到文件末尾时,它不起作用。我是新来的。我做错了什么?
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 的新字符来修复它,然后将我的代码替换为:
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
时会发生以下两种情况之一:
- 如果普通
char
是无符号的,则 EOF 将转换为 0xFF,并且 0xFF != EOF,因此循环永远不会终止。 - 如果普通
char
被签名,则 EOF 相当于一个有效字符(在 8859-1 代码集中,即 ÿ、y-umlaut、U+00FF、带分音符的拉丁文小写字母 Y ),您的循环可能会提前终止。
鉴于您面临的问题,我们可以初步猜测您将纯 char
作为无符号类型。
getc()
等返回 int
的原因是它们必须返回所有可能适合 char
的值还有一个独特的值(value),EOF。在 C 标准中,它说:
ISO/IEC 9899:2011 §7.21.7.1 The
fgetc()
function
int fgetc(FILE *stream);
If the end-of-file indicator for the input stream pointed to by
stream
is not set and a next character is present, thefgetc
function obtains that character as anunsigned char
converted to anint
...If the end-of-file indicator for the stream is set, or if the stream is at end-of-file, the end-of- file indicator for the stream is set and the
fgetc
function returns EOF.
类似的措辞适用于 getc()
函数和 getchar()
函数:它们被定义为像 fgetc()
函数,除了如果 getc()
被实现为一个宏,它可能会随意使用通常不会授予标准宏的文件流参数——具体来说,流参数表达式可能会被计算多次, 因此调用带有副作用的 getc()
(getc(fp++)
) 是非常愚蠢的(但更改为 fgetc()
它将安全,但仍然古怪)。
在你的循环中,你可以使用:
int c;
while ((c = getc(message)) != EOF) {
keep[0] = c;
这将保留赋值给keep[0]
;我不确定您是否真的需要它。
您应该检查对 fgets()
、getc()
、fread()
的其他调用,以确保您得到了什么你期望作为输入。尤其是在输入方面,您真的不能跳过这些检查。迟早会出问题,如果您不仔细检查返回状态,您的代码可能会崩溃,或者只是“出错”。
关于c - while (( c = getc(file)) != EOF) 循环不会停止执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13694394/