2014-08-28 52 views
2

我寫了一個C程序,我對程序的輸出感到困惑。 程序是這樣的:在C程序中獲取方法

int main() 
{ 
    char arr1[13] = "abcdefg"; 
    char arr2[10]; 
    gets(arr2); 
    puts(arr2); 
    strncat(arr1, arr2, 5); 
    puts(arr1); 
    puts(arr2); 

    return 0; 
} 

我輸入 「QWERTYUIOP」,其結果是:

qwertyuiop 
qwert 
qwertyuiopqwert 

誰能告訴我,爲什麼ARR1的價值變成了 「QWERT」? 非常感謝!

+0

可能重複[如何獲取()超過內存分配malloc()?](http://stackoverflow.com/questions/20094586/how-can-gets-exceed-memory-allocated-by- malloc) – anatolyg 2014-08-28 06:35:02

回答

2

請勿使用gets從用戶讀取數據,如果輸入的數據大於輸入數組大小arr2[10],則數組保存10個字節,因此\0沒有空格。這導致「未定義行爲」

由於這一點,你是getting-

qwertyuiop 
qwert 
qwertyuiopqwert // Note the extra characters with arr2, That is more then your input 

使用fgets從用戶

fgets(arr2,10,stdin); 

然後程序工作正常讀取輸入。試試這個變化 -

#include<stdio.h> 
#include<string.h> 
int main() 
{ 
    char arr1[13] = "abcdefg"; 
    char arr2[10]; 
    // gets(arr2); 
    fgets(arr2,10,stdin); // it will read only 9 characters from user, 1 byte for null 
    puts(arr2); 
    strncat(arr1, arr2, 5); 
    puts(arr1); 
    puts(arr2); 

    return 0; 
} 

輸出 -

[email protected]:~/My Docs/Programs# ./a.out 
qwertyuiopasdf <- i have entered more than 10 character. But it reads only first 9 byte 
qwertyuio 
abcdefgqwert 
qwertyuio 
+0

但是同樣的程序在我的機器上運行良好。不管得到什麼,我都會得到正確的輸出(對於這個問題)。 – 2014-08-28 06:46:00

+2

@Abhishek可能你是幸運的!未定義可以隨時發生!因爲它是未定義的! – Sathish 2014-08-28 06:47:54

+0

我的意思是說,就發佈的問題而言,使用gets應該沒有問題。 – 2014-08-28 06:50:45

0

ARR1的值不是「QWERT」
我編譯和運行程序,它提供了以下輸出

輸出控制檯:

[[email protected] replies]# ./rep2 
qwertyuiop  
qwertyuiop 
abcdefgqwert 
qwertyuiop  
[[email protected] replies]# 

程序工作正常。
這裏strncat工作得很好。

+0

該程序可能工作不正常,它有2個緩衝區溢出,導致未定義的行爲。 – nos 2014-08-28 06:47:40

+0

@nos關於發佈的問題,應該沒問題 – 2014-08-28 06:54:00

+0

qwertyuiop讀入arr2,即10個字符+一個字節,arr2溢出1個字節。 – nos 2014-08-28 06:59:09

2

功能gets從標準輸入字符串中的讀取,直到它顯示無論是換行,或文件的末尾。在這兩種情況下,它都在最後附加一個NUL字節。

您的輸入字符串qwertyuiop爲10個字符,因此總字符串長度爲11個字符。您只能在陣列中分配10個字符。所以,你的程序的行爲是不確定的。它可能會出現段錯誤,或者表現怪異。

事實上,gets功能本質上是危險的。 man page

千萬不要使用gets()。因爲事先不知道 數據,所以不可能知道有多少個字符會被()讀取,並且因爲 gets()會繼續存儲超過緩衝區末尾的字符,所以使用它是非常危險的。它已被用來破解計算機的安全性 。使用fgets()代替。