Solved

How to Read txt file line by line and store into array. # of lines is unknown.

Posted on 2007-03-21
8
3,809 Views
Last Modified: 2008-10-26
I'm trying to read a text file line by line and store it into an array. I know that the Max number of characters per line will be 8 but I do not know how many lines there will be.  Is there a way to count the lines. I am unclear of how to store the strings and allocate the memory. I'm a perl programmer moving to C so I'm not completely programming ignorant but a brief explanation of "why"  is apprecated. here is how it would work in perl.  

my $file = @ARGV;
my @lines;
open(FH,"<$file");
while(<FH>) {
  push($_, @lines);
}
# Do something with data.

Here is what I have written so far in C

int main(int argc, char *argv[]) {
      
      if(argc != 2)
            Usage();
          else
            fp = fopen(argv[1],"r");
      if(fp == NULL) {
            perror(argv[1]);
            exit(EXIT_FAILURE);
      }
      else
            puts("Open successful. Reading contents.");

     /* Read each line and push into array for use later until at EOF.
      fclose(fp);
return 0;

}
0
Comment
Question by:TristinColby
8 Comments
 
LVL 24

Expert Comment

by:fridom
ID: 18765574
At least three way seem to be doable
1) use  resizable field and start with some initial size, resize
as needed
2) Open the file first and just count the lines
   after that you can allocate space for as many rows as you like
3) Use some linked list implementation which just grows as needed
see e.g glib:
http://developer.gnome.org/doc/API/2.0/glib/glib-Strings.html
or
http://developer.gnome.org/doc/API/2.0/glib/glib-Singly-Linked-Lists.html

Regards
Friedrich
0
 
LVL 84

Accepted Solution

by:
ozo earned 500 total points
ID: 18765692
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
  char **lines=0;
 int line=0;
char buffer[10];
 while( fgets(buffer,10,fp) && (lines = (char **)realloc(lines,sizeof(char *)*++line)) ){
        lines[line-1] = strdup(buffer);
 }
0
 
LVL 1

Author Comment

by:TristinColby
ID: 18765761
fridom: I should have specified. I need it to be portable.


ozo.  can you explain that a little bit.  
0
Efficient way to get backups off site to Azure

This user guide provides instructions on how to deploy and configure both a StoneFly Scale Out NAS Enterprise Cloud Drive virtual machine and Veeam Cloud Connect in the Microsoft Azure Cloud.

 
LVL 1

Author Comment

by:TristinColby
ID: 18765932
can anyone explain ozo's code?   Specifically "lines = (char **)realloc(lines,sizeof(char *)*++line))"  
0
 
LVL 1

Author Comment

by:TristinColby
ID: 18766051
also, can someone explain why he use a pointer to a pointer?  Is there any other way to write it?
0
 
LVL 84

Expert Comment

by:ozo
ID: 18766109
a string is a pointer to char
lines is a pointer to a list of strings
if lines is a pointer to (line) strings
lines = (char **)realloc(lines,sizeof(char *)*++line))
makes lines a pointer to a list of (line+1) strings
0
 
LVL 16

Expert Comment

by:AlexNek
ID: 18767112
I think this code is too compicated for beginner, I can't understood it immediatly too.
In C++ you can do it a little bit easy as you already have dynamic arrays implementation. In C you must realize it yourself. For unknown item count I would prefere to use linked list but if you need the array then you must to grow this array yourself.
For an dynamic array definition we can use a pointer to the item and allocate space as we need.
int* myarray = NULL;
myarray = malloc(10);
...
free(myarray);
Here is only 10 items reserved, when we need more that 10 we can add more memory.
with realloc
myarray = malloc(myarray,20);
http://www.opengroup.org/onlinepubs/007908799/xsh/realloc.html

We can realloc space every time when we needed but It is time consuming so it is recommended to add a chunk every time.

As we need to store the string as an array item then we need to use 2-dimentional array of chars. Other solution is to use one dimentional array as you have only 8 chars. It is not prefereables way but it is a way. In this this way you need to allocate 9 symbols /one for trailing 0/ for each item and access to the i-item via i*9 index.

When you use 2 dimentional array we can allocate for each string as many space as it need or always 9 char.
I try to write a pseudo code that you can understod the steps
Y = ... 10  /*100*/
X = ... 10  /*100*/
arraySize = X
allocate array for arraySize items
iItemCount = 0
i = 0;
while not EOF
{
 read the line
 itemCount++
 if (ItemCount > X)
 {
    arraySize = X + Y
    realloc array for arraySize
 }
 allocMemory for readed string
 copy string to allocated memory
 i -  array item  = allocated memory with copied string
 i++;
}

It is not optimized code but you can understood it, I hope.
0
 
LVL 1

Author Comment

by:TristinColby
ID: 18767115
:) I understand now. Thank you for your help.
0

Featured Post

Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.

785 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question