Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading each line of file into array

I'm reading a file and want to put each line into a string in an array. The length of the file is arbitrary and the length of each line is arbitrary (albeit assume it will be less than 100 characters).

Here's what I've got and it's not compiling. Essentially this is an array to an array of characters, right? So shouldn't it be char** words = (**char)malloc(sizeof(*char));?

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

int main(){


 int BUFSIZE = 32767;//max number of lines to read
 char** words = (**char)malloc(sizeof(*char));//gives error: expected expression before 'char'
 FILE *fp = fopen("coll.txt", "r");
 if (fp == 0){
        fprintf(stderr, "Error opening file");
        exit(1);
 }

int i = 0;
words[i] = malloc(BUFSIZE);
while(fscanf(fp, "%100s", words[i]) == 1)//no line will be longer than 100
{
        i++;
        words[i] = realloc(words, sizeof(char*)*i);
 }

 int j;
 for(j = 0; j < i; j++)
    printf("%s\n", words);

 return 0;
}

Note: I've read "Reading from a file and storing in array" but it doesn't answer my question.

like image 289
Celeritas Avatar asked Oct 04 '13 04:10

Celeritas


People also ask

How do I read a file line by line?

Method 1: Read a File Line by Line using readlines() readlines() is used to read all the lines at a single go and then return them as each line a string element in a list. This function can be used for small files, as it reads the whole file content to the memory, then split it into separate lines.

How do you read data in an array?

The general form for reading the data from an array is :Name of array [array index] ; Ex: marks[3] ; It can display the marks of 4th subject stored in the position 3.

How do you store files in an array?

In Java, we can store the content of the file into an array either by reading the file using a scanner or bufferedReader or FileReader or by using readAllLines method.


1 Answers

There are a few issues with your program. The realloc() statement is not used correctly. I also prefer fgets() for getting a line. Here is my solution. This also uses realloc() to increase the allocation of the buffer lines so that you neither have to know the number of lines in advance nor do you have to read the file in two passes (faster that way). This is a common technique to use when you don't know how much memory you'll have to allocate in advance.

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

int main(void)

    {
    int lines_allocated = 128;
    int max_line_len = 100;

    /* Allocate lines of text */
    char **words = (char **)malloc(sizeof(char*)*lines_allocated);
    if (words==NULL)
        {
        fprintf(stderr,"Out of memory (1).\n");
        exit(1);
        }

    FILE *fp = fopen("coll.txt", "r");
    if (fp == NULL)
        {
        fprintf(stderr,"Error opening file.\n");
        exit(2);
        }

    int i;
    for (i=0;1;i++)
        {
        int j;

        /* Have we gone over our line allocation? */
        if (i >= lines_allocated)
            {
            int new_size;

            /* Double our allocation and re-allocate */
            new_size = lines_allocated*2;
            words = (char **)realloc(words,sizeof(char*)*new_size);
            if (words==NULL)
                {
                fprintf(stderr,"Out of memory.\n");
                exit(3);
                }
            lines_allocated = new_size;
            }
        /* Allocate space for the next line */
        words[i] = malloc(max_line_len);
        if (words[i]==NULL)
            {
            fprintf(stderr,"Out of memory (3).\n");
            exit(4);
            }
        if (fgets(words[i],max_line_len-1,fp)==NULL)
            break;

        /* Get rid of CR or LF at end of line */
        for (j=strlen(words[i])-1;j>=0 && (words[i][j]=='\n' || words[i][j]=='\r');j--)
            ;
        words[i][j+1]='\0';
        }
    /* Close file */
    fclose(fp);

    int j;
    for(j = 0; j < i; j++)
        printf("%s\n", words[j]);

    /* Good practice to free memory */
    for (;i>=0;i--)
        free(words[i]);
    free(words);
    return 0;
    }
like image 183
willus Avatar answered Oct 06 '22 00:10

willus