tags:

views:

233

answers:

4

hi i have the following code below, where i try to get all the lines of a file into an array... for example if in file data.txt i have the following:

first line

second line

then in below code i want to get in data array the following: data[0] = "first line"; data[1] = "second line"

My first question: Currently I am getting "Segmentation fault"... Why?

Exactly i get the following output:

Number of lines is 7475613

Segmentation fault

My second question: Is there any better way to do what i am trying do?

Thanks!!!

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

int main(int argc, char* argv[])
{
 FILE *f = fopen("data.txt", "rb");
 fseek(f, 0, SEEK_END);
 long pos = ftell(f);
 fseek(f, 0, SEEK_SET);

 char *bytes = malloc(pos);
 fread(bytes, pos, 1, f);

 int i =0;
 int counter = 0;
 for(; i<pos; i++)
 {
  if(*(bytes+i)=='\n') counter++;
 }
 printf("\nNumber of lines is %d\n", counter);

 char* data[counter];
 int start=0, end=0;
 counter = 0;
 int length;

 for(i=0; i<pos; i++)
 {
  if(*(bytes+i)=='\n')
  {
   end = i;
   length =end-start;
   data[counter]=(char*)malloc(sizeof(char)*(length));
   strncpy(data[counter],
           bytes+start,
           length);
   counter = counter+1;
   start = end+1;
  }
 }

 free(bytes);
 return 0;
}

First line of the data.txt in this case is not '\n' it is: "23454555 6346346 3463463".

Thanks!

+3  A: 

First of all you need to check if the file got opened correctly or not:

FILE *f = fopen("data.txt", "rb");
if(!f)
{
    fprintf(stderr,"Error opening file");
    exit (1);
}

If there is error opening the file and you don't check it, you'll get a seg fault when you try to fseek on an invalid file pointer.

Apart from that I see no errors. Tried running the program, by printing the value of the data array at the end, it ran as expected.

codaddict
+4  A: 
  • You need to malloc 1 more char for data[counter] for the terminating NUL.
  • after strncpy, you need to terminate the destination string.


Edit after edit of original question

Number of lines is 7475613

Whooooooaaaaaa, that's a bit too much for your computer! If the size of a char * is 4, you want to reserve 29902452 bytes (30M) of automatic memory in the allocation of data.

You can allocate that memory dynamically instead:

/* char *data[counter]; */
char **data = malloc(counter * sizeof *data);

/* don't forget to free the memory when you no longer need it */


Edit: second question

My second question: Is there any better way to do what i am trying do?

Not really; you're doing it right. But maybe you can code without the need to have all that data in memory at the same time.
Read and deal with a single line at a time.

You also need to free(data[counter]); in a loop ... and free(data); before the "you're doing it right" above is correct :)

And you need to check if each of the several malloc() calls succeeded LOL

pmg
thanks it worked, cool... can you answer my second question?
asel
Yes, that's the solution. The data array need to be on the heap, not on the stack, since it's too big. Alternatively, you can also increase the stack size of your program. But pmg is solution is better.
Laurent Parenteau
And don't forgert to add "free(data);" after your loop!
Laurent Parenteau
A: 

One thing to note is that you're opening your file as binary - line termination disciplines may not work as you expect on your platform (UNIX is lf, Windows is cr-lf, some versions of MacOS are cr).

plinth
A: 

I am trying to figure out the same kind of thing but i am very unfamilar with strncpy... What exactly would he have to change on his code to terminate the string. And also, how did others like unicornaddict get it to work by directly running his program. It definitely did not work for me. Thanks in advance.