While (( c = getc(file)) != EOF) 循环不会停止执行 [英] While (( c = getc(file)) != EOF) loop won't stop executing

查看:28
本文介绍了While (( c = getc(file)) != EOF) 循环不会停止执行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不明白为什么我的 while 循环不起作用.没有它,代码也能正常工作......代码的目的是在 bin 文件中找到一条秘密消息.所以我得到了找到这些字母的代码,但是现在当我尝试让它循环到文件末尾时,它不起作用.我是新手.我做错了什么?

I can't figure out why my while loop won't work. The code works fine without it... The purpose of the code is to find a secret message in a bin file. So I got the code to find the letters, but now when I try to get it to loop until the end of the file, it doesn't work. I'm new at this. What am I doing wrong?

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. 
");
    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 
", 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 的新字符来修复它,然后用这个替换我的代码:

After looking at my code in the debugger, it looks like having "getc" in the while loop threw everything off. I fixed it by creating a new char called letter, and then replacing my code with this:

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);
}

它现在就像一个魅力.任何更多的建议当然是受欢迎的.谢谢大家.

It works like a charm now. Any more suggestions are certainly welcome. Thanks everyone.

推荐答案

getc() 及其亲属的返回值是一个 int,而不是一个 字符.

The return value from getc() and its relatives is an int, not a char.

如果您将 getc() 的结果分配给 char,当它返回 EOF 时会发生以下两种情况之一:

If you assign the result of getc() to a char, one of two things happens when it returns EOF:

  • 如果普通的 char 是无符号的,那么 EOF 将转换为 0xFF,并且 0xFF != EOF,因此循环永远不会终止.
  • 如果纯 char 是有符号的,那么 EOF 等效于一个有效字符(在 8859-1 代码集中,即 ÿ、y-umlaut、U+00FF、LATIN SMALL LETTER Y WITH DIAERESIS),并且您的循环可能会提前终止.
  • If plain char is unsigned, then EOF is converted to 0xFF, and 0xFF != EOF, so the loop never terminates.
  • If plain char is signed, then EOF is equivalent to a valid character (in the 8859-1 code set, that's ÿ, y-umlaut, U+00FF, LATIN SMALL LETTER Y WITH DIAERESIS), and your loop may terminate early.

鉴于您面临的问题,我们可以初步猜测您将纯 char 作为无符号类型.

Given the problem you face, we can tentatively guess you have plain char as an unsigned type.

getc() 等人返回 int 的原因是他们必须返回可以放入 char 的所有可能值还有一个独特的价值,EOF.在 C 标准中,它说:

The reason that getc() et al return an int is that they have to return every possible value that can fit in a char and also a distinct value, EOF. In the C standard, it says:

ISO/IEC 9899:2011 §7.21.7.1 fgetc() 函数

ISO/IEC 9899:2011 §7.21.7.1 The fgetc() function

int fgetc(FILE *stream);

如果 stream 指向的输入流的文件结束指示符没有设置并且一个存在下一个字符,fgetc 函数将该字符作为 unsigned char 转换为 int ...

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 ...

如果设置了流的文件尾指示符,或者如果流位于文件尾,则结束-设置了流的文件指示符并且 fgetc 函数返回 EOF.

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() 并且它会安全,但仍然古怪).

Similar wording applies to the getc() function and the getchar() function: they are defined to behave like the fgetc() function except that if getc() is implemented as a macro, it may take liberties with the file stream argument that are not normally granted to standard macros — specifically, the stream argument expression may be evaluated more than once, so calling getc() with side-effects (getc(fp++)) is very silly (but change to fgetc() and it would be safe, but still eccentric).

在你的循环中,你可以使用:

In your loop, you could use:

int c;

while ((c = getc(message)) != EOF) {
    keep[0] = c;

这保留了对 keep[0] 的赋值;我不确定您是否真的需要它.

This preserves the assignment to keep[0]; I'm not sure you truly need it.

您应该检查对 fgets()getc()fread() 的其他调用,以确保您得到了什么你期望作为输入.尤其是在输入方面,您真的不能跳过这些检查.迟早会出错,如果您不认真检查返回状态,您的代码很可能会崩溃,或者只是出错".

You should be checking the other calls to fgets(), getc(), fread() to make sure you are getting what you expect as input. Especially on input, you cannot really afford to skip those checks. Sooner, rather than later, something will go wrong and if you aren't religiously checking the return statuses, your code is likely to crash, or simply 'go wrong'.

这篇关于While (( c = getc(file)) != EOF) 循环不会停止执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆