Search code examples
arrayscpointerscharfread

Troubles with pointers when reading from a txt file


Im trying to print out the strings from a txt file in order.

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

int main(int argc, char *argv[])
{
    // Check for command line args
    if (argc != 2)
    {
        printf("Usage: ./read infile\n");
        return 1;
    }

    // Create buffer to read into
    char buffer[7];
    // Create array to store plate numbers
    char *plates[8];

    FILE *infile = fopen(argv[1], "r");
    int idx = 0;


    while (fread(buffer, 1, 7, infile) == 7)
    {
        char buffer2[7];
        // Replace '\n' with '\0'
        buffer[6] = '\0';
        strcpy(buffer2, buffer);

        // Save plate number in array

        plates[idx] = buffer2;
        idx++;
    }

    for (int i = 0; i < 8; i++)
    {
        printf("%s\n", plates[i]);
    }


}

The pasted code just writes one and the same string over and over again, and I cant for the life of me figure out what Im doing wrong. When I debug the "while" method, I see that the buffer updates keep overwriting every entry to the plates array.


Solution

  • "Im trying to print out the strings from a txt file in order."

    As noted in comments fread() as used in your implementation is not the best way to read lines in a text file.

    Answering these 2 questions (at minimum the first one) will provide important values to help in declaring and initializing the right sized (and shaped) buffers for reading lines from a file...

    • What is the longest line in the file?
    • How many lines are in the file? (may be optional if not storing all lines)

    The following example(s) can be accomplished knowing only the answer to the first question, but knowing the answer to the second would be useful if it was necessary for example to store all of the lines into an array of strings. (This is out of scope here as you did not list that as a requirement for your code)

    Unless you are comfortable with making an assumption on the maximum line length, i.e. hard-coded...

    char line[guessed_max_line_length] = {0};  
    

    ...a run-time assessment to determine the length of the longest line in the file is necessary to size the buffer such that it can safely contain lines that will later be read from file. Once this assessment is done, use the length of the longest line to create a line buffer during run-time. (dynamically allocate memory):

    char *line = malloc(max_length + 1);
    memset(line, 0, max_length + 1);
    

    Using these methods, (and providing the implementation linked above) your code can be simplified to the following adaptation....

    //prototype to get max line length in file
    size_t longestLine(FILE *fi);
    
    int main(int argc, char *argv[])
    {
        // Check for command line args
        if (argc != 2)
        {
            printf("Usage: ./read infile\n");
            return 1;
        }
    
        FILE *infile = fopen(argv[1], "r");
        if(infile)
        {
            size_t max_length = longestLine(infile); //see linked implemenation from above
            rewind(infile);//suggest adding this line to longestLine() implementation.
            char *line = malloc(max_length + 1);
            if(line)
            {
                memset(line, 0, max_length + 1);
                while(fgets(line, max_length, infile))
                {
                    fputs(line, stdout);
                    //or alternatively
                    //printf("%s", line);
                }
                free(line);
            }
            fclose(infile);
        }
        return 0;
    }