【问题标题】:Using fscanf to count number of occurrences of a word使用 fscanf 计算单词的出现次数
【发布时间】:2014-05-08 09:07:44
【问题描述】:

我必须为作业编写一个程序来扫描文本文件并说出有多少句子(基于句号,没有其他标点符号)总单词数和总次数词出现。我可以计算总字数,但具体的字数和句子数让我望而却步,我相信我们应该使用fscanf。这是我所拥有的

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
FILE *datafile;
int main(){
    int count1, count2, leng, sentences ;
    char filename[50], word[120], sentence[120];
    printf("Enter a word :");
    gets(word);
    printf("Enter the filename:");
    gets(filename);
    datafile = fopen(filename, "r");
    if(datafile == NULL) {
        printf("Error , Can not open %s", filename);
        exit(249);
    }

    leng = 0;
    count2 = 0;
    sentences = 0;

    while (fscanf(datafile, "%s", word) == 1) {     //this one works
        ++leng;
    }
    while (!feof(datafile))
    { 
        fscanf(datafile,"%s",word);
        if (strcmp(word,"the")==0)
            count2++;
    }

    while(fscanf(datafile, "%s", word) == '.') {
        ++sentences;
    }
    printf("There are a total of %d words\n", leng);
    printf("The word '%s' appears %d times\n", word, count2);
    printf("There are %d sentences", sentences);

}

当我运行它时,我得到

我尝试了两种不同的方法来计算句子计数和特定字数,但我真的不明白为什么第一种也有效,我想一旦我有了其中一种,另一种将是相同的格式。感谢您提供任何帮助或建议。

【问题讨论】:

  • fscanf 返回成功匹配和分配的输入项的数量,可以少于提供的数量,如果早期匹配失败,甚至为零。您正在将一个 int 值与 '.' 进行比较。 .
  • 请注意,您应该使用fgets(word, sizeof(word), stdin); 而不是gets(word); 以避免缓冲区溢出。

标签: c scanf


【解决方案1】:

您的代码有几个问题。

  • 您在三个连续的 while 循环中读取文件。但是,第二个和第三个循环永远不会进入,因为在使用fscanf 扫描文本后,文件已用尽。您可以在重新阅读之前rewind您的文件,但最好一次性完成所有三个计数。
  • 您可以将变量word 用于各种事情:作为用户指定的单词以及作为您扫描的单词的临时缓冲区。这就是您的屏幕截图显示“1972”的原因。作为要查找的单词,而不是用户输入的“of”。 (在计算该单词时,您会检查硬编码的单词“the”。)
  • fscanf 的返回值是成功匹配的% 项目数或表示已到达文件末尾的特殊值EOF。您已经在第一个循环中正确使用了它。请不要使用feof 添加额外的检查,因为它的行为不像大多数人认为的那样,请参阅this self-answered question
  • 查找句号时使用fscanf 的方式在语法上是正确的,因为它返回一个int 和一个int 中点'.' 的ASCII 值,但这不是您想要的。 fscanf%sformat 返回一个字符串,而不是单个字符。另请注意,fscanf 的句子和标点符号的概念与我们的不同:句号可能位于字符串的末尾,如屏幕截图中的 "1972."。因此,您应该检查单词是否有句号。您可以通过 strchr 做到这一点。

【讨论】:

    【解决方案2】:

    完整的程序在这里:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    FILE *datafile;
    int main(){
        int count1, count2, leng, sentences ;
        char filename[50], word[120],word1[120] ,sentence[120];//word1 is new string
        printf("Enter a word :");
        gets(word1);
        printf("Enter the filename:");
        gets(filename);
        datafile = fopen(filename, "r");
        if(datafile == NULL) {
            printf("Error , Can not open %s", filename);
            exit(249);
        }
    
        leng = 0;
        count2 = 0;
        sentences = 0;
    
        while (fscanf(datafile, "%s", word) == 1) {     //this one works
            ++leng;
    
            if (strcmp(word,word1)== 0)//strcmp returns 0 when it matches word to word1
                count2++;
    
            if ( strchr(word,'.') != NULL )//strchr returns a pointer when it matches word to '.' null otherwise
                ++sentences;
        }
    
        printf("There are a total of %d words\n", leng);
        printf("The word '%s' appears %d times\n", word1, count2);
        printf("There are %d sentences", sentences);
    
        return 0;
    }
    

    看看各种字符串函数和返回值。 Here!

    【讨论】:

    • 除非 scannef 文件总是用空格将标点符号与单词分开,否则您的程序将找不到任何句子。通常,句号在它们前面的单词之间没有空格,因此您可能不应该将字符串与"." 进行比较,而是检查它是否包含句号。
    • 是的,你是对的。感谢您花时间回答这个问题
    • 请注意,如果gets,则应使用fgets
    • 在哪里?我正在阅读标准输入。我想我不必使用 fget。
    【解决方案3】:

    我给你一些提示:

    要获得句子计数,您可以使用strtok 和分隔符作为"."(句号)。

    要获取字数,请使用strtok,并将分隔符作为" "(空格)。

    要获得单词重复计数,您可以使用 strstr 并搜索该特定单词。

    更新: 要使用strstr,您可以使用fgets 将文件内容(逐行)读入缓冲区字符串,然后使用strstr 在该句子/字符串中查找特定单词,然后再次阅读下一个句子进入缓冲区字符串(再次使用fgets),依此类推,直到到达End-Of-File

    了解更多关于这些函数的信息:fgetsstrstrstrtok

    【讨论】:

    • 无需注意双空格 - strtok 将分隔符序列视为单个分隔符。
    • 对不起,我仍然是一个菜鸟,尤其是字符串,我从未使用过 strstr,我将如何使用它来执行此操作,我不确定您将如何格式化它来读取变量 word
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-09
    • 2021-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多