2014-10-11 2 views
2

Я новичок в программировании. Я написал программу, используя fscanf() функцию:fscanf() function error

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 ([email protected]=0x603010, format=0x400cbd "%s\n", [email protected]=0x7fffffffdd48, [email protected]=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, и я установить встроенный существенно. Любые советы были бы очень оценены.

Заранее спасибо.

+1

эти файлы являются частью * исходного кода 'glibc', почему вы хотите отладить это? – Amro

+2

Вы должны учитывать, что 'fscanf' правильно ведет себя, согласно его спецификации (см. [Fscanf (3)] (http://man7.org/linux/man-pages/man3/fscanf.3.html) ...). Поэтому вы должны использовать команду 'next'' gdb'. Однако вы должны использовать результат 'fscanf'. Ошибки находятся в вашем коде (который вы не показываете). –

+0

Почему тег * компилятор-конструкция *? Это не имеет значения! Пожалуйста, ** отредактируйте свой вопрос **, чтобы улучшить его! –

ответ

3

Ваша check_word функция содержит очевидный бесконечный цикл

root = table[hash]; 

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

Если хэш воспротивился не пусто и очень первая запись не соответствует, это будет цикл навсегда, так как вы никогда не продвигать root указатель вдоль столкновения цепь.

Еще одна серьезная проблема с вашим кодом заключается в том, что в функции load_words вы храните указатель на тот же локальный массив word во всех ваших хэш-записях. То есть все объекты node указывают на один и тот же локальный массив с указателями word. Это не имеет смысла и не имеет шансов работать должным образом. И когда функция load_words выходит из строя, локальный массив word уничтожается, и все ваши указатели word во всех хэш-узлах становятся недействительными.

Каждый хэш-узел должен иметь собственную память word. Как вы собираетесь это достичь, зависит от вас. Либо объявите word внутри node как массив, а не указатель, а затем strcpy локальный word в word узла. Или используйте strdup при сохранении каждого слова в хэш-узле.

+1

Это скорее комментарий, чем ответ. –

+0

спасибо. Теперь код работает, но у меня возникла логическая проблема. Хэш-таблица работает не так, как ожидалось. Но я это выясню. Еще раз спасибо. –

+0

Большое спасибо за ответ логической ошибки. –

1

другая Ваша проблема исходит от этой линии, так как «слово» является локальным переменным в стеке

table[hash]->word = word; 

вам нужно выделить память для «слова», например

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