Прочитать имена из файла .txt и добавить его в связанный список - PullRequest
0 голосов
/ 12 октября 2018

Я хочу создать связанный список, который содержит имена из файла input.txt.Имя и фамилия отделяются пробелом, а после фамилии - разрыв строки.

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

typedef struct node{
   char* firstname;
   char* lastname;
   struct node *next;
   }node;

node *add(node *head, char* fnme, char* lnme){
   node *new_node;
   new_node = (node*)malloc(sizeof(node));
   if(new_node == NULL)
      printf("Fehler bei Speicher reservierung...");
   new_node->firstname = (char*)malloc(100*sizeof(char));
   if(new_node->firstname == NULL)
      printf("Fehler bei Speicher reservierung...");
   new_node->lastname = (char*)malloc(100*sizeof(char));
   if(new_node->lastname == NULL)
      printf("Fehler bei Speicher reservierung...");

   strcpy(new_node->firstname, fnme);
   strcpy(new_node->lastname, lnme);

   if(head == NULL){
      head = new_node;
      head->next = NULL;
      return head;
   }

   node *current;
   current = head;

   while(current->next != NULL){
      current = current->next;
   }

   current->next = new_node;
   new_node->next = NULL;
   return head;
 }

 void print(node *head){
   node *current;
   current = head;

   while(current != NULL){
     printf("%s %s\n", current->firstname, current->lastname);
     current = current->next;
    }
   }

int main(){

  node *head = NULL;

  char character;

  FILE *fp;
  fp = fopen("input.txt", "r");

  while ((character = fgetc(fp)) != EOF) {
  char *fnme, *lnme;
  fnme = (char*)malloc(100 * sizeof(char));
  if(fnme == NULL)
     printf("Fehler bei Speicher reservierung...");
  lnme = (char*)malloc(100 * sizeof(char));
  if(lnme == NULL)
     printf("Fehler bei Speicher reservierung...");

  int i = 0;
  while (character != ' ') {
     fnme[i++] = character;
     character = fgetc(fp);
  }
  fnme[++i] = '\0';   // NULL-terminate

  i = 0;
  while (character != '\n') {
     lnme[i++] = character;
     character = fgetc(fp);
  }
  lnme[++i] = '\0';  // NULL-terminate

  head = add(head, fnme, lnme);   

  free(fnme);
  free(lnme);
 }
 print(head);
 return 0;
}

Я никогда не работал с strcat, почему-то это не работает.Я также попытался использовать массивы вместо указателей, но результат тот же.Может быть, мне нужно использовать другие функции?

Обновление 1:

Каким-то образом вывод выглядит странно, кажется, что он никогда не идет в блоке if в функции add ().Вывод с 2 именами в .txt-файл: pt?пт?Питер Паркер Кларк Кент

Обновление 2:

Изменен тип возврата функции add (), теперь она работает:)

Ответы [ 3 ]

0 голосов
/ 12 октября 2018

Измените свой код немного, и он должен работать.Вы не можете использовать strcat таким образом, так как второй параметр strcat принимает const char *, и у вас есть char, поэтому ваш код не будет компилироваться.

Также здесь стоит отметить: Я предполагаю, что функция add сделает глубокую копию для fnme и anme, в противном случае вы не можете просто освободить их здесь.

while ((character = fgetc(fp)) != EOF) {
    char *fnme, *anme;
    fnme = malloc(100 * sizeof(char));
    anme = malloc(100 * sizeof(char));

    int i = 0;
    while (character != ' ') {
        fnme[i++] = character;
        character = fgetc(fp);
    }
    fnme[++i] = '\0';   // NULL-terminate

    i = 0;
    while (character != '\n') {
        anme[i++] = character;
        character = fgetc(fp);
    }
    anme[++i] = '\0';  // NULL-terminate

    add(head, fnme, anme);   // Assume 'add' will make deep copy of both fname and 
                             // anme, otherwise you cannot free them here.
    free(fnme);
    free(anme);

}
0 голосов
/ 12 октября 2018

У вас есть ошибки в функции add().Это полное решение.Кстати, так как это дополнительный вопрос, вам лучше задать его в новом сообщении, а не обновлять исходный.

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

typedef struct node{
  char *forame;
  char *aftername;
  struct node *next;
}node;

void add(node **head, char* fnme, char* lnme){
  node *new_node;
  new_node = (node*)malloc(sizeof(node));
  new_node->forame = (char*)malloc(100*sizeof(char));
  new_node->aftername = (char*)malloc(100*sizeof(char));

  strcpy(new_node->forame, fnme);
  strcpy(new_node->aftername, lnme);

  if (*head == NULL){
    *head = new_node;
    new_node->next = NULL;
    return;
  }

  node *current;
  current = *head;

  while(current->next != NULL){
     current = current->next;
  }

  current->next = new_node;
  new_node->next = NULL;
}

void print(node *head){
   node *current;
   current = head;

  while(current != NULL){
      printf("%s %s\n", current->forame, current->aftername);
      current = current->next;
  }
}

int main() {

  node *head = NULL;
  char character;

  FILE *fp;
  fp = fopen("input.txt", "r");

  while ((character = fgetc(fp)) != EOF) {
      char *fnme, *lnme;
      fnme = (char*)malloc(100 * sizeof(char));
      lnme = (char*)malloc(100 * sizeof(char));

      int i = 0;
      while (character != ' ') {
          fnme[i++] = character;
          character = fgetc(fp);
      }
      fnme[++i] = '\0';

      i = 0;
      while (character != '\n') {
          lnme[i++] = character;
          character = fgetc(fp);
      }
      lnme[++i] = '\0';

      add(&head, fnme, lnme);

     free(fnme);
     free(lnme);
  }

  print(head);
  return 0;
}
0 голосов
/ 12 октября 2018

strcat определенно не подходит.Как должен сказать ваш компилятор, вы сначала передаете ему неверный тип переменной.Требуется 2 строки, а character - это просто char.

. Строки в C обнуляются и имеют только что выделенную память для anme и fnme, ни одна из них не будет инициализирована, поэтому выиграно 'не может содержать это NUL-завершение, поэтому вы будете испытывать неопределенное поведение.

Вместо этого просто обращайтесь с ними как с массивом и сохраняйте символы в том виде, в каком вы их читаете, а затем не забудьте завершить NUL, когда закончите читать все символы.

int count = 0;

do{  
    fnme[count++] = character;
    character = fgetc(fp);
}while(character != ' ');
fnme[count]='\0'; // Need to NUL terminate the string

count = 0; // Remember to reset count to 0
do{  
    anme[count++] = character;
    character = fgetc(fp);
}while(character != '\n');
anme[count]='\0'; // Need to NUL terminate the string

Этот метод также позволяет вам проверить, что count не превышает выделенный вами размер, который в данном случае равен 99, так как последний пробел необходим для символа NUL.

...