2015-08-26 67 views
1

下面是要求用戶 輸入一個一個程序,然後在同一時間打印出名字一個字母 ,最終產生全名。 我有兩個版本的程序。在 下面會出現一個奇怪的現象:如果我輸入的內容類似 jkljljkliunionnklsaa,它只會產生jkljljkl字符數組與scanf函數:不受限制的字符數組沒有給出正確的結果

但是,如果我限制char name[40],然後鍵入相同的名稱,程序會顯示整個名稱。 我在程序中做了什麼錯誤,不允許它產生全名?

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

    int main (void) 
    { 
     int i, s; 
     char name[s]; 

     printf ("Type a name: "); 
     scanf ("%s", name); 

     for (i = 0; i < strlen(name); i++) 
     { 
      printf ("%c", name[i]); // print the i-th character of name 
     } 
     printf("\n"); 
    } 
+0

首先,**從不寫** scanf(「%s」,...)「。當用戶輸入到數組中時,它會讀取儘可能多的非空白字符,而且這個字符不是無限大。如果您的名稱數組長度爲10個字符,並且用戶輸入了20個字符的單詞,那麼您的程序將崩潰或更糟。更糟的是,我的意思是惡意用戶可以控制你的程序並運行他們自己的代碼,在這種情況下,這是一種基於棧的緩衝區溢出。以字符串形式讀取用戶輸入的正確方法是使用'fgets()'。用'fgets(name,sizeof(name),stdin)替換你的代碼;'。這將讀取一行。 – C0deH4cker

+0

謝謝。我正處於學習編程的第一步。我仍然需要學習你建議的功能。很高興做到這一點。我是否正確理解,如果我使用scanf,我應該總是限制可能條目的數量,就像我對名稱[40]所做的那樣? – Ducol

回答

2
int i, s; 
char name[s]; 

這是未定義行爲(在ISO C行話; 任何可能發生,甚至一些你所期望的),因爲s沒有被初始化。不像你的問題的措辭建議,一個未初始化的變量作爲數組大小確實不是意思是非限制大小。這意味着程序錯誤。 :-)

s可能碰巧是0或10或-136186732,所以你可能有或沒有足夠大的字符數組來存儲一些字符。

它將開始與

int i, s = 40; 

再次努力澄清,C確實有自動增長或自適應陣列。如果您需要在運行時分配或調整陣列大小,則需要使用malloc()realloc()

+0

謝謝。我想最初使用未定義的數組,因爲沒有人知道名稱可以有多長:)但像-xxxx這樣的負值似乎是不相關的 - 我使用的是char變量,而不是數字;程序是否有可能獲得消極字符? – Ducol

+0

@Ducol's'不是字符,它是一個'int',所以它可以是負數。 ISO C標準認爲'char'類型的簽名是實現定義的,所以是的,如果該實現具有帶符號的'char'類型,則可以有'char'值小於零。 – Jens

0

在您的第一個版本中,您沒有指定字符數組的大小,而是將其保留爲name[s],其中s是一個用垃圾值初始化的整數。

然而,在第二種情況下,你做它作爲name[40]從技術上來講最多可以容納到39個字符長字符串。 (39. Think Why ???

+0

我很高興我知道爲什麼:)因爲它全部從0開始,因此0 - 39將是40個字符。至於[s]的名字,那是我的目標。鑑於這是一種不正確的做法,我試圖找到一種方法(如果存在)不限制用戶輸入的字母數量。 – Ducol

+0

是的,有一種方法,但有點複雜。檢查了這一點http://stackoverflow.com/questions/16870485/how-can-i-read-an-input-string-of-unknown-length。這裏,文件名是'stdin',意味着它從控制檯輸入而不是任何文件。 – surajsn

+0

感謝您的鏈接! – Ducol

相關問題