2014-10-08 60 views
0

如果問題實際上是愚蠢的,我很抱歉,但我剛開始學習C,並且沒有人知道我能夠提供幫助。 我應該統計stdin中的字母數,並說明每個字母被使用了多少次。 我們也期望使用計數器和fread方法。C程序返回意外的數字

編輯:伊戈爾幫助我與他的答案和程序現在幾乎一切正確。小錯誤仍然存​​在:只有前10個字符被識別並計數,其他字符被忽略。輸入必須大於10,否則不起作用。

我評論了我在代碼中所做的更改,以便其他人可以跟蹤我的錯誤。

我的代碼是:

#include <stdio.h> 
#include <ctype.h> 

int main(){ 
    char text[10]; 
    int timesUsed[26]; // I initialized the array but didn't set the values to 0. 
    int timesUsed[26] = {0}; //this line corrected the issue with getting random numbers 
    int textLength = 0; 
    char *ptr; 
    while(fread(&text,sizeof(char),10,stdin)){ 
    ptr = &text[0];  
    while(1){ 
     if(isalpha(*ptr)){ 
    textLength++; 
    *ptr = tolower(*ptr); //the original was only tolower(*ptr); which is useless 
    timesUsed[((char) *ptr) - 'a']++; 
     } 
     if(*ptr == '\n') goto end; //the original had here only one '=' 
     /**ptr = '\0';*/ 
     if(ptr == &text[10]) goto end; // on both 
     ptr ++; 
    } 
    } 
end: 
    printf("Number of letters:%20d\n",textLength); 
    int i; 
    for(i=0;i<26;i++){ 
    if(timesUsed[i]>0){ 
     char thechar = (char) 'a' + i; 
     printf("The letter %c was used %5d time(s).\n",thechar,timesUsed[i]); 
    } 
    } 
    return 0; 
} 

哪個不打印預期的結果,它究竟是打印:

Testing testing testing testing testing testing M 
Number of letters:     9 
The letter e was used  2 time(s). 
The letter g was used  1 time(s). 
The letter i was used  1 time(s). 
The letter n was used  1 time(s). 
The letter s was used  1 time(s). 
The letter t was used  3 time(s). 

的變化進行的輸出顯得更有意義。儘管如此,還是有些失誤

+1

從未使用goto語句,除非直到您希望C社區中的每個人都可以降低您的... – Haris 2014-10-08 17:48:34

+0

正確地格式化您的代碼將有助於獲得答案。我會幫忙,但我不想清理你的帖子。 – 2014-10-08 17:49:49

+0

你也期望'if(ptr =&text [10])''? – P0W 2014-10-08 17:49:56

回答

3

下次用-Wall-Wextra編譯您的代碼時,您會發現一些錯誤。

你必須初始化數組:

int timesUsed[26] = {0}; 

當你不這樣做,它包含隨機值和計數是不正確的。

這種說法沒有任何影響:

tolower(*ptr); 

而是執行此操作:

*ptr = tolower(*ptr); 

而用C =是不一樣的==它檢查是否相等,所以你應該在if語句改變到:

if(*ptr == '\n') goto end; 
     /**ptr = '\0';*/ 
if(ptr == &text[10]) goto end; 
+0

非常感謝你,我會做出改變並說出它是如何發生的。 – Raeglan 2014-10-08 18:06:36

+0

我做了更改並且已經對代碼進行了評論!非常感謝,只要我有15的聲望,我會upvote你的答案! :) – Raeglan 2014-10-08 18:25:40

+0

沒問題... :) – Igor 2014-10-08 18:28:41

0

試試這個:

#include <stdio.h> 
int main(){ 
    const char *str = "this is string to count"; 
    int counts[256] = { 0 }; 
    int i,letters=0; 
    size_t len = strlen(str); 
    for (i = 0; i < len; i++) { 
    counts[(int)(str[i])]++; 
    } 

    for (i = 0; i < 256; i++) { 
    if(counts[i]>0){ 
     printf("%c occurs %d times.\n", i , counts[i]); 
     if((char)i!=' '){ 
     letters+=counts[i]; 
     } 
    } 

    } 
printf("Number of letters : %d", letters); 
getchar(); 
    return 0; 

} 

輸出:

occurs 4 times. 
c occurs 1 times. 
g occurs 1 times. 
h occurs 1 times. 
i occurs 3 times. 
n occurs 2 times. 
o occurs 2 times. 
r occurs 1 times. 
s occurs 3 times. 
t occurs 4 times. 
u occurs 1 times. 
Number of letters : 19 
0

該代碼看起來太過複雜,我。這是一個全指針算術版本。沒有數組符號責任:

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

#define A ((unsigned char)'a') 
#define Z ((unsigned char)'z') 

#define BUFFER_SIZE ((size_t)8192) 

int main(int argc, char *argv[]) 
{ 
    int   counter_max = 1 + UCHAR_MAX ; 
    int   *counter  = calloc((size_t) counter_max , sizeof(int) ) ; 
    unsigned char *buffer  = calloc(BUFFER_SIZE   , sizeof(*buffer)) ; 
    int   bufl  ; 

    while ((bufl=fread(buffer,sizeof(*buffer),BUFFER_SIZE,stdin)) > 0) 
    { 
    for (unsigned char *p = buffer ; p < buffer+bufl ; ++p) 
    { 
     unsigned char c = tolower(*p) ; 
     ++ *(counter+c) ; 
    } 
    } 

    for (int *p = counter+A ; p <= counter+Z ; ++p) 
    { 
    int n = *p ; 
    if (n > 0) 
    { 
     char c = p-counter ; 
     printf("The letter '%c' was found %d times.\n" , c , n ) ; 
    } 
    } 

    return 0; 
} 
+0

它非常複雜,但我們需要使用指針,fread並從stdin獲取輸入。 我們還需要有一個緩衝區,並能夠從標準輸入變爲任何大小的文本。 – Raeglan 2014-10-08 19:05:44

+0

@Raeglan,似乎是我修正的答案。 – 2014-10-08 20:28:50

1

好吧,讓我們嘗試改進一些東西:

#include <stdio.h> 
#include <ctype.h> 

int main(){ 
    char text[10] = ""; // This is allocating space for exactly 10 chars. 
    int timesUsed[26] = {0}; // Always initialize your variables. Particularly arrays. 
    int textLength = 0; 
    int inputLength = 0; 
    inputLength = fread(&text,sizeof(char),10,stdin); // fread returns the number of chars actually read, and since you're telling it to read 10 chars, that's the MAXIMUM amount of chars it'll read. It may read less, that's why it returns to you how much it read; 
    for(int i=0;i<inputLength;i++){ // since you know the length, iterate over it! 
     if(isalpha(text[i])){ 
     textLength++; 
     char c = tolower(text[i]); // No need to mess with pointers! 
     timesUsed[text[i] - 'a']++; 
     } 
     if(text[i] == '\n') break; //Exit the for loop. NEVER EVER EVER USE GOTO!!! Actually I don't think this will ever happen because I think fread returns when the user hits ENTER 
    } 
    printf("Number of letters:%20d\n",textLength); 
    int i; 
    for(i=0;i<26;i++){ 
    if(timesUsed[i]>0){ 
     char thechar = (char) 'a' + i; 
     printf("The letter %c was used %5d time(s).\n",thechar,timesUsed[i]); 
    } 
    } 
    return 0; 

它將可能編譯罰款,但我沒有檢查。如果不是,可能是一些錯字。 希望它有幫助。