2

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 :(

unwind
  • 391,730
  • 64
  • 469
  • 606
JoOb
  • 999
  • 2
  • 10
  • 10

4 Answers4

6
  • 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
  • 391,730
  • 64
  • 469
  • 606
  • +1 for using existing C library functions. No reason to reinvent the wheel. – Tim Dec 07 '09 at 16:21
  • I agree, the 'f' functions are easier. but, using open/read/close (because of the standard line lengths) works well too. – KevinDTimm Dec 07 '09 at 16:23
  • 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 Dec 07 '09 at 16:58
  • how can you select this as the correct answer when it fails the (undisclosed) tenets of the assignment? – KevinDTimm Dec 07 '09 at 17:08
  • 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 Dec 07 '09 at 18:51
1

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
  • 14,226
  • 3
  • 42
  • 60
0

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

user224003
  • 217
  • 1
  • 3
0

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
  • 64,155
  • 6
  • 88
  • 132
  • 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 Dec 07 '09 at 16:55
  • No problem, nul-terminated strings can take some getting used to. – Useless Dec 07 '09 at 18:12