[英]How to iterate through a file twice by using while((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
時會發生以下兩種情況之一:
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.