2015-09-20 92 views
0

這是我第一次學習C語言。我只想問你怎麼能夠在C中返回一個字符串。這就是我正在做的事情。使用C語言從函數返回字符串

int main() 
{ 
    char input[1] = ""; 
    input = setChar(); 
    printf("%s",input); 
} 

char *setChar() 
{ 
    char *character; 
    printf("Enter a new character.\n"); 
    scanf("%s", &character); 
    return character; 
} 

編輯:所以基本上我想有將返回一個字符串或字符值,這將改變從main方法的字符串或字符值的方法。這可能嗎?

+0

? – Sim

+1

讓問題更加清楚:( – DarKnight

+0

什麼是'$ input'? – alk

回答

1

實際上不可能返回字符串,因爲字符串是適合模式的值序列。我們將這個值序列存儲到一個類型中(通常是一個字符數組),並且我們返回的是類型的(或者指向該類型的指針)。

你的功能是通常返回指向字符串,這可能是你的意思詢問...現在我可以看到你的實際目標是我可以指導你在一個指針從一開始就有更好的方向,而不是僅僅指出你發佈的程序出了什麼問題。

但是我需要使用char返回類型和參數。那可能嗎?像「char * setChar()」

我在this answer中寫了一些代碼。利用該代碼,你可以寫這樣的功能是這樣的:

cbar *setChar() { 
    return get_dynamic_word(stdin); 
} 

與該代碼,您main功能應該是這個樣子:

int main(void) { 
    char *input = setChar(); 
    if (input == NULL) { 
     exit(EXIT_FAILURE); 
    } 

    printf("%s", input); 
    free(input); 
} 

有幾件事情錯了與此計劃。讓我們一次確定一行。

int main() 

雖然這可能平時工作,它不提供獨立的環境(你的操作系統)與特定的原型。在C標準的話,

在一個函數聲明是不是該函數的定義的部分的空列表指定沒有關於參數的數目或類型的信息被提供。

這個概念最好由缺少錯誤消息證明,即使有嚴格的指示警告應該是錯誤標誌進行編譯時:

int main() { 
    return main(42, 42, 42, 42, 42); 
} 

所以這兩個原型(或equivelant)它會選擇嗎?

int main(void) { /* ... */ } 

int main(int argc, char *argv[]) { /* ... */ } 

從技術上講,該行爲是不確定的。

關於未定義行爲的快速提示:有些人會寫道,可能會發生「崩潰」,而不是。將未定義的行爲定義爲「崩潰」是錯誤的;這可能會像你期望的那樣工作,但這不是C標準的要求。所以如果你改變了編譯器,或者你的操作系統更新,或者其他一些微小的改變(比如用戶輸入),那麼你可能會開始看到你的程序出現故障。

您應該堅持前面提到的main的兩個原型之一。

順便說一下,很明顯你可能沒有從書中學習。 K & R(第二版)已經試過&已經測試了幾十年,並且已經證明可以成功教授數千名學生。 確保你做了練習。


char input[1] = ""; 

字符串是字符的序列,其終止於第一'\0'(又名0,不與'0'混淆(見引號),它通常是48)。你可能會注意到,如果你printf("%d\n", input[0]);input中的第一個(也是唯一的)字符被初始化爲0

您可以存儲多少個字符值到input?只有一個,因爲你宣稱它只是一個字符。這意味着您只能將一種字符串存儲到此數組中:一個空的之一。

當您決定使用您的存儲字符串的數組的多長時間時,您需要適應字符串的零(零)終止。如果您要聲明inputchar input[256];(如其他答案中所示),input可以存儲255個非零字符,後跟1個零字符來終止字符串。


input = setChar(input); 

這行代碼在技術上是違反約束;你的編譯器應該產生一個錯誤信息。你不能像這樣分配數組。不用擔心,這是一個簡單的解決方法,因爲返回值是多餘的;你的函數直接修改數組。利用這一點,來代替:

setChar(input); 

printf("%s",$input); 

您還沒有宣佈任何這樣的標識符$input,而事實上,因爲C標準不要求$字符存在於源字符集中,那麼這將是一個錯誤。我想你的意思是這樣寫:

printf("%s", input); 

scanf("%s", &c); 

有兩個問題:

  • 當1以外scanf回報什麼,可能發生了IO錯誤,並且c可能不包含一個字符串(這意味着你不應該騙到printf,並告訴它打印一個非字符串,就像它是一個字符串一樣......請參閱關於未定義行爲的註釋)。 不要忽略scanf的返回值。永遠。
  • 格式指令%s告訴scanf,你給它的參數是一個char *,但使用&操作上char *產生char ** ...你騙scanf,這也是不確定的行爲。

你大概意思寫的東西,如:

int x = scanf("%s", c); 
if (x == 1) { 
    return c; 
} 
else { 
    return NULL; 
} 

這將使你的返回值的目的:你能確定你的函數是否是成功的,當你把它叫做:

char *str = setChar(input); 
if (str == NULL) { 
    /* An error occured */ 
} 
else { 
    /* c -should- contain a string */ 
} 

我這樣說應該包含一個字符串,因爲有些情況下它可能不會。其他人提到了緩衝區溢出的問題。這些可以通過告訴scanf避免你的陣列有多大,在這種情況下,一個字符串可以保證:

char input[256]; 
int x = scanf("%255s", input); 

產生了一個問題,這就是如果一個特定的詞,會發生什麼(因爲%s讀取)長超過255個字符。 scanf將停止閱讀,留下下一個電話scanf(或getchar,或其他)處理的單詞的其餘部分。如果你想放棄這樣一個字的剩餘部分,上面的代碼可以通過這個隨訪:

scanf("%*[^ \n\t]"); 
puts("NOTE: Input truncated!"); 
要返回一個字符串代替焦炭的