我應該使用fgets或格式化scanf為scanf("s", foo).
除了scanf不讀取空白字符,這可以解決并使用scanset做更多的事情,那么為什么我應該使用fgets而不是scanf?
任何幫助,將不勝感激。
編輯
我想問的另一件事是:即使我們使用fgets如果用戶輸入的字符超過邊界(我的意思是很多字符)會發生什么,它是否會導致緩沖區溢位?那怎么處理呢?
uj5u.com熱心網友回復:
在大多數作業系統上,默認情況下,用戶輸入是基于行的。這樣做的一個原因是允許用戶在將輸入發送到程式之前按退格鍵來更正輸入。
對于基于行的用戶輸入,程式一次讀取一行輸入是有意義且直觀的。這就是函式fgets所做的(假設緩沖區足夠大以存盤整行輸入)。
scanf另一方面,函式通常不會一次讀取一行輸入。例如,當您將%sor%d轉換格式說明符與 一起使用時scanf,它不會消耗整行輸入。相反,它只會消耗與轉換格式說明符匹配的輸入。這意味著行尾的換行符通常不會被消耗(這很容易導致編程錯誤)。此外,scanf使用%d轉換格式說明符呼叫將考慮輸入,例如6sldf23dsfh2number 的有效輸入6,但任何scanf使用相同說明符的進一步呼叫都將失敗,除非您從輸入流中丟棄該行的其余部分。
在處理基于行的用戶輸入時scanf, 的這種行為是違反直覺的,而 的行為fgets是直觀的。
使用后fgets,您可以sscanf在字串上使用該函式,用于決議單個行的內容。這將允許您繼續使用掃描集。或者您可以通過其他方式決議該行。無論哪種方式,只要您使用fgets而不是scanf讀取輸入,您將一次處理一行輸入,這是處理基于行的用戶輸入的自然而直觀的方式。
當我們使用
fgets如果用戶輸入的字符超過邊界(我的意思是很多字符)會發生什么,它會導致緩沖區溢位嗎?那怎么處理呢?
如果用戶輸入的字符多于第二個fgets函式引數指定的緩沖區中的字符數,則它不會溢位緩沖區。相反,它只會從輸入流中提取緩沖區中適合的字符數。您可以通過檢查字串'\n'末尾是否包含換行符來確定是否讀取了整行。
uj5u.com熱心網友回復:
這是一個經常討論的話題,充滿了意見,但仍然很有趣。我觀察到,大多數已經在本網站上回答過類似問題的人都站在fgets(). 我是其中之一。我發現fgets()用于用戶輸入比scanf()在少數例外情況下要好得多。scanf()被許多人認為是處理用戶輸入的次優方法。例如
“......它會告訴你它是成功還是失敗,但只能告訴你它失敗的大致位置,而根本不能告訴你失敗的原因或原因。你幾乎沒有機會進行任何錯誤恢復。”
(詹姆斯德林)。但是為了嘗試平衡,將開始參考這個討論。
對于來自 的用戶輸入stdin,即鍵盤輸入,fgets()將是更好的選擇。它更寬容,因為它讀取的字串可以在嘗試轉換之前完全驗證
使用scanf()形式的少數幾次之一: fscanf()可以使用可能是在轉換來自非常受控制的源的輸入時,即從讀取具有重復可預測欄位的嚴格格式化的檔案。
對于更多討論,這兩者的比較突出了兩者的其他優點和缺點。
編輯:解決關于溢位的 OP 附加問題:
“我還要問的一件事是:即使我們使用fgets,如果用戶輸入的字符超過邊界(我的意思是很多字符)會發生什么,會導致緩沖區溢位嗎?那么如何處理呢?”
這是一個很好的問題,對于字串緩沖區,答案非常簡單:在格式字串中使用寬度說明符。例如,如果您想讀取輸入并將用戶的輸入大小限制為最多 100 個字符,則代碼將包括以下內容:
char buffer[101] = {0};// includes space for 100 1 for NULL termination
scanf("0s", buffer);
^^^ width specifier
但是對于數字,使用scanf(). 為了演示,使用這個簡單的代碼,每次運行輸入注釋中指示的兩個值:
int main(void)
{
int val = 0;
// test with 2147483647 & 2147483648
scanf("%d", &val);
printf("%d\n", val);
return 0;
}
對于第二個值,我的系統拋出以下內容:
NON-FATAL RUN-TIME ERROR: "test.c", line 11, col 5, thread id 22832: Function scanf: (errno == 34 [0x22]). Range error
`
在這里,您需要讀入一個字串,然后使用以下strto_()函式之一進行字串到數字的轉換:strtol()、strtod()、...)。兩者都包括在導致運行時警告或錯誤之前測驗溢位的能力。請注意,使用atoi(),atod()也不會防止溢位。
uj5u.com熱心網友回復:
例如,如果您有一個字符陣列宣告為
char s[100];
并且想要讀取包含嵌入空格的字串,那么您可以使用scanf以下任一方式
scanf( "
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/364025.html
