0
FILE *fp;
char *f_array[256];
int f_length;
int *a = 0;

fp = fopen("test.txt", "r");
fseek(fp, 0, SEEK_END);
f_length = ftell(fp);
printf("%d\n\n", f_length);
int n = 1, i = 0;
while (n > 0)
{
    n = fscanf(fp, "%s", f_array[i]);
    i++;
}

I am trying to copy the contents of a .txt file into a char* array. Much like what would happen with InternetReadFile and lpbuffer. However, I cannot seem to get this right. I need my array to be filled with the contents of the .txt file character by character. Any suggestions? I need the array to be single-dimensional

4
  • Don't use fscanf for this, use fread. Commented Feb 14, 2018 at 2:13
  • Possible duplicate of Reading the whole text file into a char array in C Commented Feb 14, 2018 at 2:13
  • @I'L'I I checked out the linked post and am now receiving the "entire read fails" error Commented Feb 14, 2018 at 2:19
  • No worries, thought it might be of use — glad you got it sorted. Commented Feb 14, 2018 at 2:40

2 Answers 2

1

The issue is mainly to do with your data types. You want to store the file in memory. That would be a character (byte) array, but you have created an "array of pointers":

char *f_array[256];

When you probably wanted just:

char f_array[256];

Then, to do as you asked and read character by character into that array, use fgetc. Note that fgetc will be far less efficient that just reading the whole file in a single function call with fread. The kernel:

while ( EOF != (c = fgetc( fp )) && ++i < MAX_LEN )
    f_array[ i ] = c;

In context of a working example:

#include <stdio.h>
int main ( ) {
    const size_t MAX_LEN = 255;
    FILE * fp;
    char f_array[ MAX_LEN +1];
    int c;
    size_t i = -1;
    f_array[ MAX_LEN +1] = 0;

    fp = fopen("test.txt","r");

    if ( NULL == fp )
        perror("Error opening file");
    else {
        while ( EOF != (c = fgetc( fp )) && ++i < MAX_LEN )
            f_array[ i ] = c;

        fclose (fp);
    }
    f_array[ i ] = 0;
    printf("%zu bytes read\n\n", i);
    printf("Content read:\n%s\n", f_array);

    return 0;
}
Sign up to request clarification or add additional context in comments.

8 Comments

When explaining, please don't call it "array of arrays", that's not an array of arrays, it's an array of pointers. That is huge difference. Calling it array of arrays is misleading. And the cast (char) c is unnecessary.
@Pablo "array of arrays": fair. I wasn't focused on that particular detail, but the detail that his datatype wasn't fit for purpose. Mea culpa. Meanwhile, while answering, you beat me to it, so I'm inclined to just delete my answer.
don't delete the answer, it's a good answer. Someone might find yours more understandable than mine. Just update the bit with the "array of arrays".
@Pablo (char) c not necessary: That would be stale thinking as I was typing that up. The compiler would throw a warning if not there. But the real issue is that int c should be char c. Fixed.
No no, c should definitely be int, otherwise you will get problems when comparing with EOF. And I don't get any a warning with char c = 10; although 10 is an integer. That's not a problem.
|
0

You are calculating the length of the file but you don't use this information in any way.

char *f_array[256];

This is an array of dimension 256 of pointers to char. f_array[i] is uninitialized and it's pointing into the digital nirvana, passing it to fscanf yields undefined behaviour. You would need to declare it as something like this:

char f_array[255][255];

But then you are limiting yourself to max 255 strings, you are not storing it into a single string. Also you are storing max. 255 words. Use fgets or fread to get the whole content at once.

char file[f_length + 1];

rewind(fp);

fread(file, f_length, 1, fp);

file[f_length] = 0; // terminate the string

printf("Whole file is: %s\n", file);

Here you are storing the whole file in an array of chars. Also after setting the file at the end, you'll need to rewind the file to the beginning, otherwise you are not reading anything.

7 Comments

This code is not reliable. fp = fopen("test.txt", "r"); opens the file in text mode. But ftell() on a stream in text mode does not return the number of bytes in the file, or even the number of bytes that can be read from the file. Per 7.21.9.4 The ftell function, paragraph 2 of the C standard:
(cont) "For a text stream, its file position indicator contains unspecified information, usable by the fseek function for returning the file position indicator for the stream to its position at the time of the ftell call; the difference between two such return values is not necessarily a meaningful measure of the number of characters written read" For example, on Windows file[f_length] = 0; // terminate the string will not properly terminate the string.
@AndrewHenle this is new to me, I've read the ftell man page on my system at work (debian 8) and the page does not mention this at all. I've been doing this on linux for years without a problem. In fact in Linux b is ignored (my man page even says all POSIX conforming systems) . To be portable, what would you suggest, fopen("test.txt", "rb");?
@Pablo It works on Linux because Linux is (mostly) POSIX-compliant, and POSIX defines ftell() to return a byte offset: "ftell() ... shall return the current value of the file-position indicator for the stream measured in bytes from the beginning of the file." But there's a portability problem with fseek() on a binary stream: "A binary stream need not meaningfully support fseek calls with a whence value of SEEK_END."
@Pablo (cont) Additionally: "Setting the file position indicator to end-of-file, as with fseek(file, 0, SEEK_END), has undefined behavior for a binary stream ..." So, there is no portable way that's strictly compliant with the C standard to get the size of a file other than to read it char-by-char and count them. There are some downright strange storage systems out there...
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.