2017-07-21 46 views
0

我想知道如何用一個已知大小的字符串填充單個字符。然後我寫了這個簡單的代碼來解決更大的問題,我有 (動態填充未知大小的字符串) 。當我試圖編譯並運行這段代碼時,我遇到了一個輸出有心臟符號的問題!我不知道它來自哪裏。puts()函數爲什麼會給我一個心臟符號?

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

int main() 
{ 
    int i; 
    char str[3]; 
    for(i=0;i<=2;i++){ 
     str[i]=getc(stdin); 
    } 
    puts(str); 
    return 0; 
} 

謝謝。

+3

在C'char'串真的叫***空終止* ** *字節字符串*。該「零終止」部分很重要。如果你沒有在一個字符串中,那麼所有的字符串函數都會在搜索它的時候超出範圍,並且你將會有*未定義的行爲,這會使你的程序不合格*並且無效。 –

+0

@某位程序員老兄_謝謝。爲什麼不跳過額外的輸入?我知道索引是0,1,2,索引2是空終止的。如果我輸入堆棧爲什麼不跳過確認? –

+2

但你*不*終止'str'中的字符串,你讀了三個字符並將它們放入數組中。如果要讀取三個字符,則數組需要爲四個*大字符,最後一個元素爲終止符(您明確需要初始化)。 –

回答

3

C strings是由null character(即代碼爲0的字符)終止的字符序列。它可以表示爲'\0','\x0'或簡單地0

您的代碼填充str三個字符但未能生成null終止符。因此,puts()會打印它在內存中找到的任何字符,直到它到達第一個字符null

您的代碼公開Undefined Behaviour。它可以做任何事情,這不是它的錯。

爲了解決它,你必須確保該字符串與null終止字符:

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

int main() 
{ 
    int i; 
    // Make room for 3 useful chars and the null terminator 
    char str[4]; 
    // Read three chars 
    for(i = 0; i < 3; i ++) { 
     str[i] = getc(stdin); 
    } 
    // Add the null terminator for strings 
    str[3] = 0; 

    puts(str); 
    return 0; 
} 

更新

由於@JeremyP注意到一個評論,如果文件閱讀從(stdin)結束之前的代碼讀取3字符,fgetc()將返回EOF(文件結束)字符,也是有趣的非打印字符,讓你想知道它們來自哪裏。

寫這段代碼的正確方法是檢查輸入文件從中讀取之前達到EOF(feof()):

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

int main() 
{ 
    int i; 
    // Make room for 3 useful chars and the null terminator 
    char str[4]; 
    // Read at most three chars 
    for(i = 0; i < 3 && !feof(stdin); i ++) { 
     str[i] = getc(stdin); 
    } 
    // Add the null terminator for strings 
    str[i] = 0; 

    puts(str); 
    return 0; 
} 
+0

而且如果我不將'str [3] = 0'帶入我的代碼? –

+0

如果你不添加'str [3] = 0;'那麼你和以前一樣。你有3個由getc()設置的字符,而第四個是執行代碼時在內存中發生的事情;來自之前執行的其他代碼的剩餘部分。 'str'是一個局部變量;它在分配時不會被初始化。 – axiac

+0

您的代碼仍然不正確。 'getc()'返回'int',以便在遇到文件結尾時可以返回'EOF'。就目前情況而言,如果文件少於三個字符,緩衝區將填充'(char)EOF'字符,可能是0xff。 – JeremyP

0

c中的字符串需要空終止,所以可能是因爲忘記在字符串末尾添加了'\0'字符。心臟符號出現的原因是當puts()試圖寫出一個字符串時,它會一直讀取內存中的下一個字符,直到它到達一個空終止符'\0'。既然它沒有遇到它,它就會繼續讀入記憶,並發現我猜測到的心臟符號。希望這可以幫助。

+1

謝謝親愛的尼古拉斯。 –

+0

_it可能是你忘了添加一個'\ 0'_,不,它不是__可以__,他__really__忘記添加'\ 0'字符。 –

+0

@MichaelWalz,我只是想表現得很有禮貌。 –

相關問題