【问题标题】:C program to count total words in an input fileC程序计算输入文件中的总字数
【发布时间】:2015-04-08 05:22:29
【问题描述】:

输入文件在第 2 行包含一个完全空的行,并且在文本的最后一个句号之后有一个不必要的空格。有了这个输入文件,我得到了 48 个单词,而我本来应该得到 46 个单词。

我的输入文件包含:
“查尔斯·达尔文的《两个城市的故事》开场

这是最好的时代,也是最坏的时代。那是时代 智慧的时代,是愚蠢的时代。那是一个时代 相信,那是怀疑的时代。 "

这是我的尝试:

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

#define max_story_words 1000
#define max_word_length 80

int main (int argc, char **argv)
{


    char story[max_story_words][max_word_length] = {{0}};
    char line[max_story_words] = {0};
    char *p;
    char ch = 0;
    char *punct="\n ,!.:;?-";
    int num_words = 1;
    int i = 0;

    FILE *file_story = fopen ("TwoCitiesStory.txt", "r");
    if (file_story==NULL) {
        printf("Unable to open story file '%s'\n","TwoCitiesStory.txt");
        return (EXIT_FAILURE);
    }

    /* count words */
    while ((ch = fgetc (file_story)) != EOF) {
        if (ch == ' ' || ch == '\n')
            num_words++;
    }

    rewind (file_story);

    i = 0;
    /* read each line in file */
    while (fgets (line, max_word_length, file_story) != NULL)
    {
        /* tokenize line into words removing punctuation chars in punct */
        for (p = strtok (line, punct); p != NULL; p = strtok (NULL, punct))
        {
            /* convert each char in p to lower-case with tolower */
            char *c = p;
            for (; *c; c++)
                *c = tolower (*c);

            /* copy token (word) to story[i] */
            strncpy ((char *)story[i], p, strlen (p));
            i++;
        }
    }

    /* output array */
    for(i = 0; i < num_words; i++)
        printf ("story[%d]: %s\n", i, story[i]);

    printf("\ntotal words: %d\n\n",num_words);

    return (EXIT_SUCCESS);
}

【问题讨论】:

  • 使用isalpha - example 可能更容易。
  • 我不想更改我的整个代码,有一个很小的错误我想不通。
  • @SadmanAhmed 如果你不想让别人告诉你如何让你的代码更好,那你就错了网站
  • 要计算你不应该找到字母的单词,最好计算空格(空格、制表符、换行符)。

标签: c string counter readfile


【解决方案1】:

您的 num_words 考虑了两个额外的空格,这就是您得到 48 的原因。

如果我没记错的话,您应该在 fgets-strtok 循环之后立即打印 i

【讨论】:

    【解决方案2】:

    类似的东西:

    while ((ch = fgetc (file_story)) != EOF) {
        if (ch == ' ') {
             num_words++;
             while( (ch = fgetc (file_story)) == ' ' && (ch != EOF) )
        }
        if (ch == '\n') {
             num_words++;
             while( (ch = fgetc (file_story)) == '\n' && (ch != EOF) )
        }
    

    虽然我想知道为什么您只使用空格和换行符来计算新单词。由其他标点符号分隔的两个单词绝对不会在您的代码中计入

    【讨论】:

      【解决方案3】:

      我的建议是改变单词计数循环如下:

      /* count words */
      num_words = 0;
      int flag = 0; // set 1 when word starts and 0 when word ends
      while ((ch = fgetc (file_story)) != EOF) {
          if ( isalpha(ch) )
          {
              if( 0 == flag )   // if it is a first letter of word ...
              {
                  num_words++;  // ... add to word count
                  flag = 1;   // and set flag to skip not first letters
              }
              continue;
          }
          if ( isspace(ch) || ispunct(ch) )  // if word separator ...
          {
              flag = 0;                      // ... reset flag
          }
      }
      

      【讨论】:

      • 你为什么有continue
      • continue 只是为了小优化,也可以在第二个if ( isspace ... 之前代替这个else。我希望文本中有很多字母和少量空格,所以首先检查字母,当它是true 时,检查空格或标点符号没有意义。
      猜你喜欢
      • 2016-07-13
      • 2022-07-31
      • 1970-01-01
      • 1970-01-01
      • 2022-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-27
      相关资源
      最近更新 更多