0

I have a txt file that looks like this: (str)name (str)last_name (int)weight (int)height and I'm supposed to save it in a linked list. Everything seems to work, up until I print the list and it's all empty or 0 values. I did something very similiar that used a scanf() function and worked, this is why I think the problem might be related to fscanf() function instead.

Here's my code:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define ERR -1
#define OK 0
#define MAX 50

struct profile {
    char name[MAX];
    char lname[MAX];
    int weight;
    int height;
    struct profile* next;
};

void print_profiles(struct profile** head) {
    struct profile* curr = *head;
    while (curr != NULL) {
        printf("%s %s\t%d %d\n", curr->name, curr->lname, curr->weight, curr->height);
        curr = curr->next;
    }
    putchar('\n');
}

int readSize(FILE *fp) {
    int lines = 0;
    for (char c=getc(fp); c!=EOF; c=getc(fp))
        if (c == '\n') lines++;
    return lines;   
}

int readFile(char *file, struct profile** head) {
    FILE *fp = fopen(file, "r");
    if (fp == NULL) return ERR;
    int lines = readSize(fp);
    struct profile *curr, *prev;
    curr = prev = NULL;
    
    for (int i=0; i<lines; i++) {
        curr = malloc(sizeof(struct profile));
        fscanf(fp, "%s%s%d%d", curr->name, curr->lname, &curr->weight, &curr->height);
        curr->next = NULL;
        if (i == 0) *head = curr;
        else prev->next = curr;
        prev = curr;
    }
    fclose(fp);
    return OK;
}

void freeNode(struct profile** head) {
    struct profile* curr = *head;
    while (curr != NULL) {
        struct profile* next = curr->next;
        free(curr);
        curr = next;
    }
    head = NULL;
}

int main() {
    struct profile* head = NULL;
    readFile("profiles.txt", &head);
    print_profiles(&head);

    freeNode(&head);
    return 0;
}
Angelo
  • 57
  • 8
  • 4
    Why are you ignoring the return value of `fscanf`? – Oka May 31 '23 at 10:00
  • @Oka I get what you say about checking the return value. But I don't have clear how should I use that so as to make the function work properly. – Angelo May 31 '23 at 10:34
  • 1
    What is `struct profile` declared as? Where is the `main()` function? I can't compile your code. Kindly provide a minimal reproducible example. As of `fscanf()`, see it's man page. – Harith May 31 '23 at 11:12
  • 2
    Why put `\n` in `fscanf` format strings? If you need to read lines, read lines with `fgets`. – n. m. could be an AI May 31 '23 at 11:32
  • 2
    Possible duplicate: [Why does scanf ask twice for input when there's a newline at the end of the format string?](https://stackoverflow.com/q/15740024/10871073) TL;DR; - try your code without the `\n` in the `fscanf` format string. – Adrian Mole May 31 '23 at 11:34
  • 2
    You need to use a return value to *verify* that the function does what you expect it to do. If it doesn't, you can get more information about what exactly went wrong from the return value and/or `errno`. – n. m. could be an AI May 31 '23 at 11:37
  • 1
    Also, reading a file to determine the number of entries is a waste of effort and generally a wrong thing to do. (And my guess is that the bug is actually there). Just read the records until the end. When you get to the end, stop. – n. m. could be an AI May 31 '23 at 11:44
  • 1
    I ran your program and, making reasonable assumptions for all the parts you left out, it worked perfectly. So the problem is probably in something you haven't shown us. Perhaps there's something wrong with your `print_profiles()` function — it's odd that you're calling `print_profiles(&head)`. (I would have expected `print_profiles(head)`.) – Steve Summit May 31 '23 at 11:49
  • 1
    Edit the question to provide a [mre]. – Eric Postpischil May 31 '23 at 12:09
  • 1
    I also note that if you fail to open the file you will get an empty list . You do not test the result of readFile – pm100 May 31 '23 at 12:46
  • 1
    After reading the file to determine the number of lines, you must rewind it to read it again. – stark May 31 '23 at 12:56
  • @pm100 I think that was the actual problem (Aside all the additional mistakes other made me notice), I had to use the rewind() function to re-read the file. Eventually I reworked the code without using the readSize() function, so as to not rewind the file. Thank you all! – Angelo May 31 '23 at 14:01

0 Answers0