2015-10-21 46 views
0

我想寫一個簡單的C程序來輸出字的長度並輸出它們的頻率。例如,如果用戶輸入「hey」,我的程序將輸出字長:3出現次數1,等等,輸入一個更大的字符串。我似乎無法正確地循環它。我想在設置兩個計數器的時候,看到分隔符的時間長度和它的出現時間,但是我還沒有找到一種方法讓它工作。我如何修復我的循環?我的代碼如下。我會很感激任何幫助。我應該包括我的程序只能正確運行一個字輸入,而不是一個完整的句子或多個句子。C程序中的字長度頻率

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <ctype.h> 
const char delim[] = ", . - !*()&^%$#@<> ? []{}\\/\""; 
const int n_delim = 31; 
#define SIZE 1000 

int is_delim(int c); 
int main(){ 
    char string[SIZE]; 
    int wordlength = 0, wl[SIZE]; 
    int word = 0, i; 


    printf("Enter your input string:"); 
    fgets(string, SIZE, stdin); 
    string[strlen(string) - 1] = '\0'; 

printf("Word Length\tCount\n"); 
    int seen = 0; 
    int l; 
    for (i = 0; i < strlen(string); i++){ 
     if (is_delim(string[i])){ 
      wl[word++] = wordlength; 
      l = wordlength; 
      seen++; 
      printf("%d\t\t%d\n", l, seen); 
      wordlength = 0; 
     } 
     wordlength++; 

    } 
    return 0; 
} 

int is_delim(int c){ 
    register int i; 
    for (i = 0; i < n_delim; i++) 
     if (c == delim[i]) return 1; 
    return 0; 
} 
+0

這段代碼甚至沒有編譯,你從不在任何地方聲明'i'。 – Linus

+0

抱歉我的錯誤會立即修復它。 – Benny

+0

你也從來不會在任何地方使用'wl',如果你用'Wall'編譯,你會看到這些東西。 – Linus

回答

1

訣竅是wl [n]擁有長度爲n的單詞 的計數。此外,您不需要在每次迭代時都繼續調用strlen() ,只需在末尾檢查零字節即可。 如果啓用它,優化器將爲您執行此操作。 奇數尋找(; 1;)使得循環計數 最終字,它由零字節終止。

memset(wl,0,sizeof(wl)); 
for(wordStart=maxLength=i=0;1;i++) { 
    if(is_delim(string[i]) || string[i]==0) { 
    int wordLength= i-wordStart; 
    if(wordLength>0) 
     wl[wordLength]++; 
    if(wordLength>maxLength) 
     maxLength= wordLength; 
    wordStart= i+1; 
    } 
    if(string[i]==0) 
    break; 
} 

for(i=1;i<=maxLength;i++) { 
    if(wl[i]>0) { 
    printf("%d words of length %d.\n",wl[i],i); 
    } 
} 
+0

是我沒有包含的某個庫中的memset?因爲我通過用這段代碼替換我的循環來編譯程序,沒有任何輸出?我將wordStart和maxLength都設置爲int,因爲這裏沒有包含它。@ TeasingDart – Benny

+0

if(is_delim ...)語句中存在一個錯位的parethesis。我已糾正它。 – TeasingDart

+0

是的,它現在完美編譯@TeasingDart。感謝您的幫助! – Benny

0

你真的應該使用strtok這個。現在,你永遠不會比較最後一個字符串和當前字符串,所以你不能將它們區分開來。您可以使用strcmp。最後,不要手動測試字符串的長度,你應該使用strlen。這裏是你的循環可能會看怎麼樣

int seen = 0; 

pch = strtok(string, delim); 
last = pch; 
while(pch != NULL) { 
    if(strcmp(last, pch) != 0) { 
    printf("%s:\t%d\t\t%d\n", last, (int)strlen(last), seen); 
    seen = 1; 
    }else { 
    seen++; 
    } 
    last = pch; 
    pch = strtok(NULL, delim); 
} 
printf("%s:\t%d\t\t%d\n", last, (int)strlen(last), seen); 

注意,你應該在循環之前的變量seen設置爲0。

+0

非常感謝您的時間@Linus。我用我的編譯器中的這個循環取代了我的循環,除了輸入的第一個單詞之外,它顯示它的長度,但是計數輸出垃圾爲什麼會這樣呢? – Benny

+0

wl []在堆棧上分配,並且將包含堆棧垃圾,您需要使用memset(wl,0,sizeof(wl )) – TeasingDart

+0

我意識到什麼是輸出垃圾。第一次看到聲明沒有賦值給它。 – Benny