[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 3822
  • Last Modified:

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

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
TristinColby
Asked:
TristinColby
1 Solution
 
fridomCommented:
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
 
ozoCommented:
#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
 
TristinColbyAuthor Commented:
fridom: I should have specified. I need it to be portable.


ozo.  can you explain that a little bit.  
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
TristinColbyAuthor Commented:
can anyone explain ozo's code?   Specifically "lines = (char **)realloc(lines,sizeof(char *)*++line))"  
0
 
TristinColbyAuthor Commented:
also, can someone explain why he use a pointer to a pointer?  Is there any other way to write it?
0
 
ozoCommented:
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
 
AlexNekCommented:
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
 
TristinColbyAuthor Commented:
:) I understand now. Thank you for your help.
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now