【问题标题】:C Program to count the word frequency in a text fileC程序计算文本文件中的词频
【发布时间】:2019-01-08 16:03:58
【问题描述】:

我需要能够在 C 编程中编写代码,该代码可以读取文本文件并找出每个单词的数量并输出该单词以及它出现的次数。现在我有代码可以打印出每个单词以及它出现的次数,但我需要它按字母顺序打印并忽略大写字母。例如,“It”和“it”应该算作同一个词。我不确定在我的代码中的哪个位置包含修订。下面是我的代码示例。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
    if (argc == 1) {
        printf("The input file name has not been provided\n");
    } else if (argc == 2) {
        FILE *f = fopen(argv[1], "rb");
        fseek(f, 0, SEEK_END);
        long fsize = ftell(f);
        fseek(f, 0, SEEK_SET);

        char *str = malloc(fsize + 1);
        fread(str, fsize, 1, f);
        fclose(f);

        str[fsize] = 0;
        int count = 0, c = 0, i, j = 0, k, space = 0;
        char p[1000][512], str1[512], ptr1[1000][512];
        char *ptr;
        for (i = 0; i < strlen(str); i++) {
            if ((str[i] == ' ') || (str[i] == ',') || (str[i] == '.')) {
                space++;
            }
        }
        for (i = 0, j = 0, k = 0; j < strlen(str); j++) {
            if ((str[j] == ' ') || (str[j] == 44) || (str[j] == 46)) {
                p[i][k] = '\0';
                i++;
                k = 0;
            } else
                p[i][k++] = str[j];
        }
        k = 0;
        for (i = 0; i <= space; i++) {
            for (j = 0; j <= space; j++) {
                if (i == j) {
                    strcpy(ptr1[k], p[i]);
                    k++;
                    count++;
                    break;
                } else {
                    if (strcmp(ptr1[j], p[i]) != 0)
                        continue;
                    else
                        break;
                }
            }
        }
        for (i = 0; i < count; i++) {
            for (j = 0; j <= space; j++) {
                if (strcmp(ptr1[i], p[j]) == 0)
                    c++;
            }
            printf("%s %d \n", ptr1[i], c);
            c = 0;
        }
    }
    return 0;
}

【问题讨论】:

  • “忽略大写字母”是最简单的部分。读取文件后,通过char 遍历它char 并执行str[i] = toupper((unsigned char) str[i]);

标签: c word-count


【解决方案1】:

这是一个最小的提议,您的代码可能需要分解为函数,但请考虑这只是某种提议草案。 您可以简单地将strcmp 替换为strcasecmp 用于区分大小写的部分。

然后进行排序,可以使用qsort: 定义一个比较函数,例如:

int compar(const void *a, const void *b)
{
        return *(char *)a - *(char *)b;
}

并将其应用于您的单词数组。 据我了解,ptr1 似乎持有你的话,所以你可以添加

   qsort(ptr1, count, sizeof(ptr1[0]), compar);

在最后一个 for 循环之前。

尽管如此,在我看来,您需要修复提取循环,因为 valgrind 在您的代码中报告了一些错误。

【讨论】:

    【解决方案2】:

    这是使用milkstrings函数的示例函数

        typedef struct tWord {
          tXt tx ;
          int count ;
          struct tWord *   next ; } tWord;
        typedef struct tWord *pWord;
    
        void wordfrequency(void) {
          pWord np,prev,bprev,most,allword ;
          allword = NULL ;
          FILE * fi = fopen("sample.txt","r") ;
          if (fi == NULL)
            return ;
          tXt rlin = " " ;
          while (rlin != txtEndFile) {
            tXt lin = txtUpcase(txtTrim(rlin = txtFromFile(fi))) ;
            while (lin[0]) {
              tXt wrd = txtTrim(txtEat(&lin,' ')) ;
              np = allword ;
              while (np) {
                if (strcmp(np->tx,wrd) == 0) {
                  np->count++ ;
                  wrd = "" ; 
                  np = NULL ;
                  }
                else
                  np = np->next ;}
              if (wrd[0]) {
                np = (pWord) malloc(sizeof(tWord)) ;
                np->tx = fridge(wrd) ;
                np->count = 1 ;
                np->next = allword ;
                allword = np ; } } }
          while (allword) {
            prev = bprev = NULL ;
            np = most = allword ;
            while (np) {
              if (strcmp(most->tx , np->tx) >0 ) {
                most = np ;
                bprev = prev ; }
              prev = np ;
              np = np->next ; }
            printf("%5d %s\n",most->count,unfridge(most->tx)) ;
            if (bprev)
              bprev->next = most->next ;
            else
              allword = most->next ;
            free (most) ;  }
          fclose(fi) ;
          if (txtAnyError())
            printf("%s\n",txtLastError()) ;
    
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-22
      • 2011-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多