字数统计程序 - stdin

时间:2016-10-13 08:27:21

标签: c eof getchar

低于question

  

编写一个程序,将英文文本读入数据结尾(类型control-D表示终端数据结束,见下文检测),并打印字长计数,即总数发生长度为1的单词,长度为2的单词,依此类推。

     

将单词定义为字母字符序列。您应该允许最多25个字母的单词长度。

     

典型输出应该是这样的:

        length 1 : 10 occurrences
        length 2 : 19 occurrences
  length 3 : 127 occurrences
     length 4 : 0 occurrences
        length 5 : 18 occurrences
        ....
     

要读取数据末尾的字符,请参阅上述问题。

这是我的工作解决方案,

#include<stdio.h>
int main(void){
  char ch;
  short wordCount[20] = {0};
  int count = 0;
  while(ch = getchar(), ch >= 0){
    if(ch == ' ' || ch == ',' || ch == ';'|| ch == ':'|| ch == '.'|| ch == '/'){
      wordCount[count]++;
      count=0;
    }else{
      count++;
    }
  }
  wordCount[count]++; // Incrementing here looks weird to me

  for(short i=1; i< sizeof(wordCount)/sizeof(short); i++){
    printf("\nlength %d : %d occurences",i, wordCount[i]);
  }
}

问题:

1)

从代码优雅方面来看,我可以避免在wordCount循环之外递增(++)while吗?

2)

我可以根据字大小使wordCount数组大小更具动态性,而不是常量20吗?

注意:了解struct但尚未学习Linkedlist等动态结构

2 个答案:

答案 0 :(得分:2)

至1):  也许从一个分隔字符扫描到下一个分隔字符,直到你增加wordCount。也可以使EOF成为分隔字符。

到2)  你可以扫描文件两次,然后决定你需要多少内存。或者,只要需要更多内存,就动态realloc。这是std::array类在内部执行的操作。

此外,您应该考虑如果彼此之后有两个个字符会发生什么。现在你可以把它算作一个单词。

答案 1 :(得分:2)

对于动态分配,您可以从20 shorts的空格开始(尽管问题陈述似乎要求您允许最多25个字符的单词):

short maxWord = 20;
short *wordCount = malloc(sizeof(*wordCount) * maxWord);

然后,当你增加count时,如果当前单词比动态数组中的计数长,你可以分配更多的空间:

} else {
    count++;
    if (count >= maxWord) {
        maxWord++;
        wordCount = realloc(sizeof(*wordCount) * maxWord);
    }
}

完成后不要忘记free(wordCount)

由于您不需要计算零长度字词,因此您可以考虑修改代码,以便wordCount[0]存储长度为1的字数,依此类推。