【问题标题】:Counting word occurrences in a file C计算文件 C 中的单词出现次数
【发布时间】:2015-06-12 17:03:48
【问题描述】:

欢迎大家。我是 Stackoverflow 的新手,我用 C 编码了一段时间。 我在编写一个计算文本文件中单词出现次数的程序时遇到了问题。我需要有一个输出告诉哪个单词出现了多少次。以下是源代码:

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

int new_words=0;
int nwords=0;

typedef struct element{
    char word[30];
    int how_many;
} element;

int is_word_new(element ** dictionary, char * string)
{
    for (int i =0; i<new_words; i++)
    {
        if (strcmp(string, dictionary[i]->word)==0)
            return 0;
    }
    return 1;
}
int which_word(element ** dictionary, char * string)
{
    for (int i =0; i<new_words; i++)
    {
        if (strcmp(string, dictionary[i]->word)==0)
            return i;
    }
    return 0;
}

int main()
{
    FILE * fp;
    char word[30];


    fp=fopen("input.txt", "r");
    if (fp==NULL)
    {
        printf("FILE ERROR");
        return 0;
    }


    while(!feof(fp))
    {
        fscanf(fp, "%s",word);
        nwords++;
    }
    nwords--;
    rewind(fp);

    struct element * dictionary = (element*)malloc(sizeof(element)*nwords);

    for (int i =0; i<nwords; i ++)
    {
        fscanf(fp, "%s", word);

        if( is_word_new(&dictionary, word) )
        {
            strcpy(dictionary[new_words].word, word);
            //dictionary[new_words].word= word;
            dictionary[new_words].how_many=1;
            new_words++;
        }
        else
            dictionary[which_word(&dictionary, word)].how_many++;
        word[0]='\0';
    }

    printf("\n\nFinal dictionary\n with %d words", new_words);
    for (int i =0; i<new_words; i++)
    {
        printf("%s %d \n", dictionary[i].word, dictionary[i].how_many);     
    }

    free(dictionary);
    fclose(fp);
    return 0;
}

这个想法是我首先计算文本中有多少个单词(不知何故,它总是比实际大一)。函数 is_word_new 检查字典中是否已经有一个新读的单词。 which_word() 告诉我们找到了哪个单词

但是,运行此程序时出现分段错误。 当我使用注释为// dictionary[i].word=word 的行时,程序的行为就像字典中只有“单词”一样。

请给我提示我在哪里做错了这些事情

【问题讨论】:

  • 我希望有一个程序来统计这个问题在 SO 上出现的次数...
  • is_word_new(element ** dictionary... : element ** dictionary 表示 {element *,element *,...},dictionary 是指向顶部的指针。但实际上是指向 {element ,element ,...} 的指针的指针
  • @BLUEPIXY,我不确定您的评论是什么意思,但这与我在下面回答的类似,对吧?抱歉问了,但我真的很想拿精炼徽章,所以我的回答必须是好的才能获得至少一个赞成票。
  • @gsamaras 对不起我的英语不好。我的迹象是,假设的实际情况不同。我同意“无需传递双指针”
  • 哦,我看到了@BLUEPIXY,至少该评论可能会给我一个获得该徽章的机会(通过激活问题)。 :P

标签: c string count


【解决方案1】:

必读问题:Why is “while ( !feof (file) )” always wrong? 感谢 Jonathan Leffler 的评论。


请在下面的代码中检查我的 cmets。当单词出现一次时,我让你开始了。我把剩下的工作交给你,这样我们就可以分享乐趣,但你当然可以问。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int new_words = 0;
int nwords = 0;

typedef struct element {
    char word[30];
    int how_many;
} element;

// no need to pass double pointer
int is_word_new(element* dictionary, char * string) {
    int i;
    for (i = 0; i < new_words; i++) {
        printf("|%s|, |%s|\n", string, dictionary[i].word);
        if (strcmp(string, dictionary[i].word) == 0)
            return 0;
        printf("i=%d\n",i);
    }
    return 1;
}

int which_word(element ** dictionary, char * string) {
    int i;
    for (i = 0; i < new_words; i++) {
        if (strcmp(string, dictionary[i]->word) == 0)
            return i;
    }
    return 0;
}

int main() {
    FILE * fp;
    char word[30];


    fp = fopen("test.txt", "r");
    if (fp == NULL) {
        printf("FILE ERROR");
        return 0;
    }

    printf("file read\n");

    int read_counter;
    while (!feof(fp)) {
        read_counter = fscanf(fp, "%s", word);
        // increment only if we really read something
        if(read_counter >= 0)
                nwords++;
    }
    // this is wrong, remove it
    //nwords--;
    rewind(fp);

    printf("nwords = %d\n", nwords);
    // do not cast what malloc returns. Also struct is not needed.
    element * dictionary = malloc(sizeof (element) * nwords);

    int i;
    for (i = 0; i < nwords; i++) {
        fscanf(fp, "%s", word);
        printf("read |%s|\n", word);
        if (is_word_new(dictionary, word)) {
            strcpy(dictionary[new_words].word, word);
            //dictionary[new_words].word= word;                     
            dictionary[new_words].how_many = 1;
            new_words++;
        } else {
            printf("bhka\n");
            dictionary[which_word(&dictionary, word)].how_many++;
        }
        //word[0] = '\0';
    }

    printf("\n\nFinal dictionary\n with %d words", new_words);
    for (i = 0; i < new_words; i++) {
        printf("%s %d \n", dictionary[i].word, dictionary[i].how_many);
    }

    free(dictionary);
    fclose(fp);
    return 0;
}

这是我使用的test.txt:

sam klouvi george dit epfl
ok
end

【讨论】:

  • 感谢您的帮助,它确实有效。我真的不知道为什么,但是帮助将双指针从what_word()中的“字典”更改为单指针。现在它可以正常工作了。
猜你喜欢
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-24
  • 2021-04-19
  • 1970-01-01
相关资源
最近更新 更多