[英]Why “scanf” works but fgets doesn't works in C?
在這里,我認為這兩個程序應該等效。 但是顯然它們不是,因為第一個程序有效,而第二個程序無效。 有人可以向我解釋一下,為什么fgets()無法完成這項工作?
// FIRST PROGRAM : WORKS FINE
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *stream;
char fileName[67];
scanf("%s", fileName);
printf("%s", fileName);
stream = fopen(fileName, "r");
char ch;
if(stream){
ch = fgetc(stream);
while(!feof(stream)){
putchar(ch);
ch = fgetc(stream);
}
fclose(stream);
}
}
// SECOND PROGRAM: DOES NOT WORK
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *stream;
char fileName[67];
fgets(fileName, 67, stdin);
printf("%s", fileName);
stream = fopen(fileName, "r");
char ch;
if(stream){
ch = fgetc(stream);
while(!feof(stream)){
putchar(ch);
ch = fgetc(stream);
}
fclose(stream);
}
}
我兩次都在控制台中輸入“ test.txt”,然后按Enter。 當然test.txt存在於正確的目錄中
原因是fgets()
保留輸入的newline
。 您可以通過將打印語句更改為
printf("[%s]", filename);
當]
出現在下一行時。 您可以這樣刪除尾隨的newline
#include <string.h>
...
filename [ strcspn(filename, "\r\n") ] = 0;
Weather Vane可以正確解決您遇到的主要問題,但是我想指出您的代碼的另一個問題:讀取和寫入文件內容的循環不正確。 大多數情況下,使用feof(stream)
測試文件結尾會導致錯誤的行為。 就您而言,從stream
讀取錯誤將導致您的程序無限循環,將0xFF
字節寫入stdout
。
有一種更簡單和慣用的方式來實現此循環:
if (stream) {
int ch;
while ((ch = fgetc(stream)) != EOF) {
putchar(ch);
}
fclose(stream);
}
如您所見,當輸入失敗時,它更簡單並且可以在正確的時間正確地測試EOF
。 它將fgetc()
的返回值存儲到一個int
變量中,該變量可以保存fgetc()
所有可能的返回值。 使用int
是必要的,因為將char
值與EOF
進行比較通常會失敗,如果char
類型是未簽名的,或者如果char
是已簽名的並且具有值'\\377'
則可能給出假肯定。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.