-1

I'm trying to open a file, read the content line by line (excluding the empty lines) and store all these lines in an array, but seems I cannot come to the solution.

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

int main()
{

char buffer[500];
FILE *fp;
int lineno = 0;
int n;
char topics[lineno];

if ((fp = fopen("abc.txt","r")) == NULL){
printf("Could not open abc.txt\n");
return(1);
}

while (!feof(fp))
{
// read in the line and make sure it was successful
if (fgets(buffer,500,fp) != NULL){
    if(buffer[0] == '\n'){
    }
    else{
    strncpy(topics[lineno],buffer, 50);
    printf("%d: %s",lineno, topics[lineno]);
    lineno++;
    printf("%d: %s",lineno, buffer);
    }
}
}
return(0);
}

Considering "abc.txt" contains four lines (the third one is empty) like the following:
ab
2

4

I have been trying several ways but all I'm getting now is segmentation fault.

ekekekek
  • 5
  • 3
  • 2
    Please see [Why is “while ( !feof (file) )” always wrong?](http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong). Use `while(fgets(...) != NULL) {...}` – Weather Vane Apr 05 '16 at 16:29
  • you have detected an "empty" line by checking the first character as `newline`, but this `newline` is retained at the end of all lines read from a file that have a `newline` at their end in the file. The `newline` is always read (if present: the last line in the file might not have one, or the line might be longer than the buffer size you pass to `fgets`). – Weather Vane Apr 05 '16 at 16:43
  • while (fgets (str, 1160, fp) !=NULL) { size_t ln = strlen(str) - 1; temas[n] = str; if (str[ln] == '\n') { str[ln] = '\0'; } puts(str); } fclose(fp); return(0); } – ekekekek Apr 05 '16 at 16:44

2 Answers2

2

It is mostly because you are trying to store the read line in a 0 length array

int lineno = 0;
int n;
char topics[lineno];    //lineno is 0 here

There are more mistakes in your program after you correct the above mentioned one.

strncpy() needs a char* as its first parameter, and you are passing it a char.


If you want to store all the lines, in a manner such that array[0] is the first line, array[1] is the next one, then you would need an `array of char pointers.

Something like this

char* topics[100];
.
.
.
if (fgets(buffer,500,fp) != NULL){
    if(buffer[0] == '\n'){
    }
    else{
        topics[lineno] = malloc(128);
        strncpy(topics[lineno],buffer, 50);
        printf("%d: %s",lineno, topics[lineno]);
        lineno++;
        printf("%d: %s",lineno, buffer);
    }

NOTE: Use the standard definition of main()

int main(void) //if no command line arguments.

Bonus

Since you have accidentally stepped onto 0 length array, do read about it here.

Haris
  • 12,120
  • 6
  • 43
  • 70
  • It's more than that: `strncpy(topics[lineno],buffer, 50);` will only work if `topics` is an array of pointers, or 2-D. – Weather Vane Apr 05 '16 at 16:32
  • Thanks a lot, didn´t notice due to all the tweaking haha :) – ekekekek Apr 05 '16 at 16:32
  • @WeatherVane, Yes. Mentioned that. Now, I do not know whether the OP wants an `array of pointers to char` to store all the lines, or just and `array of char` to store each line once and move on. – Haris Apr 05 '16 at 16:36
  • I would guess an array of pointers, since OP already has the string in `buffer[]` and wants to skip empty lines. – Weather Vane Apr 05 '16 at 16:39
  • @WeatherVane, Yes, that makes sense. But beginners do all kinds of crazy unnecessary things to learn, anyways. I will add and example for the former. – Haris Apr 05 '16 at 16:40
  • @Haris The goal would be to make an array[0] ... array[n], where 0 is the first line and so on. So it would be an array of chars I think. – ekekekek Apr 05 '16 at 16:41
  • @ekekekek, You are mixing things. If `array[]` is an array of char, then it will hold one character only, not one line. If you want to store one lines then you need an array of pointers to char. – Haris Apr 05 '16 at 16:42
  • @Haris Woops, thought you could store more than one c har in an array. – ekekekek Apr 05 '16 at 16:47
  • You can, But you have to understand, In `array of char` you can store more then one char, but essentially one string (or one line in your case). You need something where you can store multiple strings. It would be Like a 2D thing. An array of strings. – Haris Apr 05 '16 at 16:49
  • Is that because of the need to have a pointer to the next string? – ekekekek Apr 05 '16 at 16:51
  • @ekekekek, The need to store many separate strings calls for pointers, not the other way around. And since using pointers in the above mentioned way, you can store and keep all the strings (lines) safely and access them later. – Haris Apr 05 '16 at 16:54
  • @Haris Got it. Thanks for the lesson. Really appreciated :) – ekekekek Apr 05 '16 at 16:57
  • @ekekekek, Happy to help. :) – Haris Apr 05 '16 at 16:58
1

This declaration of a variable length array

int lineno = 0;
char topics[lineno];

is invalid because the size of the array may not be equal to 0 and does not make sense in the context of the program/

You could dynamically allocate an array of pojnters to char that is of type char * and reallocate it each time when a new record is added.

For example

int lineno = 0;
int n;
char **topics = NULL;

//...

char **tmp = realloc( topics, ( lineno + 1 ) * sizeof( char * ) );
if ( tmp != NULL )
{
    topics = tmp;
    topics[lineno] = malloc( 50 * sizeof( char ) );
    //... copy the string and so on
    ++lineno;
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335