Read names from .txt File and add it to a linked list

Feliboy Source

I want to create a linked list, wich contains names from a input.txt File. First name and last name are seperatet by a blank space and after the last name there is a linebreak.

#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;
}

I never worked with strcat, somehow that doesnt work. I also tried using char-arrays instead of pointers but its the same result. Maybe I have to use other functions?

Update 1:

Somehow the Output is strange, seems like it's never going in the if-block in the add() function. Output with 2 names in the .txt-file: pt? pt? Peter Parker Klark Kent

Update 2:

Changed the Return type of the add() function, now it works :)

cfile-iolinked-list

Answers

answered 5 days ago Chris Turner #1

strcat is definitely not the right thing to use. As your compiler should be telling, you're firstly passing in the wrong type of variable in to it. It takes 2 strings and character is just a char.

Strings in C are NUL terminated and having just allocated memory for anme and fnme, neither of them will be initialised so won't contain that NUL termination, so you'll be experiencing undefined behaviour.

Instead, just treat them like an array and store the characters as you read them in and then remember to NUL terminate it when you've finished reading in all the characters.

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

This method also allows you to check that count doesn't exceed the size you've allocated, which in this case is 99 as the last space is needed for the NUL character.

answered 5 days ago colin #2

Modify your code a little bit, and it should work. You can not use strcat in that way, since the second parameter of strcat accepts const char *, and you have char, so your code won't compile.

Also something noteworthy here is: I assume the function add will make a deepcopy for both fnme and anme, otherwise, you cannot simply free them here.

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);

}

answered 5 days ago colin #3

You have some errors in add() function. This is the full solution. BTW, since this is a follow up question, you'd better ask it in a new post rather than updating the original one.

#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;
}

comments powered by Disqus