Home > Back-end >  How do I store a txt file into a char array?
How do I store a txt file into a char array?

Time:12-01

I'm looking to store a txt file with 52 characters that have no spaces into a char array. What I have below only outputs garbage. I would appreciate on some insight on how to solve this.

`

int main()
{
    fstream fin, fout;
    int maxSize = 9999; // Max length for text file.
    int sizeArray = 0; //Stores length of message.txt file.
    char storeCharacter[maxSize]; //Array that stores each individual character.
    
    
    fin.open("message.txt");
    if(fin.fail())
    {
        cout << "Input file failed to open (wrong file name/other error)" << endl;
        exit(0);
    }
    
    sizeArray = fileLength(fin, storeCharacter, maxSize); //Assigns size using fileLength function.
    cout << sizeArray << endl; 
    char txtCharacters[sizeArray];
    storeInArray(fin, txtCharacters, sizeArray);
    
    for(int i=0; i<=sizeArray; i  )
    {
        cout << txtCharacters[i];
    }
    
    fin.close();
    fout.close();

    return 0;
}

int fileLength(fstream& fin, char storeCharacter[], int length)
{
    char nextIn;
    int i = 0;
    fin >> nextIn;
    while(!fin.eof())
    {
        storeCharacter[i] = nextIn;
        i  ;
        fin >> nextIn;
    }
    
    return i; //returns the file size.
}

void storeInArray(fstream& fin, char arr[], int length)
{
    int i = 0;
    char nextIn;
    
    while(!fin.eof() && i!=length )
    {
        fin >> nextIn;
        arr[i] = nextIn;
        i  ;
    }
}


`

I tried to use a while and for loop to store the txt file characters into a char array. I was expecting it to work since I have done a similar thing with a txt file full of integers. Instead garbage gets outputted instead of the contents of the text file.

CodePudding user response:

first error here is that VLA is not a standard c feature. Do not use it

char txtCharacters[sizeArray];

also do not do

 while(!fin.eof() 

read Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?

next fileLength reads to the end of the file but you do not rewind the file after that. This function loads the file into an array anyway so why the read it (or try to) into a second array.

also

for(int i=0; i<=sizeArray; i  )

you mean

for(int i=0; i<sizeArray; i  )

way simpler is to read into std::vector, no need to calculate initial size. Just push_back each char

CodePudding user response:

From the world of old-school, we use fopen, fread and fclose:

#include <stdio.h>

int read_file(const char* path, char* data, int max_length)
{
    FILE *fp = fopen(path, "rb");
    if (!fp) return 0;
    int n = fread(data, 1, max_length, fp);
    fclose(fp);
    return n;
}

int main()
{
    char data[1024] = { };
    int l = read_file("message.txt", data, 1024);
    printf("length = %d\n", l);
    printf("text = %s\n", data);
    return 0;
}

For the following message.txt (the alphabet twice with a trailing new line character, i.e. 26 26 1 = 53 bytes)

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

I get the following output:

length = 53
text = ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

Somethings you'll note:

  • The read_file is implemented as a refactor of fopen, fread and fclose
    • We open the file in read-only binary mode
    • If the file didn't exist or there was a reason why we couldn't open, we early exit with 0 bytes read
    • We read up to a maximum of max_length and return the actual bytes read
    • We make sure we close the file before exiting
  • In the main I declare data as 1024 bytes, i.e. 1K which is more than enough
    • I ensure that the data has been zero-initialized, so, if nothing populates it, it will contain NUL characters
  • I use printf statements to display what has been read
  • Related