1

I'm trying to take in multiple inputs(strings,integers and doubles) and add them to a linked list i cant get fgets() function to work properly and there's no constructive error that would help me find a solution.

I ask the user to enter each detail separately then try add it to a Linked List. I realised that scanf doesn't work so tried to use fgets and it doesn't seem to work either.

void add(){ 
  struct LinearNode *aNode;
    struct book *anElement;

    char *idB,*nameB,*authorB;
    int yearB,loanedTimesB;
    double valueB;

  anElement = (struct book *)malloc(sizeof(struct book));
  if (anElement == NULL)
            printf("Error - no space for the new element\n");
        else{
      printf("Please enter the book ID.\n");
      fgets(anElement->id,sizeof anElement->id,stdin);
      //strcpy(anElement->id, idB);
      printf("Please enter the name of the book.\n");
      scanf("%s", anElement->name);
      printf("Please enter the name of the book author.\n");
      scanf("%s", anElement->author);
      printf("Please enter the year of publication.\n");
      scanf("%d", &anElement->year);
      printf("Please enter the initial book value.\n");
      scanf("%lf", &anElement->value);
      anElement->loanedTimes = 0;
      anElement->loaned = false;

      aNode = (struct LinearNode *)malloc(sizeof(struct LinearNode));
      if (aNode == NULL)
                printf("Error - no space for the new node\n");
          else { // add data part to the node
                aNode->element = anElement;
                aNode->next = NULL;
                //add node to end of the list
                if (isEmpty()) {
                   front = aNode;
                   last = aNode;
                }
                else {
                     last->next = aNode;
                     last = aNode;
                  } //end else
           }
    }
}

here is the full code

#define _CRT_SECURE_NO_WARNINGS
#define bool int
#define false 0
#define true (!false)

//Libraries
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
//Preprocessor Variable
#define SIZE 10

struct book{
  char *id,*name,*author;
  int year,loanedTimes;
  bool loaned;
  double value;
};

struct LinearNode {
    struct book *element;
    struct LinearNode *next;
};

struct LinearNode *front = NULL;
struct LinearNode *last = NULL;

void check(),menu(),add(),borrow(),returnBook(),deleteBook(),viewAll(),viewOne(),viewPopNo(),viewValue();
bool isEmpty();
int main(int argc, char *argv[]) {
    check();
  menu();
    return 0;
}

void check(){
  if( access( "book.dat", F_OK ) != -1 ) {
    printf("The system has been populated with books from the data file.\n");
} else {
    printf("Database of books doesn't exist.\nPlease populate it using the first function from the menu.\n");
}
}

void menu(){
    int x = 0;
    do{
    printf("1. Add a new book to the library \n");
    printf("2. Allow customer to take out a book \n");
    printf("3. Allow Customer to return a book \n");
    printf("4. Delete an old book from stock \n");
    printf("5. View all books \n");
    printf("6. View a specific book \n");
    printf("7. View details of most popular and least popular books \n");
    printf("8. Check value of the books \n");
    printf("9. Exit the system \n");
  scanf("%d",&x);
  getchar();
  if (x==1)
  add();
    }while(x!=9);
}
void add(){ 
  struct LinearNode *aNode;
    struct book *anElement;

    char *idB,*nameB,*authorB;
    int yearB,loanedTimesB;
    double valueB;

  anElement = (struct book *)malloc(sizeof(struct book));
  if (anElement == NULL)
            printf("Error - no space for the new element\n");
        else{
      printf("Please enter the book ID.\n");
      fgets(anElement->id,sizeof anElement->id,stdin);
      //strcpy(anElement->id, idB);
      printf("Please enter the name of the book.\n");
      scanf("%s", anElement->name);
      printf("Please enter the name of the book author.\n");
      scanf("%s", anElement->author);
      printf("Please enter the year of publication.\n");
      scanf("%d", &anElement->year);
      printf("Please enter the initial book value.\n");
      scanf("%lf", &anElement->value);
      anElement->loanedTimes = 0;
      anElement->loaned = false;

      aNode = (struct LinearNode *)malloc(sizeof(struct LinearNode));
      if (aNode == NULL)
                printf("Error - no space for the new node\n");
          else { // add data part to the node
                aNode->element = anElement;
                aNode->next = NULL;
                //add node to end of the list
                if (isEmpty()) {
                   front = aNode;
                   last = aNode;
                }
                else {
                     last->next = aNode;
                     last = aNode;
                  } //end else
           }
    }
}
bool isEmpty() {
    if (front == NULL)
        return true;
    else
        return false;
}




9
  • 4
    Do not mix fgets with scanf. It will only give you troubles. Commented Mar 25, 2019 at 15:02
  • do you have any recommendations to take in strings and add them to a linked list? Commented Mar 25, 2019 at 15:03
  • You could use getline (or fgets) and sscanf to scan from the data you get from the first call. Commented Mar 25, 2019 at 15:05
  • 1
    What's struct book? Or more specifically what´s its field member .id (sizeof anElement->id may be wrong)? Commented Mar 25, 2019 at 15:06
  • scanf is not made for interactive user input. But you can use it for simple test programs. You can use scanf("%s", anElement->id) instead of fgets, as mentioned before, mixing fgets and scanf on the same input file only causes trouble.. Also show struct book, depending on how you've defined it, there may be other problems. Commented Mar 25, 2019 at 15:07

1 Answer 1

1

sizeof anElement->id yields the size of a pointer!

fgets(anElement->id,sizeof anElement->id,stdin);
//                  ^^^^^^^^^^^^^^^^^^^^
//                  size of a pointer
//                  probably 4 or 8

You should allocate enough space and read that many bytes

anElement->id = malloc(100);      // error checking omitted for brevity
fgets(anElement->id, 100, stdin); // error checking omitted for brevity
// use anElement->id
free(anElement->id);

Don't forget to free() the memory when you no longer need it.

Sign up to request clarification or add additional context in comments.

3 Comments

Does the free(anElement->id); clear then information saved in the linked list? Because i still need it there.
After freeing it, you cannot access it anymore. I didn't take into consideration you are using a linked list. With a linked list you need to defer the free until you no longer need any of the list (probably the end of program). Some programmers simply don't even think about the resource usage in similar cases and just let the Operating System deal with that when the program terminates.
Maybe better for you to follow @Jabberwocky's suggestion and use arrays rather than pointers in your struct.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.