Solved

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

Posted on 2007-03-21
8
3,805 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
 
LVL 1

Author Comment

by:TristinColby
ID: 18765932
can anyone explain ozo's code?   Specifically "lines = (char **)realloc(lines,sizeof(char *)*++line))"  
0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
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

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
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 and use structures in the C programming language.
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.

759 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

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now