fread dropping carriage returns in C?
Asked Answered
M

2

6

I want to be able to read in a Windows text file, modify it in memory, and then overwrite the old file with the modified data. However, fread doesn't seem to store the carriage returns present in my Windows text file, which is throwing things off when I write over the old data. I can't find anyone else who seems to have had this issue.

Here is some example code that demonstrates the problem:

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

int main()
{
    FILE* textFile;
    long fileSize;
    char fileCharacterBuffer[100];

    int i;
    for(i = 0; i < 100; i++)
    {
        fileCharacterBuffer[i] = '\0';
    }

    textFile = fopen("./Test.txt", "r+");

    fseek(textFile, 0L, SEEK_END);
    fileSize = ftell(textFile);
    fseek(textFile, 0L, SEEK_SET);

    fread(fileCharacterBuffer, 1, fileSize, textFile);
}

The test file:

3
112
REd
110
green

#5/09/2014
5087 - 5/6/2014

Its hex dump, which shows its EOLs are \r\n:

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000  33 0D 0A 31 31 32 0D 0A 52 45 64 0D 0A 31 31 30  3..112..REd..110
00000010  0D 0A 67 72 65 65 6E 0D 0A 0D 0A 23 35 2F 30 39  ..green....#5/09
00000020  2F 32 30 31 34 0D 0A 35 30 38 37 20 2D 20 35 2F  /2014..5087 - 5/
00000030  36 2F 32 30 31 34 0D 0A                          6/2014..

After the fread, GDB prints fileCharacterBuffer as:

"3\n112\nREd\n110\ngreen\n\n#5/09/2014\n5087 - 5/6/2014\n", '\000' <repeats 51 times>

With only the \n's present. What?

Madelon answered 15/5, 2014 at 23:38 Comment(2)
And the platform is windows? (avoid it, or use "rb" )Mechanic
Definitely related although not a duplicate: #10632448Hussar
H
10

You are seeing the effects of "text mode" where line endings are being converted from Windows to Unix aka C newlines.

You need to open the file in binary mode which means adding a "b" to the fopen flags. It would look like textFile = fopen("./Test.txt", "rb+")

Also, I am not sure I understand why you get the length of the file before reading it.

Just read it. Look at the return value of fread to see how much you read. If you use a size of 1 the return value will be the number of bytes read.

Like this:

fileSize = fread(fileCharacterBuffer, 1, sizeof(fileCharacterBuffer), textFile);
Hussar answered 15/5, 2014 at 23:43 Comment(3)
br+ threw me an error, but rb+ that was suggested above worked. I checked the length of the file because I want to read the entire file into the buffer. Its size will change over time, but it will never exceed 100 characters.Madelon
@user3642854: sorry about the typo.Hussar
@user3642854: you don't have to know the size ahead of time. fread will read until it runs out of file to read. Up to the size that you gave it.Hussar
F
4

Open the file in binary format textFile = fopen("./Test.txt", "rb+");. Currently you are reading in text format and \r\n gets converted appropriately.

Fiesole answered 15/5, 2014 at 23:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.