Как вы читаете файл строк в связанный список? (С)

Моя структура определяется следующим образом:

typedef struct node {
  char * word;
  int wordLength;
  int level;
  struct node * parent;
  struct node * next;
}Node;

Я пытаюсь создать связанный список структуры выше, где «слово» — это строка, которая читается из файла. Ниже приведена функция, которую я использую для создания списка. Кажется, он работает нормально и печатает слова, но затем, когда я пытаюсь распечатать его в main(), он ничего не печатает.

void GetWords(char * dictionary, Node * Word, Node * Start)
{
  FILE *fp;
  char * currentWord = (char *)malloc(sizeof(char));
  fp = fopen(dictionary, "r");
  ErrorCheckFile(fp);
  if(fscanf(fp, "%s", currentWord) == 1){
    Start = Word = AllocateWords(currentWord);
  }

  while((fscanf(fp, "%s", currentWord)) != EOF){
    Word->next = AllocateWords(currentWord);
    Word = Word->next;
    printf("%s: %d\n", Word->word, Word->wordLength);
  }



  fclose(fp);
}

Нужно ли возвращаться к началу списка? Если да, то как бы я это сделал? В этой функции у меня "Старт" указывает на первое слово в файле, нужно ли мне это? Я пытаюсь распечатать их, просто чтобы убедиться, что файл правильно хранится в списке.

Моя функция main():

int main(int argc, char ** argv)
{
  Node * Word = (Node *)malloc(sizeof(Node));
  Node * Start = (Node *)malloc(sizeof(Node));
  GetWords(argv[1], Word, &Start);


  printf("Start: %s\n", Start->word);
  printf("Word: %s\n", Word->word);
  while(Word->next != NULL){
    printf("%s\n", Word->word);
  }

  return 0;
}

Операторы печати находятся там только для того, чтобы проверить, печатается ли список. В нынешнем виде Start->word печатает последнее слово в файле, а Word->word печатает (null), а цикл while вообще не выполняется.

Моя функция AllocateWords() выглядит следующим образом:

Node * AllocateWords(char * string)
{
  Node * p;
  p = (Node *)malloc(sizeof(Node));
  if(p == NULL){
    fprintf(stderr, "ERROR: Cannot allocate space...\n\n");
    exit(1);
  }
  p->word = string;
  p->wordLength = strlen(p->word);
  p->parent = NULL;
  p->next = NULL;
  return p;
}

person liamw9    schedule 20.11.2015    source источник
comment
sizeof(char) равен 1, а это очень мало места для хранения строки.   -  person M Oehm    schedule 20.11.2015
comment
Также проблема в том, что Word и Start являются локальными переменными. Изменения, которые вы в них вносите, не будут отражены в функции, из которой вызывается GetWords.   -  person M Oehm    schedule 20.11.2015


Ответы (1)


Используйте вызов по ссылке вместо вызова по значению для указателя Start.

основная функция:

Node * Start

GetWords(..., &Start)

и

 void GetWords(char * dictionary, Node * Word, Node ** Start)
 {

  ....
  *Start = Word = AllocateWords(currentWord);
  ....

Вам также необходимо исправить размер currentWord. Если максимальная длина слова составляет 255 символов, используйте:

char * currentWord = (char *)malloc(256*sizeof(char));
...
if(fscanf(fp, "%255s", currentWord) == 1){
...
while((fscanf(fp, "%255s", currentWord)) != EOF){

Вам также необходимо исправить вашу функцию main(). Вам не нужно выделять текущий указатель слова Word или указатель узла Start.

...
Node * Word = (Node *) NULL;
Node * Start = (Node *) NULL;
GetWords(argv[1], Word, &Start);

printf("Start: %s\n", Start->word);
Word = Start;
while(Word->next){           // identical to while(World->next!=NULL){      
  Word=Word->next;
  printf("%s\n", Word->word);
}  
person jofel    schedule 20.11.2015
comment
Спасибо! Единственная проблема заключается в том, что когда я распечатываю Start в main(), он указывает на последнее слово в файле, а не на первое (именно это я и намеревался указать) - person liamw9; 20.11.2015
comment
@ liamw9 Можете ли вы перечислить AllocateWords и свою процедуру вывода - может быть, ошибка где-то здесь. - person jofel; 20.11.2015
comment
@ liamw9 Ошибка действительно была в вашей основной функции. Вы не правильно повторили. - person jofel; 20.11.2015