[英]How to read input in C
我正在嘗試用scanf("%[^\\n]")
讀取一行scanf("%[^\\n]")
; 就在它之前,我正在讀一個帶有“%d”的整數,有人告訴我,scanf在閱讀后不會刪除'\\ n',所以我必須調用fflush()來避免它,但即便這樣做我仍然有同樣的問題,所以這是我的代碼:
scanf("%d", &n);
fflush(stdin);
lines = (char**)malloc(sizeof(char*)*n);
for(i = 0; i < n; i++){
lines[i] = (char*)malloc(sizeof(char)*1001);
}
for(i = 0;i < n;i++){
scanf("%[^\n]", linhes[i]);
}
我讀取一個整數,然后scanf不等待,它開始讀取輸入 - 無論整數值是什么,無論是5還是10,scanf都會讀取所有字符串為空。 已經嘗試了fgets,結果幾乎相同,只是它讀取了一些字符串並跳過其他字符串。
讓我們一步一步地看一下:
“...用scanf讀取一行(”%[^ \\ n]“);”。
scanf("%[^\\n]", buf)
不讀取一行。 它幾乎 - 有時 - 。 "%[^\\n]"
指示scanf()
讀取任意數量的非'\\n'
char
直到遇到一個(然后將'\\n'
放回到stdin
)或發生EOF。
這種方法有一些問題:
char
是'\\n'
,則scanf()
會將其放回stdin
而不會改變buf
! buf
保持原樣 - 也許是未初始化的 。 scanf()
然后返回0。 '\\n'
,則將其保存到buf
和更多char
直到出現'\\n'
。 一個'\\0'
被附加到buf
並且'\\n'
被放回到stdin
而scanf()
返回1.這個無限制可以很容易地溢出 buf
。 如果沒有保存char
並且發生EOF
或輸入錯誤,則scanf()
返回EOF
。 scanf()
/ fgets()
等函數的返回值 。 如果您的代碼沒有檢查它,則buf
的狀態是未知的。 在任何情況下, '\\n'
仍然通常留在stdin
,因此該行未被完全讀取。 這個'\\n'
通常是下一個輸入函數的問題。
... scanf在讀取后不會刪除'\\ n'
另一個常見的誤解。 scanf()
讀取'\\n'
或不讀取,具體取決於提供的格式。 有些格式消耗'\\n'
,有些則不消耗。
...調用fflush()來避免它
fflush(stdin)
在某些編譯器中定義明確,但不符合C標准。 通常的問題是代碼想要消除stdin
任何剩余數據。 當線路末端尚未發生時,常見的替代方案是讀取並處置,直到找到'\\n'
:
int ch; // Use int
while ((ch = fgetc(stdin)) != '\n' && ch != EOF);
我仍然有同樣的問題
最好的解決方案IMO是讀取一行用戶輸入然后掃描它。
char buf[sizeof lines[i]];
if (fgets(buf, sizeof buf, stdin) == NULL) return NoMoreInput();
// If desired, remove a _potential_ trailing \n
buf[strcspn(buf, "\n")] = 0;
strcpy(lines[i], buf);
我建議緩沖區大小應該是典型代碼預期輸入大小的2倍。 強大的代碼,而不是此代碼段,將檢測是否需要讀取更多行。 國際海事組織,這種過長的線路往往是黑客的標志,而不是合法使用。
評論中的BLUEPIXY回答了我的問題:
嘗試
"%[^\\n]"
更改為" %[^\\n]"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.