C - fgets() keeps skipping lines randomly when using the most basic case

96 views Asked by At

Before you remove it, I haven't seen this in any thread. I've seen people who wants to skips line but it fails, or it fails if there's a user input (which is due to weird input buffer thing in stdlibc... But not a case of fgets outright not working)

So, I need help, or for someone to tell me that the code works and that I need to reinstall everything on my PC or something.

At the start, I just wanted to quickly code a CSV -> 2D float array program in C. Just because it would be neater then manually inputing an array in main. So, Tried to look for already made code. Couldn't find it. Tried to make it myself from scratch. Shouldn't be too bad I thought. I already did things similar.

But nothing worked. Here's what I tried.

I originally tried to just fread the whole file into a single char * array. Didn't work either.

When I printed using %d, I got the whole array (except for newline character, ascii code 10, which didn't appear, even when reading in binary mode) I needed '\n' in the char array to split("\n") into different lines, but hey, I guess that's life)

To further add to my confusion, When I printed using %c or %s I only got the last line.

So Seeing that fread didn't work, I tried again, with fgets. Used lots of code until I simplified it to the most basic case and it's still not working.

It's a really weird issues. Either I'm missing something and I'm too tired to see it, or The C compiler got updated with a bug. After looking online and trying for hours, I didn't find a single post about this. It's weird, because fgets used to work on previous project. I tried restarting my PC and even compiling for linux and windows. Both doesn't work.

Here's a CSV file content.

2D_data.csv:

0.1,0.2,0.3
1.1,2.2,3.3

and here's the code.

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

void readCSV(char *filename, int lineSize)
{
    FILE *filePointer = fopen(filename, "rb");
    char line[lineSize];

    fgets(line, lineSize, filePointer);
    printf("%s|\n", line);
}

void main()
{
    printf("\n\n------------START OF PROGRAM------------\n\n");
    readCSV("2D_data.csv", 128);
}

and I get the output:

1.1,2.2,3.3|

when it should be the first line of the file aka

0.1,0.2,0.3|
2

There are 2 answers

3
Self learning student On

Huh, I seems it's because lineSize > 1 line... Still, how do you get a buffer that's big enough to hold any line and not overflow on newline?

Isn't fgets supposed to stop at newline character?


New comment: File created in linux, code compiled and ran in linux (Windows Ubuntu Subsystem). This is the previous code, I just didn't strip it down even further.

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

typedef struct
{
    int size;
    char *string;
} Line;

typedef struct
{
    Line *LineArray;
    int hor; // number of element horizontally (m)
    int ver; // number of element vertically;
    float **data_matrix;
} CSV;


CSV *readCSV(char *filename, int lineSize)
{

    CSV *csv = malloc(sizeof(CSV));
    csv->hor = csv->ver = 0;



    FILE *filePointer = fopen(filename, "rb");
    char line[lineSize];



    while (fgets(line, lineSize, filePointer) != NULL)
    {
        printf("%s",line);
    }
    return csv;
}

void main()
{
    printf("\n\n------------START OF PROGRAM------------\n\n");
    readCSV("data.csv",128);
}




data.csv (created in linux)

0.1,0.2,0.3,0.4,0.5
1.1,1.2,1.3,1.4,1.5
2.1,2.2,2.3,2.4,2.5
3.1,3.2,3.3
4.1,4.2

Output (compile and ran in linux)



------------START OF PROGRAM------------

0.1,0.2,0.3,0.4,0.5
1.1,1.2,1.3,1.4,1.5
2.1,2.2,2.3,2.4,2.5
3.1,3.2,3.3
4.1,4.2

But for file created in windows, it still can't work. Is there any solution other then "Windows Bad" ? I don't wanna have to use my linux subsystem everytime i do C coding.

New Edit: The code does work When ran in windows, if the csv was created in linux. wtf

Final Edit: It was due to a mac CSV encoding. See my other answer. Thanky you to everyone

3
Self learning student On

Solved: Solution: No problem with the code

It's because I wanted to be safe and created a CSV file from excel and saved as CSV. However, I missclicked the Mac CSV options rather then the windows CSV options.

Hence, When compiled on windows or Linux, the newline being a different character, doesn't get caught.

Moral of the story: Manually write your CSV with a texteditor next time.