2016-12-28 114 views
-4

實際上最近我發現了一個問題,我需要計算一個給定字符串(由測試用例)給定的(由oj)char。所以我寫這個代碼,但輸出是不是我想要的。我是初學者,所以我會非常感謝任何種類的指導性建議或幫助。謝謝。在一個循環中輸入字符串和字符c

#include<stdio.h> 
#include<string.h> 

int main() 
{ 
    int ara [123]; 
    char s[1000]; 
    int l, j, i, len; 
    char c; 

    scanf ("%d\n", &l); 

    while (l >= 0){ 

     for (i = 65; i <= 122; i++) 
     { 
      ara[i] = 0; 
     } 

     fgets(s, 1000, stdin); 
     len = strlen(s); 

     for (i = 0;i <= len; i++) 
     { 
      ara[s[i]]++; 
     } 

     scanf(" %c\n", &c); 
     j = c; 
     printf("count : %d\n", ara[j]); 

     l--; 
    } 

    return 0; 
} 
+0

歡迎堆棧溢出。請花些時間閱讀[The Tour](http://stackoverflow.com/tour),並參閱[幫助中心](http://stackoverflow.com/help/asking)中的資料,瞭解您可以在這裏問。 –

+0

解決這些問題的正確工具是您的調試器。在*堆棧溢出問題之前,您應該逐行執行您的代碼。如需更多幫助,請閱讀[如何調試小程序(由Eric Lippert撰寫)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)。至少,您應該\編輯您的問題,以包含一個[最小,完整和可驗證](http://stackoverflow.com/help/mcve)示例,該示例再現了您的問題,以及您在調試器。 –

+0

如果任何發佈的答案解決了您的問題,請記住接受它。這有助於我們所有人知道,不需要採取進一步的行動 – 4386427

回答

1

的問題是,scanf被留在輸入newline被解讀爲目標的句子。

您可以使用fgetssscanf來解決此問題。我還添加了一些提示,以便更容易地知道預期結果。

#include <stdio.h> 
#include <string.h> 

int main (void) 
{ 
    int ara [128];       // increased array size 
    char s[1000]; 
    char t[10]; 
    int l, j, i, len; 
    char c; 

    printf("Enter how many loops:\n"); 
    fgets(t, sizeof t, stdin);    // replace scanf 
    sscanf (t, "%d\n", &l);     // with sscanf 

    while (l > 0){       // changed end test 

     for (i = 'A'; i <= 'z'; i++)  // replaced magic numbers 
     { 
      ara[i] = 0; 
     } 

     printf("Enter the string:\n"); 
     fgets(s, sizeof s, stdin); 
     len = strlen(s); 

     for (i = 0;i <= len; i++) 
     { 
      ara[s[i]]++; 
     } 

     printf("Enter the letter:\n"); 
     fgets(t, sizeof t, stdin);   // replace scanf 
     sscanf (t, "%c\n", &c);    // with sscanf 
     j = c; 
     printf("count : %d\n", ara[j]); 

     l--; 
    } 

    return 0; 
} 

程序會話

 
Enter how many loops: 
2 
Enter the string: 
one two three four 
Enter the letter: 
o 
count : 3 
Enter the string: 
three seven 
Enter the letter: 
e 
count : 4 

注意,理想情況下,你也應該從fgetssscanf檢查函數的返回值。

+1

當這個答案發布時,我正在寫我自己的答案。所以現在我看不出有什麼理由發佈我的原則是相同的。但是我認爲應該添加一些東西:1)初始化整個'ara'數組。目前這個代碼有UB。從標準輸入讀取程序時,初始化所有內容所需的額外時間並不重要。 2)檢查'j'的值是否在範圍之內,然後用它來索引到'ara' – 4386427

+1

和3)檢查's [i]'的值,然後索引到'ara'中 – 4386427

+1

@ 4386427謝謝,我只是最後提到的錯誤檢查。該數組可能有256個元素,並帶有'unsigned char'輸入。還有一些我可以提到的其他事情,但想要保持答案接近問題,而不是徹底改寫。 –

0

在您的程序中,當您讀取charcter值時使用此代碼,那麼您的代碼將正常工作。

scanf(" %c", &c); 
//flushes the standard input (clears the input buffer) or discard extra characters 
int etc_ch; 
while ((etc_ch=getchar()) != '\n' && etc_ch != EOF); 

注意

你也可以使用fseek(stdin,0,SEEK_END);清除輸入緩衝區 insted的while循環

使用該程序將在任何情況下適用於任何類型的字符串。通常c中有256個ascii字符。

#include<stdio.h> 
#include<string.h> 

int main() 
{ 
    int ch_arr[256]; //255 charcters in c 
    char string[1000]; 
    int test, j, i, len; 
    char ch='a'; 

    //printf("\nEnter the no of test cases :"); 
    scanf("%d\n",&test); //store test cases values 

    while(test>0) 
    {  
     for(i=0;i<256;i++) 
     ch_arr[i]=0; 
     //printf("\nEnter string input :"); 

     fgets(string, 1000, stdin); 

     len = strlen(string); 

     for (i = 0;i<len; i++) 
     { 
      ch_arr[string[i]]++; 
     } 

     scanf(" %c",&ch); 

     // flushes the standard input (clears the input buffer) 
     int etc_ch; 
     while ((etc_ch=getchar()) != '\n' && etc_ch != EOF); 

     j = ch; 
     printf("count : %d\n", ch_arr[j]); 

     test--; 
    } 
    return 0; 
} 

上述程序的輸出:

2 
abcde 
a 
count : 1 
@#$% 
@ 
count : 1 
+0

當您丟棄輸入流中的剩餘字符時,您還需要檢查'EOF'以避免無限循環。請注意,如果發生錯誤,'getchar()'返回'EOF',用戶也可以輸入'EOF'字符。 –

+0

感謝您的建議.....'while((getchar())!='\ n'&&(getchar())!= EOF);'代碼將正常工作。你也可以在getchar()的地方使用** fseek(stdin,0,SEEK_END); **來清除輸入緩衝區 –

+0

你不需要像這樣連續調用2個'getchar()': 'int ch; while((ch = getchar())!='\ n'&& ch!= EOF)continue;'這是實現這個常用習慣用法的正確方法。我的回憶是,不能保證'stdin'的鍵盤輸入是隨機訪問(因此可以搜索)。我很樂意被證明是錯誤的:) –