2012-08-05 72 views
1

任何人都可以告訴我爲什麼這段代碼崩潰?很簡單,如果字符串的長度大於16,再次詢問一個字符串。如果我在if語句中寫入control = 1,它會起作用,但如果沒有它,它應該也是一樣的,因爲那時控制的值是1,對嗎? thans(我學)簡單,如果陳述在c不起作用

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int 
main(void) 
{ 
    int control = 1; 
    char word[16] ; 
    printf("Enter a word: "); 

    while(control == 1) 
    { 
     scanf("%s", word); 

     int len = strlen(word); 
     printf("Lenght is: %d\n", len); 

     if (len >= 16) 
     { 
      printf("Word lenght to long, enter a new one: "); 
     } 

     else 
     { 
      control = 0; 
     } 

    } 
    printf("This is the word: %s\n", word); 

} 

回答

8

炭字[16]的字符串分配16個字節存儲。

scanf()然後將字符串讀入該存儲。

如果您讀入的分配存儲量超過存儲量,則在存儲結束後存儲器損壞。

這就是爲什麼你會崩潰。

+3

還要記住終止NULL字符計爲已分配的16個字符之一。 – 2012-08-05 22:54:10

+0

當然,希望SO只會計算出最好的答案,如10分,而不是每個upvote 10分。如果我寫一個需要多年經驗的無鎖問題的答案,我可能會得到一兩票,因爲還有誰知道?我在一個基本的C問題上寫了一個簡單的問候,嘿,八票。這是啤酒'甜點'投票。這實際上並不僅僅是對接受者的感覺良好的因素。 – 2012-08-05 23:33:11

+0

另外考慮更深奧的問答比較少的觀衆,因此投票少。 – 2012-08-05 23:43:49

2

問題是,如果用戶鍵入的字符超過了您分配空間的15個字符,則計算機將愉快地將所有這些字符寫入內存中,超過數組的末尾。這將導致「未定義的行爲」,包括崩潰您的程序。

1

正如其他人已經注意到的,您的根本問題是您爲該字符串分配16個字符,並且scanf會愉快地允許您將這些16字符寫入不屬於您的內存中。請注意,C將允許您使用數組來完成此操作,並瞭解標準C字符串是如何工作的:您需要null-terminate它們,這意味着您將始終需要數組中的額外空間一個空終止字符\0

的方式來限制scanf相對於C字符串,用字段寬度說明符%s,就像這樣:

char input[17]; // room for 16 characters plus null-terminator 

// here scanf will stop after reading 16 characters: 
scanf("%16s", input); 

有了這個代碼,你可以放心地使用scanf填寫您的字符串不超過16個字符,而scanf將爲您終止字符串。

但正如其他人也指出的,scanf在處理用戶輸入方面很差。通常使用fgets會更好,並且可以逐個管理輸入字符串。