1

I need, in ANSI C, to open a file, to read all of its lines into a dynamically allocated array of strings, and to print the first four lines. The file may be any size up to 2^31-1 bytes, while each line is at most 16 characters. I have the following, but it does not seem to work:

#define BUFSIZE 1024
char **arr_lines;
char buf_file[BUFSIZE], buf_line[16];
int num_lines = 0;
// open file
FILE *fp = fopen("file.txt", "r");
if (fp == NULL) {
    printf("Error opening file.\n");
    return -1;
}
// get number of lines; from http://stackoverflow.com/a/3837983
while (fgets(buf_file, BUFSIZE, fp))
    if (!(strlen(buf_file) == BUFSIZE-1 && buf_file[BUFSIZE-2] != '\n'))
        num_lines++;
// allocate memory
(*arr_lines) = (char*)malloc(num_lines * 16 * sizeof(char));
// read lines
rewind(fp);
num_lines = 0;
while (!feof(fp)) {
    fscanf(fp, "%s", buf_line);
    strcpy(arr_lines[num_lines], buf_line);
    num_lines++;
}
// print first four lines
printf("%s\n%s\n%s\n%s\n", arr_lines[0], arr_lines[1], arr_lines[2], arr_lines[3]);
// finish
fclose(fp);

I am having trouble on how to define arr_lines in order to write into this and to easily access its elements.

cm007
  • 1,352
  • 4
  • 20
  • 40
  • as a start, don't cast the result of malloc, see http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc. Secondly, post a complete minimal program that compiles that showcases the problem you're experiencing... – Fredrik Pihl Dec 21 '11 at 20:21

2 Answers2

3

There are a few issues in your code, but the main one is that in the malloc line you are de-referencing an uninitialized pointer. Also, unless your lines consist of a single word, you should use fgets() instead of fscanf(...%s...) because the latter returns after reading a word, not a line. Even if your lines are words, it's safer to use the same type of loop that you used to count lines anyway, otherwise you risk reading more lines than you allocated.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void){
#define LINESIZE 16
        char *arr_lines, *line;
        char buf_line[LINESIZE];
        int num_lines = 0;
        // open file
        FILE *fp = fopen("file.txt", "r");
        if (fp == NULL) {
                printf("Error opening file.\n");
                return -1;
        }
        // get number of lines; from http://stackoverflow.com/a/3837983
        while (fgets(buf_line, LINESIZE, fp))
                if (!(strlen(buf_line) == LINESIZE-1 && buf_line[LINESIZE-2] != '\n'))
                        num_lines++;
        // allocate memory
        arr_lines = (char*)malloc(num_lines * 16 * sizeof(char));
        // read lines
        rewind(fp);
        num_lines = 0;
        line=arr_lines;
        while (fgets(line, LINESIZE, fp))
                if (!(strlen(line) == LINESIZE-1 && line[LINESIZE-2] != '\n'))
                        line +=  LINESIZE;
        // print first four lines
        printf("%s\n%s\n%s\n%s\n", &arr_lines[16*0], &arr_lines[16*1], &arr_lines[16*2], &arr_lines[16*3]);
        // finish
        fclose(fp);
        return 0;
}

Hope this helps!

oriola
  • 31
  • 3
0

Change

(*arr_lines) = (char*)malloc(num_lines * 16 * sizeof(char));

to

arr_lines = malloc(num_lines * sizeof(char*));

then in the while loop below it, add

arr_lines[n] = malloc(16 * sizeof(char));
cubetwo1729
  • 1,438
  • 1
  • 11
  • 18