2017-08-25 1012 views
-2

scanf("%s"),scanf(」%[^\n]s")gets(a) C編程?scanf(「%s」,a)scanf(「%[^ n] s」,a)與C編程中的字符串得到(a)有什麼區別?

scanf("%[^\n]s", a) 

scanf("%s", a) 

gets(a) 

採取字符數組輸入三種方式之間的主要區別是什麼?

+1

'puts()'用於輸出,至少。什麼是'a'?如果它是一個char數組或指向此類第一個元素的指針,那麼'&a是錯誤的,因爲它是指向char數組的指針或指向char的指針。 –

+2

您確定您的意思是''%s [^ \ n]「',而不是'」%[^ \ n]「'?也許你需要一個[很好的'scanf'(和家庭)參考](http://en.cppreference.com/w/c/io/fscanf)? –

+4

'scanf(「%s [^ \ n]」,a)'只是**錯**。有一個轉換說明符''和一個**不同的**轉換說明符'[]'。他們不是要結合。 –

回答

2

首先,他們都已經不確定出於同樣的原因行爲:他們會讀一些你無法預先知道字符,而是通過你的指針,你提供存儲在哪裏存儲該數據,而這個存儲有一些固定的大小。因此,總有輸入可能會溢出您的緩衝區。你不應該在你的代碼中使用這些行的任何

這就是說:

  • gets()讀取輸入並存儲的到您的緩衝區。它也讀取換行符,但不存儲。 此功能被設計破壞,因爲有沒有辦法安全地使用它。永遠不要使用它。已經從C11的C標準中刪除了,所以你只能使用它與舊標準無論如何。正確的替代品是char a[100]; fgets(a, sizeof a, stdin);。但是,將換行符存儲在緩衝區中。

  • scanf("%[^\n]s", ...)還將讀取的輸入。 []轉換說明符采用被接受的列表或前面的^拒絕的字符。因此,使用此語法,它將接受任何字符,但換行符除外。因此,換行符將不會被這樣讀取s將在輸入中進行搜索,字面意思是,這不是你的意思。 s[]不同轉換說明符。要正確使用這個字段,您必須像這樣使用字段:char a[100]; scanf("%99[^\n]", a);。請注意,您必須指定比緩衝區大小小,因爲scanf()不包括附加爲字符串結束標記的'\0'字符。

  • scanf("%s", ...)讀取「」,這是它停靠在第一空白字符。正確使用這個,如上所述,使用類似char a[100]; scanf("%99s", a);的東西。

+0

愛詞組」設計「....我知道你的意思,但它幾乎聽起來像設計師_meant_爲'gets()'被打破;) –

+0

哈哈,從來沒有想過這個*這樣的短語。當然,我的意思是設計在一定程度上是錯誤的,這使得在實現中無法「修復」。 –

+0

「scanf(」%s「,...)讀取一個」單詞「,即它停在第一個空格字符處。」省略了前導空格被讀取和丟棄的部分,然後開始讀取「單詞」。 – chux

4

scanf("%s",a);將跳過輸入前導空格字符,將匹配字符,直到一個空白遇到字符(或者直到達到文件結束),將它們存儲在由論證者指示的數組中噸。請注意,這容易受到緩衝區溢出的影響,所以最好包含一個寬度指定符,以提供從輸入中讀取的最大字符數。例如,如果a是100 char的數組,則應使用%99s;這爲\0終止符留下了空間,該終止符自動由scanf()添加。

scanf("%s[^\n]",a);scanf("%[^\n]s", a);也可能是什麼意思,而應該是:scanf("%[^\n]",a);%[]掃描集指令。沒有必要遵循%[]指示與s,它只會告知scanf()%[]完成後在輸入中匹配字面s。 scanset指令匹配方括號內描述的字符並將它們分配給相應的參數。當匹配失敗時,該字符被放回到輸入流中。在這裏,^\n表示除了之外的所有字符應該匹配換行符,所以該指令將匹配字符,直到遇到換行符,並且換行符將保留在輸入流中。關於指定最大寬度的相同建議也適用於此處:%99[^\n]以避免緩衝區溢出,如果a是100 char s的數組。請注意,%[^\n]指令將匹配任何不是\n的字符,包括其他空格字符。這意味着它將跳過前導空白字符(但是在輸入的領先\n將導致指令立即失敗,未做分配),而相比之下,%s,並將讀取包含輸入空間。

puts(a);不讀取輸入,而是輸出功能。請注意,該函數在打印參數後打印換行符。也許你打算在這個方法列表中包含gets()來收集輸入。

gets(a); is an unsafe function在C99中已棄用,並且已從C11中的語言中完全刪除。出於任何原因,您絕不應該使用此功能。該函數獲取一行輸入,讀取字符,直到遇到換行符,或者直到達到文件結尾。換行符被丟棄;它不存儲在a指示的數組中,並且不會返回到輸入流。因此,當過去使用gets()時,它與puts()一起工作良好,它在打印參數後自動打印換行符。

最後,多一點信息,有fgets()。該函數獲取一行輸入,但需要一個大小參數,以避免緩衝區溢出。由於我前面的char a[100];例如,fgets()會被稱爲是這樣的:

fgets(a, 100, stdin); 

或有時:

fgets(a, sizeof a, stdin); 

這裏,fgets()讀取最多一個字符少比大小參數指定的數,允許總是添加\0的空間。如果讀取了\n,則它存儲在a中。由於換行符不被丟棄,因此puts()在這裏不起作用;經常在輸入fgets()後需要刪除換行符。

+0

對不起,我的最後一次編輯是在你精心設計的答案中發生的,OP顯然在發佈之前沒有想過,請隨時編輯它,我現在就放棄... –

+0

你是說'gets()'現在在答案中嗎?我剛剛看到並正在更新.... –

+1

好吧...至少現在問題中的代碼是OP的意思。我希望人們會花一秒鐘的時間來證明他們在點擊發布按鈕之前所要求的內容:o –

相關問題