2017-07-26 32 views
-1

我使用Ubuntu 14.04和gcc 4.8.4C:在scanf這份聲明中人物返回垃圾價值

#include<stdio.h> 
void main() 
{ 
    char c[15]; 
    printf("enter a character\n"); 
    scanf("%15c",c); 
    printf("%s\n",c); 
} 

輸出:

enter a character 
qwertyuiopasdfghjkl 
qwertyuiopasdfg 

當我執行以上超過15個字符的程序作爲輸入,輸出不返回垃圾值。但是,當我執行下面的程序:

#include<stdio.h> 
void main() 
{ 
    char c[5]; 
    printf("enter a character\n"); 
    scanf("%5c",c); 
    printf("%s\n",c); 
} 

我給輸入,超過5個字符。它用垃圾值返回輸出。

+1

問題是由'%15c'和'%5c'讀取的值不是空終止的,所以你的兩個代碼都有未定義的行爲。 –

+0

'main()'的返回類型總是'int',而不是'void'。這並不是說這是中心問題。 –

+0

@JohnBollinger雖然不是中心問題,C允許'無效的主要()'每「或在某些其他實現定義的方式」。 C11§5.1.2.2.11 – chux

回答

3

%c指令是用於讀取單個字符和字符數組,但不是用於特異性用作C字符串這些陣列。特別是,它不會在從輸入傳輸的最後一個字符之後存儲空字符。

因此,您的兩個scanf()通話都非常好,但後續printf()通話不是。在每種情況下,該陣列由c指定的內容是不是空終止,因此,試圖通過%s指令打印的陣列將導致scanf()讀取超出數組的末尾,從而產生不確定的行爲。在一個案例中未定義的行爲對您而言似乎合理,而在另一案件中的未定義行爲並不無關緊要。

我建議不要與未結束的字符串數組類似工作作爲你在做什麼。最好讓陣列足夠大以便終止,並確保它們實際上已被終止。但是,如果你必須通過printf()打印匹配或可能未結束的字符數組,那麼一定要使用該指令的精度域限制可以打印的字符數:

#include<stdio.h> 

int main(void) { 
    char c[5]; 
    printf("enter a character\n"); 
    scanf("%5c", c); 
    printf("%.5s\n", c); 
} 
+0

不,@chux。不管場的寬度,一個'%C'指令告訴'printf()的'期望一個對應的'int'參數,並將它轉換成無符號的'對char'印刷。作爲相應的參數,'char *'是不可接受的,並且如果傳遞了一個''char *',那麼最終的未定義行爲更可能沿着解釋指針值的一部分作爲'unsigned char'的行而不是輸出任何指向字符。 –

+0

是的,當然,你是對的。 A「如果你還記得60年代 - 你不在那裏。」時刻。 – chux

0

如果輸入超過5字符,那麼你的程序將完美地顯示5個字符,然後開始顯示垃圾值,因爲在打印字符串時它將打印到'\ 0'字符。如果'\ 0'最後不存在,它會打印垃圾。

1

您使用了錯誤的格式說明在scanf一個字符串。

#include <stdio.h> 

int main(void) { 
    char c[15]; 
    printf("enter a string\n"); 
    scanf("%14s", c);    // change %c to %s 
    printf("%s\n", c); 
    return 0; 
} 

注意,長度限制比數組大小少一個,以允許餘地nul終止子。