fscanf()函数错误

时间:2014-10-11 05:48:21

标签: c scanf

我是c编程的新手。我使用fscanf()函数编写了一个程序:

fscanf(fileptr, "%s\n", word);

但是当我运行该程序时,它被困在终端中。我尝试在程序上运行GDB,它显示以下行:

109     for (int i = 0; i < 100; i++)
(gdb) 
111         fscanf(fileptr, "%s\n", word);
(gdb) 
__isoc99_fscanf (stream=0x603010, format=0x400cbd "%s\n") at isoc99_fscanf.c:26
26  isoc99_fscanf.c: No such file or directory.

然后是这些界限:

(gdb) 
_IO_vfscanf_internal (s=s@entry=0x603010, format=0x400cbd "%s\n", argptr=argptr@entry=0x7fffffffdd48, errp=errp@entry=0x0) at vfscanf.c:225
225 vfscanf.c: No such file or directory.

编译器有什么问题,或者我错过了什么?我编译:

gcc -ggdb3 -O0 -std=c99 -Wall -Werror hash.c -o hash

以下是完整代码:

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

#define MAXLENGTH 10

// structure for each node in hash
typedef struct node
{
    char* word;
    struct node* next;
}
node;

// global pointer for the root node
node* root = NULL;
node* table[26] = {};

// function declearations
int hash_function(char data[MAXLENGTH]);
void load_words(FILE* fileptr);
bool check_word(char* word);

// main function takes command line arguments
int main(int argc, char** argv)
{
    // validates user input at command line
    if (argc != 2)
    {
        printf("Invalid Input!\n");
        printf("Usage : ./hash <word>\n");
        return 1001;
    }

    // loads the dictionary
    FILE* file_ptr = fopen("dictionary.txt", "r");
    if (file_ptr == NULL)
    {
        printf("failed to load the file!\n");
        return 1002;
    }
    else
    {
        load_words(file_ptr);
    }

    // checks if the word is in dictionary
    if (check_word(argv[1]) == true)
    {
        printf("Word spelled right!\n");
        return 0;
    }
    else
    {
        printf("Word spelled wrong!\n");
        return 0;
    }
}

// hash function
int hash_function(char data[MAXLENGTH])
{
    if (isalpha(data[0]) != 0)
    {
        int res = tolower(data[0]);
        res = res - 'a';
        return res;
    }
    else
    {
        printf("not a word!\n");
        return -1;
    }
}

// check_word function
bool check_word(char* word)
{
    int hash = hash_function(word);
    if (hash != -1)
    {
        root = table[hash];

        while(root != NULL)
        {
            if (strcmp(word, root->word) == 0)
            {
                return true;
            }
        }
    }
    return false;
}

// load words into hash table
void load_words(FILE* fileptr)
{
    char word[10];

    for (int i = 0; i < 100; i++)
    {
        fscanf(fileptr, "%s\n", word);

        int hash = hash_function(word);

        if (hash != -1)
        {
            if (table[hash] == NULL)
            {
                table[hash] = malloc(sizeof(node));
                if (table[hash] == NULL)
                {
                    printf("memory allocation failed!\n");
                    return;
                }

                table[hash]->word = word;
                table[hash]->next = NULL;
            }
            else
            {
                root = table[hash];

                while (root->next != NULL)
                    root = root->next;

                node* newNode = malloc(sizeof(node));
                if (newNode == NULL)
                {
                    printf("memory allocation failed!\n");
                    return;
                }

                newNode->word = word;
                newNode->next = NULL;

                root->next = newNode;
            }       
        }
        else
        {
            printf("hash failed!\n");
        }
    }
}

我正在使用Ubuntu 14.04并且我已经安装了build-essential。任何建议都将非常感谢。

提前致谢。

2 个答案:

答案 0 :(得分:3)

您的check_word函数包含明显的无限循环

    root = table[hash];

    while(root != NULL)
    {
        if (strcmp(word, root->word) == 0)
        {
            return true;
        }
    }

如果hash bucked不为空并且第一个条目不匹配,它将永远循环,因为你永远不会沿着碰撞链前进root指针。

您的代码的另一个主要问题是在load_words函数中,您在所有哈希条目中存储指向同一本地word数组的指针。即所有node个对象都使用word指针指向同一个本地数组。这没有意义,也没有机会正常工作。当load_words函数退出时,本地word数组将被销毁,并且所有散列节点中的所有word指针都将变为无效。

每个哈希节点必须拥有自己的word内存。你将如何实现这一目标取决于你。在wordnode声明数组,而不是指针,然后将strcpy本地word声明为节点的word。或者在散列节点中存储每个单词时使用strdup

答案 1 :(得分:1)

你的另一个问题来自这条线,因为&#34; word&#34;是堆栈上的局部变量

table[hash]->word = word;

您需要为&#39; word&#39;分配存储空间。 e.g。

table[hash]->word = strdup(word);