2017-03-16 89 views
0

我在CS50 IDE中遇到了printf函數的問題。當我使用printf打印出一個字符串(此代碼中的鹽)時,正在輸出的字符不在原始參數(argv)中。CS50 IDE:printf返回額外的字符

下面發佈是我的代碼。任何幫助,將不勝感激。謝謝。

#include <cs50.h> 
#include <stdio.h> 
#include <string.h> 
#include <ctype.h> 
#include <stdlib.h> 

int main(int argc, string argv[]) 
{ 
    // ensuring that only 1 command-line argument is inputted 
    if (argc != 2) 
    { 
     return 1; 
    } 
    char salt[2]; 
    for (int i = 0; i < 2; i++) 
    { 
     char c = argv[1][i]; 
     salt[i] = c; 
    } 

    printf("the first 2 characters of the argument is %s\n", salt); 

} 
+0

C字符串必須是_null-terminated_,但您的字符串不是。 – ForceBru

+0

向我們展示原始參數(argv)._ – BLUEPIXY

+0

'printf(「參數的前2個字符是%s \ n」,salt);' - >'printf(「參數的前2個字符是% .2s \ n「,salt);' – BLUEPIXY

回答

2

您在salt中缺少字符串終止符。

不知何故,計算機需要知道你的字符串在內存中的位置。它通過讀取直到它遇到一個NUL字節,這是一個零值的字節。

你的數組salt恰好有2個字節的空間,並且在它們之後,存在隨機垃圾,它恰好在你的數組後面的內存中。由於您沒有字符串終止符,計算機也會讀取此垃圾,直到遇到NUL字節。

所有你需要做的是包括你的陣列在這樣一個字節,就像這樣:

char salt[3] = {0}; 

這將使salt一個字節長,並且{0}{0, 0, 0}的簡寫,這將初始化內容與所有零的數組。 (或者,您可以使用char salt[3];,稍後使用salt[2] = 0;手動將最後一個字節設置爲零。)

+0

非常感謝您的回覆。快速的問題只是爲了清楚理解:爲什麼如果我在初始化'char salt [3] = {0}之後執行'printf(%s \ n,salt)'',編譯器就會明白, 'salt [2]中的'0'不是字符'0',而是字符串的空終止符? – laserguidedtofu

+0

因爲_character_「0」在這個上下文中被寫爲「0」,它等於_value_「48」。試試'char test [6] = {'1','0',49,48,1,0}; sprintf(「%s \ n」,測試);'看看我的意思。 (提示:笑臉具有值'1')。請參閱https://en.wikipedia.org/wiki/ASCII#Code_chart – CherryDT

+0

明白了,非常感謝。然而,在那個例子中,你的意思是'printf(「%s \ n」,test)'而不是'sprintf',對嗎?糾正我,如果我錯了:'sprintf'需要分配給它的緩衝區,在這個例子中沒有分配緩衝區。乾杯! – laserguidedtofu

0

在你的情況,salt是至少一個元素害羞的是一個,除非argv[1]只有一個元素,它不包含空終止符。

您需要分配空間來容納空終止和居然把一個人也可以使用salt作爲,如預期中的printf()情況下,參數%s轉換符。

否則,字符串相關的函數和操作,實質上依賴於將會有一個空終止符來標記數組的末尾(即標記可以訪問的有效內存的結尾)的事實,將嘗試訪問過去引起undefined behavior的有效內存。一旦你打UB,什麼都不能保證。

所以,考慮到要使用

你需要做的事實 「......在參數的第2個字符.....」

salt 3元素char數組,並確保salt[2]包含空終止符,如'\0'