character by character reading from a file in C

Welcome to Programming Tutorial official website. Today - we are going to cover how to solve / find the solution of this error character by character reading from a file in C on this date .

How to read text from a file into a dynamic array of characters? I found a way to count the number of characters in a file and create a dynamic array, but I can’t figure out how to assign characters to the elements of the array?

FILE *text;
char* Str;
int count = 0;
char c;
text = fopen("text.txt", "r");
while(c = (fgetc(text))!= EOF)
{
  count ++;
}
Str = (char*)malloc(count * sizeof(char));

fclose(text);

Answer

To just do what you asked for, you would have to read the whole file again:

...
// go back to the beginning
fseek(text, 0L, SEEK_SET);
// read
ssize_t readsize = fread(Str, sizeof(char), count, text);
if(readsize != count) {
  printf("woops - something bad happenedn");
}

// do stuff with it
// ...

fclose(text);

But your string is not null terminated this way. That will get you in some trouble if you try to use some common string functions like strlen.

To properly null terminate your string you would have to allocate space for one additional character and set that last one to ”:

...
// allocate count + 1 (for the null terminator) 
Str = (char*)malloc((count + 1) * sizeof(char));    

// go back to the beginning
fseek(text, 0L, SEEK_SET);
// read
ssize_t readsize = fread(Str, sizeof(char), count, text);
if(readsize != count) {
  printf("woops - something bad happenedn");
}
// add null terminator
Str[count] = '';

// do stuff with it
// ...

fclose(text);

Now if you want know the number of characters in the file without counting them one by one, you could get that number in a more efficient way:

...
text = fopen("text.txt", "r");

// seek to the end of the file
fseek(text, 0L, SEEK_END);
// get your current position in that file
count = ftell(text)

// allocate count + 1 (for the null terminator) 
Str = (char*)malloc((count + 1) * sizeof(char));    
...

Now bring this in a more structured form:

// open file
FILE *text = fopen("text.txt", "r");

// seek to the end of the file
fseek(text, 0L, SEEK_END);
// get your current position in that file
ssize_t count = ftell(text)

// allocate count + 1 (for the null terminator) 
char* Str = (char*)malloc((count + 1) * sizeof(char));    

// go back to the beginning
fseek(text, 0L, SEEK_SET);
// read
ssize_t readsize = fread(Str, sizeof(char), count, text);
if(readsize != count) {
  printf("woops - something bad happenedn");
}

fclose(text);

// add null terminator
Str[count] = '';

// do stuff with it
// ...

Edit:

As Andrew Henle pointed out not every FILE stream is seekable and you can’t even rely on being able to read the file again (or that the file has the same length/content when reading it again). Even though this is the accepted answer, if you don’t know in advance what kind of file stream you’re dealing with, his solution is definitely the way to go.