【问题标题】:fgetc() not working as I had hopedfgetc() 没有像我希望的那样工作
【发布时间】:2014-03-09 18:19:14
【问题描述】:

我希望我不会因此而很快被否决,但我有一个正在为学校工作的项目,我必须在其中构建一个拼写检查器。我决定使用 trie,它似乎工作正常,但我有一个我找不到的错误。我认为问题出在以下,

bool load(const char* dictionary)
{

    if (!rootNode)
    {
        rootNode = trieNodeCreate();
        if (!rootNode)
        {
            printf("could not allocate root node");
            return false;
        }
    }

    // Open the file 
    FILE* fp = fopen(dictionary, "r");

    if (fp == NULL)
    {
        printf("could not open dictioanry %s\n", dictionary);
        return false;
    }


    int index = 0;
    for (int c = fgetc(fp); c != EOF; c = fgetc(fp))
    {
        char word[LENGTH];
        if (c != '\n' )
        {
            word[index] = c;
            index++;
        }
        else
        {
            trieWordInsert(word, rootNode);
            index = 0;
                wordCount ++;

        } 

    }
    fclose(fp);

    if (wordCount)
    {
        return true;
    }
    return false;
}

但我一直找不到它。该项目的其余部分可以在

找到

https://github.com/iMillJoe/spell-checker

【问题讨论】:

  • 使用所有警告和调试信息进行编译(例如使用gcc -Wall -g)。 使用调试器(例如gdb
  • 在 X-Code 中构建它,我没有收到任何警告。使用 lldb,我可以看到问题,但看不到问题所在。
  • 请更具体一点:您看到的错误是什么?干杯
  • @Mblanc,似乎我可以确定拼写正确的唯一词是“a”,尽管当我在项目之外测试它时我的 trie 似乎工作得很好,因此我认为错误在于在这里,我将我的 trie 插入发行版代码。
  • 单词是否用换行符分隔?

标签: c trie fgetc


【解决方案1】:

在循环之外声明你的word[LENGTH] 数组,否则它只会丢弃word 指针并在每个循环结束时释放分配的,创建一个新的。我不认为你想要那样,我认为你宁愿只在 if 条件没有得到满足时才想要那样。

我可能不知道 trieWordInsert 做了什么,但我会假设您需要一个 0 终结器。

  • for( ... ) { ... } 之前声明word[LENGTH] = { 0 };
  • else 块内添加memset( word, 0, LENGTH);
  • 如果您目前还没有包含其中任何一个,请为 memset 添加 memory.hstring.h

我认为应该是这样的......

编辑:在了解了trieWordInsert 或多或少的问题后,word 被推入...

EZ 模式的直接代码:

bool load( const char* dictionary )
{

    if ( !rootNode )
    {
        rootNode = trieNodeCreate( );
        if ( !rootNode )
        {
            printf( "could not allocate root node" );
            return false;
        }
    }

    // Open the file 
    FILE* fp = fopen( dictionary, "r" );

    if ( fp == NULL )
    {
        printf( "could not open dictioanry %s\n", dictionary );
        return false;
    }

    int index = 0;
    char word[LENGTH];
    for ( int c = fgetc( fp ); c != EOF; c = fgetc( fp ) )
    {
        if ( c != '\n' )
        {
            word[index] = c;
            index++;
        }
        else
        {
            word[index] = 0;
            trieWordInsert( word, rootNode );
            index = 0;
            wordCount++;
        }

    }
    fclose( fp );

    if ( wordCount )
    {
        return true;
    }
    return false;
}

【讨论】:

  • memset 有点矫枉过正;只需确保在发送之前终止字符串(也应防止添加空字符串,但 OP 可能会“正确”解析“正确”数据,因此可能没什么大不了的。不过,这个答案是可靠的,然后打勾。
  • @WhozCraig 谁知道...也许他在trieWordInsert 内部做了一些奇怪的事情,要求word 指向的每个字符对于LENGTH long 都为零。我只是想确定一下。
【解决方案2】:

我认为你没有以'\0'结束单词

char word[LENGTH];
 if (c != '\n' )
 {
     word[index] = c;
     index++;
 }
 else
 {
     word[index] = '\0'; //missing this one!!!
     trieWordInsert(word, rootNode);
     index = 0;
     wordCount ++;
 } 

我认为您最好使用fscanf 并逐字阅读文件。

【讨论】:

  • 在项目规范中警告不要使用 fscanf()。
  • 任何字符串都必须有一个终止的空值。在调用trieWordInsert 之前尝试打印单词并与文件进行比较。
  • @Joe - trieWordInsert 如何知道插入的单词有多长?当然,所有单词都不完全是LENGTH long。
  • @MattMcNabb 您可能正在做某事,trieWordInsert 调用 strlen() 来计算字符串的长度。 (LENGTH 为 45,英语中最长的单词)如果 '/0' 不是字符串的结尾,strlen() 将不起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-30
  • 2016-12-03
  • 2021-10-06
  • 1970-01-01
  • 2019-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多