2016-04-07 82 views
1

我開始學習中C.輸入字符串在下面的源代碼我得到長度5.使用scanf的輸入字符串()

#include<stdio.h> 
int main(void) 
{ 
    char s1[5]; 
    printf("enter text:\n"); 
    scanf("%s",s1); 
    printf("\n%s\n",s1); 
    return 0; 

} 

的字符數組當輸入爲:

  1. 1234567891234567,我檢查了它的工作正常多達16個元素(我不明白,因爲它超過5個元素)。
  2. 12345678912345678,它給我一個錯誤segmentation fault: 11(我給在這種情況下,17種元素)
  3. 123456789123456789,錯誤被Illegal instruction: 4(我給在這種情況下,18種元素)

我不明白爲什麼有不同的錯誤。這是C中的scanf()或字符數組的行爲。我正在閱讀的這本書對這些事情沒有一個明確的解釋。僅供參考我不瞭解指針。任何進一步的解釋都會很有幫助。

+1

的行爲*不確定*當輸入的長度超過4個字符。 *未定義的行爲*並不意味着「必須立即崩潰」,這意味着語言沒有義務做任何特別的事情。 – EOF

+0

但是當輸入超過5個字符時它不應該給我一個錯誤? – yash

+0

@buggenerator:這不是違反約束條件,編譯器沒有義務發出診斷消息,也沒有要求在運行時引發錯誤。 – EOF

回答

5

這是scanf()或C中的字符數組的行爲嗎?

TL; DR - 不,您正面臨undefined behavior的副作用。

爲了闡述,在你的情況,針對類似的代碼

scanf("%s",s1); 

,你必須定義

char s1[5]; 

輸入任何超過4 char會導致你的計劃進軍無效的內存區(通過分配的內存),然後調用undefined behavior

一旦你擊中UB,程序的行爲無法以任何方式預測或證明。它可以做任何事情(甚至不可能)。

沒有什麼其中阻止你讀取過長輸入和溢出緩衝器中的scanf()固有的,則應通過使用場寬度保持在輸入字符串掃描控制,如

scanf("%4s",s1); //1 saved for terminating null 
+0

但是它怎麼樣可以達到16個字符,而且比給我錯誤還有'不同的錯誤'更好? – yash

+0

閱讀[未定義行爲](https://en.wikipedia.org/wiki/Undefined_behavior)。也請查看最新的答案以進行澄清。 –

+2

下一次你編譯和運行,它可能會接受高達128或可能在第6次崩潰,你永遠不會知道... –

2

scanf功能當讀取字符串時讀入下一個空格(例如換行符,空格,製表符等)或「文件結尾」。它有沒有有關您提供的緩衝區大小的想法。

如果您讀取的字符串比提供的緩衝區長,那麼它會寫出界限,並且您將有未定義的行爲

停止這種最簡單的方法是提供一個字段長度爲scanf格式,如

char s1[5]; 
scanf("%4s",s1); 

請注意,我用4作爲字段長度,因爲需要爲一個字符串結束的空間好。

您還可以使用「安全」 scanf_s在您需要提供的緩衝區大小作爲參數:

char s1[5]; 
scanf_s("%s", s1, sizeof(s1)); 
+0

我不是故意在這裏天真。這是否意味着在這種情況下緩衝區是16個字符? – yash

+1

@buggenerator否緩衝區的長度是您聲明變量時提供的長度_you_。所以這裏的長度是5.(char s1 [** 5 **]) –

+0

@buggenerator「緩衝區大小」是您聲明的數組的大小(可能會減去終止符的大小)。 –

相關問題