Janis Peisenieks
Janis Peisenieks

Reputation: 4988

Reading text file per line in C++, with unknown line length

I have a text file, that is formatted somewhat like this:

1 3 4 5 6
6 7 8
4 12 16 17 18 19 20
20
0

A line can contain 1 to 10000 integers. What I need to do, is read all of them line by line.

Pseudocode like this:

line=0;
i=0;
while(!file.eof()){
 while(!endLine){

 array[0][i++]=file.readChar();
 }
line++;i=0;
}

So, I have an array , into which I would like to read every line, and each line would consist of each of these integers.

The problem I'm having, is how to check if the end of a line has come.

Note, I can't use strings.

Yes, This is for a homework, but the main task for the assignment is to build a tree and then transform it. I can do that, but I've no idea how to read the integers from the file.

Upvotes: 4

Views: 10223

Answers (4)

xanatos
xanatos

Reputation: 111820

Probably something like this:

after reading an int, I manually skip spaces, tabs, carriage return and end of line (for this one you'll have to implement your logic). To read an int I read it directly using the C++ functions of ifstream. I don't read it character by character and then recompose it as a string :-) Note that I skip \r as "spaces. The end of line for me is \n.

#include <iostream>
#include <fstream>
#include <vector>

int main() 
{
    std::ifstream file("example.txt");

    std::vector<std::vector<int>> ints;

    bool insertNewLine = true;

    int oneInt;

    //The good() here is used to check the status of 
    //the opening of file and for the failures of
    //peek() and read() (used later to skip characters).
    while (file.good() && file >> oneInt)
    {
        if (insertNewLine)
        {
            std::vector<int> vc;
            ints.push_back(vc); 

            //With C++11 you can do this instead of the push_back
            //ints.emplace_back(std::vector<int>());

            insertNewLine = false;
        }

        ints.back().push_back(oneInt);

        std::cout << oneInt << " ";

        int ch;

        while ((ch = file.peek()) != std::char_traits<char>::eof())
        {
            if (ch == ' '|| ch == '\t' || ch == '\r' || ch == '\n')
            {
                char ch2;

                if (!file.read(&ch2, 1))
                {
                    break;
                }

                if (ch == '\n' && !insertNewLine)
                {
                    std::cout << std::endl;
                    insertNewLine = true;
                }
            }
            else
            {
                break;
            }
        }
    }

    //Here we should probably check if we exited for eof (good)
    //or for other file errors (bad! bad! bad!)

    return 0;
}

Upvotes: 4

g4th
g4th

Reputation: 993

You could read the numbers in a char and check against carriage return. A snippet that I had just tried is given below:

ifstream ifile;  
ifile.open("a.txt");  
char ch;  
while((ch = ifile.get()) != EOF)  
{  
    std::cout<<ch<<"\n";  
    if (ch == '\n')  
        std::cout<<"Got New Line";  
}  
ifile.close();  

Upvotes: 0

Skizz
Skizz

Reputation: 71060

You need a function to read a value from a file or indicates an end of line or end of file condition, something like:

result_type GetNextValue (input_file, &value)
{
  if next thing in file is a number, set value and return number_type
  if next thing in file is an end of line, return end_of_line_type
  if end of file found, return end_of_file_type
}

and then your array building loop becomes:

line = 0
item = 0
eof = false

while (!eof)
{
  switch (GetNextValue (input_file, value))
  {
  case value_type: 
    array [line][item++] = value

  case end_of_line_type:
    line++;
    item = 0;

  case end_of_file_type:
    eof = true
  }
}

I'll leave the details to you as it's homework.

Upvotes: 0

v01d
v01d

Reputation: 1507

There is a function called getline() which will read a whole line. Link

Upvotes: 2

Related Questions