1

Im attempting to read a file with 10 lines that looks like:

000000 52.3 65.2 98.7 96.3 100.0 25.0 95.6 98.7 82.5 63.1
111111 81.0 68.6 54.2 96.3 74.2 78.6 98.5 62.1 64.7 75.0
222222 52.6 63.5 25.4 42.6 32.0 22.1 52.3 96.6 98.5 63.2
333333 98.2 65.3 65.4 93.5 32.6 37.5 63.5 91.0 96.3 82.5
444444 96.3 85.2 74.1 36.9 25.8 14.7 12.3 13.4 63.5 98.4
555555 93.6 82.5 74.1 63.1 65.2 63.5 98.7 63.2 63.8 64.0
666666 95.2 61.5 97.8 52.3 63.3 33.3 44.4 55.5 66.6 77.7
777777 11.1 22.2 33.3 44.4 55.5 66.6 77.7 88.8 99.9 100.0
888888 12.3 23.4 34.5 45.6 56.7 67.8 78.9 89.1 91.1 98.1
999999 98.7 87.6 76.5 65.4 54.3 43.2 32.1 21.0 52.9 87.1

I need to read the file line by line into a string so currently i have:

#include<stdio.h>

int main()
{
    FILE *p;
    char *line[10], *buffer; //Array of strings and a buffer string
    int a;
    p = fopen("assign6.dat", "r+");
    for(a = 0; a < 10; a++) {
        fscanf(p, "%[^\n]", buffer); //Read until we reach a newline
        fgetc(p); //Read the newline
        line[a] = buffer;
        printf("%s\n", line[a]);
    }
    for(a = 0; a < 10; a++) {
        printf("%s\n", line[a]);
    }
    fclose(p);
    return 0;
}

So i declared an array of pointers to char to store all 10 lines of data. The first printf statement prints out the correct data. However the second printf statement inside the second for loop prints out the last line of the file over and over (10 times). So why are these printf statements printing our different things when they are the same thing.

JackV
  • 218
  • 2
  • 12

3 Answers3

4

Copying strings

You will need to change this:

line[a] = buffer;

to this:

strcpy(line[a], buffer);

and it will work. The reason is that line[a] and buffer are pointers, and by making those equal, you'll end up pointing to the same address in the memory.

What is strcpy?

Whis is this the case?

Allocating memory

You need to allocate memory for your strings but you haven't done so.

Judging from your file, changin this:

char *line[10], *buffer;

to this

char line[10][129], buffer[129];

is a quick solution. I'm allocating 129 characters, because the file's string have a maximum length of 6 and we need one more space for the null character. You can change that as you please. Otherwise, you might want to dynamically allocate memory.

How to dynamically allocate memory using malloc

Community
  • 1
  • 1
codingEnthusiast
  • 3,800
  • 2
  • 25
  • 37
  • may need allocation for `line[a]` too – Arun Apr 19 '15 at 20:26
  • Wouldnt the array need to be char line[10][128] instead of what you said because 7 isnt enough to read the whole line – JackV Apr 19 '15 at 20:41
  • If the maximum length of each line is going to be 128 characters, then allocate 129 (+1 for the null char). I'm sorry for using only 7, had something else on my mind. But generally it depends on your file. Thanks for your comment. – codingEnthusiast Apr 19 '15 at 20:45
1

Because buffer is a pointer to memory. The string that buffer points to is written over every time fscan() is run and line[a] all has the value of the buffer pointer so they all point to the same memory position. In that position only the last line is stored.

You need to store each line for instance by using

strcpy(line[a], buffer); // Instead of line[a] = buffer;
1

Two problems:

No memory allocated for buffer.

fscanf(p, "%[^\n]", buffer);

No memory allocated for line[a]

line[a] = buffer;

It may be convenient to use a pre-allocated buffer for reading from file and a string for further copying.

enum {MaxLineLength = 128};
char buffer[MaxLineLength];

string line[10];

Note that, for buffer the program cannot know the real length before actually reading, hence a upper limit on length is desired.

Arun
  • 19,750
  • 10
  • 51
  • 60