簡體   English   中英

而((c = getc(file))!= EOF)循環不會停止執行

[英]While (( c = getc(file)) != EOF) loop won't stop executing

我無法弄清楚為什么我的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),並且您的循環可能會提前終止。

鑒於您遇到的問題,我們可以暫時猜測您將普通char作為無符號類型。

getc()等返回int是它們必須返回每個可能適合char值以及不同的值EOF。 在C標准中,它說:

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

int fgetc(FILE *stream);

如果輸入流中的結束文件指針指向的stream沒有設置和下一個字符存在,則fgetc函數獲取字符作為unsigned char轉換為int ...

如果設置了流的文件結束指示符,或者流位於文件結尾,則設置流的文件結束指示符,並且fgetc函數返回EOF。

類似的措辭適用於getc()函數和getchar()函數:它們的定義與fgetc()函數類似,只是如果將getc()實現為宏,則可能需要使用文件流參數自由。通常不會授予標准宏 - 具體來說,可以多次計算stream參數表達式,因此調用帶副作用的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;
    ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM