views:

365

answers:

4

Hello,

I am trying to write some code that will open a file, read its content line by line and store each of these lines into an array.

First I open the file and count the number of lines, each of the lines is of a fixed length so I simply do this :

    char buf2[LINE_LENGTH];
    int in2 = open("toSend2", O_RDONLY);
    int number_of_lines = 0;

    for (;;)
 {
  char* p2 = buf2;
  int count = read (in2, p2, LINE_LENGTH);
  if (count < 0)
  {
    printf("ERROR");
    break;
  }
  if (count == 0) break; 

  number_of_lines++;

  printf("count: %d \n",count);
  printf("File 2 line : %s", p2);
  printf("\n");

 }
 close (in2);

So far, this works well, number_of_lines is indeed the number of lines in the file "toSend2" and each of my printf are the lines contained in that file.

Now with the number of lines, I create an array of strings and then I basically go through the whole file again but this time, I would like to store each of the lines in the array (there's probably a better way to find out the number of lines in a file, but everything that I tried has failed !)

    char * array[number_of_lines];
    int b=0;
    int in3=0;
    in3 = open("toSend2", O_RDONLY);
    for (;;)
 {
  char* p3 = buf3;
  int count = read (in2, p3, LINE_LENGTH);
  if (count < 0)
  {
    printf("ERRORRRRRR");
    break;
  }
  if (count == 0) break;


  array[b] = p3;
  b++;

  printf("count: %d \n",count);
  printf("FILE 2 LINEEEEEE : %s", p3);
  printf("\n");

 }  
 close(in3);

This, of course, doesn't work : each of my printf are the right line plus the last line of the file, for example, the first printf would be :

FILE 2 LINEEEEEEE : "1st line of the file" "last line of the file"

And after this for loop, when I trace the contents of my array, every item in it is simply the last line of the file. I think this is because I simply put the same pointer (pointing to a different line at that moment) in the array each time, but in the end it will point to the last line, therefore everything will be the last line.

How would I solve my problem ?

p.s.: I just started C, so please do not assume I know even basic things about it :(

+5  A: 
  • Use stdio, i.e. fopen(), fgets() and fclose() to do the I/O. You're using much lower-level Posix-style I/O, for no good reason.
  • You will need to dynamically allocate each new line in order to store it in the array. You can use strdup() to do this.
  • Remember that things can go wrong; files can fail to open, lines can fail to read in, and memory can fail to be allocated. Check for this, and act accordingly.
unwind
+1 for using existing C library functions. No reason to reinvent the wheel.
Tim
I agree, the 'f' functions are easier. but, using open/read/close (because of the standard line lengths) works well too.
KevinDTimm
Oh, I think I have to use the open read close because of the context of the assignment :(strdup() fixed my problem main problem, so thank you very much !
JoOb
how can you select this as the correct answer when it fails the (undisclosed) tenets of the assignment?
KevinDTimm
Well, strdup() solved my main problem and Useless' answer helped me find a better way of calculating the number of lines and, as an unexpected bonus, made me realize the cause behind my other problem
JoOb
A: 

why not use fopen, then just use fgets to get each line

Oh I forgot to mention its part of the assignment :(
JoOb
A: 

You haven't created an array of strings, you've created a pointer to an array of strings. you need to malloc your array in part2 to be count of lines * number of char's per line. then move your read lines into each subsequent position of array.

[edit]
one more thing.....
your strings are X length. 'C' strings aren't X length, they're X+1 length :)
[/edit]

KevinDTimm
Indeed, thank you and, about the strings, that explains those weird characters at the end of the lines but they're not a problem :)
JoOb
oh, but yes they are! as you will soon see.
KevinDTimm
A: 

You can use stat to get the file size. Then number_of_lines = stat.st_size/LINE_LENGTH

If you don't need your character strings nul-terminated, you can read the whole file into a single buffer. Set up the array of pointers if you really want them, or just use &buf[n * LINE_LENGTH] to get the start of line n.

To print a non-nul terminated string of known length, you can use:

printf("line %d = '%.*s'\n", n, LINE_LENGTH, &buf[n * LINE_LENGTH]);

Let me know in a comment if you want to see actual code.

Useless
Indeed, well played, thank you very much, the modification I made also helped me find the error which was causing the 2 lines instead of just one error!
JoOb
No problem, nul-terminated strings can take some getting used to.
Useless