c - while (( c = getc(file)) != EOF) 循环不会停止执行

标签 c file input output

我不明白为什么我的 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, the fgetc function obtains that character as an unsigned char converted to an int ...

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/

相关文章:

c - C中读取字符串数组

c - 如何将已编译库的源路径链接到 Eclipse 中的不同位置?

c - C 中的高级数据结构

c# - 如何比较 2 个 .csv 文件并创建一个包含两个 csv 文件的部分的新 .csv?

Java 在文件被修改时获取通知

C++字符串和文件输入

css - 如何在 CSS 中引用附加了类的输入?

c - 无论如何释放空指针或先检查?

java - 按预定义的顺序读取输入

java - 如何从java中的文件夹中获取单个文件?