2013-12-18 46 views
3

我不明白爲什麼我的字符串比較沒有正確比較。這是C.字符串比較在C工作不正常

它從建立這樣的文件中讀取:

1 - ls    
2 - cd     
3 - history    

如果我按c它想抓住以「C」開始上次使用的串並運行!命令。但它永遠不會進入if(strcmp(())= 0)行。我的代碼

部分是在這裏:

char currLine[MAXINPUTLINE]; 

    else if (isalpha(input[1])){ 
     int count = 1; 
     fileRead = fopen(".simpleshell_history", "r"); 
     while(fscanf(fileRead, "%s\n", currLine) != EOF){ 
      printf(input+1); 
      printf(currLine); 
      if(strcmp((input+1), currLine) == 0){ 
       printf("%s\n", currLine); 
       parse(currLine); 
      } 
     } 
    } 

這是在while循環打印的printf的,我不知道如何解決這個問題,我一直在堅持了一段時間。這是當我輸入'!c'

c 
1c 
-c 
lsc 
2c 
-c 
cdc 
3c 
-c 
historyc 
4c 
-c 
!c!c 
+1

你有沒有在輸出什麼? – klm123

+0

你是什麼意思?現在假設進入if語句並輸出currLine,但它只循環while循環而不進入if語句。 – user2318083

+1

你有printf -s那裏。他們打印什麼? – klm123

回答

1

如果input是字符串!c和你正在尋找匹配的對線2 - cd,你必須要小心。 strcmp肯定不會工作,因爲只有當它比較的兩個字符串完全匹配時它纔會返回成功。

爲了測試一個字符串(cd)是否以另一個字符串(c)開頭,您希望使用strncmp(),這將限制要比較的字符數。

另外:你需要小心,開始從input第二個字符(跳過!),並從currLine第五個字符(跳過2 -字符)比較。

這應該讓你有:

while (fgets(currLine, sizeof currLine, fileRead) != NULL) { 
     printf(input+1); 
     printf(currLine); 
     if (strncmp(input + 1, currLine + 4, strlen(input)-1) == 0) { 
      printf("%s\n", currLine); 
      parse(currLine); 
     } 
    } 
+0

試過你的解決方案,但它仍然沒有進入if語句。我在下面的答案中顯示了while循環的輸出。 – user2318083

+1

'input'是否有一個尾隨的換行符,正如其他地方所建議的那樣?如果是這樣,請嘗試使用'strlen(input)-2',以防止它將'input'的換行符與'currLine'中的'd'進行比較。 –

+0

是的你是對的,現在當我printf,但它打印整個行,包括我不需要它的數字,但我認爲這是一個簡單的修復。至少我希望如此,例如它打印出「3 - 歷史」而不是「歷史」 – user2318083

1

一種可能性是輸入可能包含尾隨換行符,而curline肯定不會因爲scanf規範。

+0

你是對的輸入在字符串的末尾有尾隨'\ n',但是這不僅僅是比較第一個字母嗎?所以這不重要嗎? – user2318083

+1

不,strcmp會比較整個字符串。如果你想比較第一個字母然後做(輸入[1] == curline [1]) –

+0

嗯,似乎也不工作,「1 - 」會干擾字符串比較嗎? – user2318083

1

您的問題與您獲得input的方式有關。 (注意當你打印時,它有一個換行符)。它有一個尾隨\n和你的currLine不。因此比較失敗。

對於用戶和文件輸入,建議OP使用fgets()

喜歡的東西

char buf[MAXINPUTLINE]; 
while(fgets(buf, sizeof buf, fileRead) != NULL) { 
    int LineNo; 
    if (sscanf(buf, "%d - %s", &LineNo, currLine) != 2) Handle_UnexpectedInput(); 
    ... 
} 

注:"%s\n"不一樣"%s "不一樣"%s\t"%s跳過可選的前導空格,然後掃描非空白。 s"%s\n"之後的空格掃描可選空白。

+0

也許我應該包括這個,我也有一個「while(fgets(input,sizeof(input),stdin)){」之前的所有代碼。所以它確實fgets()「輸入」 – user2318083

+1

@ user2318083是的,它會得到「!c \ n」。 – chux

+0

所以我只需要從輸入中獲取'\ n'或將其添加到currLine中? – user2318083

2

這個循環:

while(fscanf(fileRead, "%s\n", currLine) != EOF) { 

將讀空白delimeted令牌,currLine,而不是線條。所以第一次迭代將會是1,第二次-,第三次ls等等,就像你在printf中看到的一樣。名稱currLine表示您想要讀取行而不是令牌。

然後,您將讀取的令牌與輸入行的其餘部分進行比較,該行顯然是"c\n"。既然你永遠不會得到一個換行符,它永遠不會匹配。即使你擺脫換行的,它永遠不會滿足,因爲你的文件不包含令牌c

編輯

你說你要輸入行的其餘部分比較反對的前綴命令 該行。要做到這一點,您首先要弄清楚前綴的長度,然後使用strncmp。您還需要解析文件中的行以將命令從索引中分離出來。所以,你可以這樣做:

else if (isalpha(input[1])){ 
    int count = 1; 
    int pfxlen = 1; 
    while (!isspace(input[pfxlen+1])) pfxlen++; 
    fileRead = fopen(".simpleshell_history", "r"); 
    while(fscanf(fileRead, "%d - %[^\n]", &index, currLine) == 2) { 
     if(strncmp((input+1), currLine, pfxlen) == 0) { 
      printf("%s\n", currLine); 
      parse(currLine); 
     } 
    } 
} 
+0

你是對的,它確實這樣做,試圖找出這樣做的最好方法,但我有點無知。 – user2318083

+0

你試圖弄清楚該怎麼做?你只是說「它工作不正常」,但不要說它應該做什麼。 –

+0

所以我必須從輸入中取出「\ n」,並且不知何故只比較第一個字符而不是整個標記? – user2318083