1

Summary

I am trying to create a program that converts the contents of a file into a string.

I fseek to the end of the file then ftell to find the length in order to use the length for fread.

Problem is, I have to fseek back to the start of the file in order to read from the beginning, or else it will read starting from the end of the file, which is obviously a problem.

Problem is, using rewind() returns an error for some reason.

Note that removing the rewind() line from my code allows it to run without errors, but (null) is printed because its reading from the end of the file. This is why I'm assuming rewind() is the problem.

Code

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

int main(void) {
    FILE* dictionary = fopen("test.txt", "r");
    fseek(dictionary, 0, SEEK_END);
    int len = ftell(dictionary);
    rewind(dictionary);

    char* txt;
    fread(txt, len+1, 1, dictionary);
    printf("%s", txt);
}

Error Message

shell returned 139
IrAM
  • 1,720
  • 5
  • 18
BrianZhang
  • 153
  • 1
  • 8
  • 5
    `txt` is not assigned any memory ... UB – Damien Dec 07 '20 at 15:02
  • 2
    `txt` points nowhere. What you see is a manifestation of _undefined behaviour_ (google that). – Jabberwocky Dec 07 '20 at 15:07
  • OT: always check if `fopen` fails. – Jabberwocky Dec 07 '20 at 15:16
  • And `fread()`. Not checking the return value from `fread()` is why you thought your code worked without rewind. Your code didn't work - the `fseek()` call left the file pointer at the end of the file, so the `fread()` call **didn't read anything** and never had to try accessing non-existent memory. – Andrew Henle Dec 07 '20 at 15:24

2 Answers2

3

Memory is needed in txt:

Change:

 char* txt;
 fread(txt, len+1, 1, dictionary);
 printf("%s", txt);

To

char* txt = malloc(len+1);
if(txt)
{
    fread(txt, len, 1, dictionary);
    txt[len] = 0;//add terminating NULL
    printf("%s", txt);
    free(txt);
}
ryyker
  • 22,849
  • 3
  • 43
  • 87
1

The root of the problem is that fread() tries to write the data from the file into txt, but txt doesn't point to allocated memory. Here's one way to fix it:

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

int main(void) {
    FILE* dictionary = fopen("test.txt", "r");
    fseek(dictionary, 0, SEEK_END);
    int len = ftell(dictionary);
    rewind(dictionary);

    char *txt = malloc(len);
    fread(txt, len, 1, dictionary);
    printf("%s", txt);
}

I think this worked when rewind() was removed because fread reached the end of file before writing to the invalid pointer in txt.

GandhiGandhi
  • 1,029
  • 6
  • 10