2

I am a newbie in C++. I'm currently doing a task that requires me to read a file, and store each line into a linked list, and then store all linked lists into a linked list. In sum, I would need to create a linked list of rows, and each row contains linked list of chars.

And I am stuck on here for quite a while. As the program will be tested by files that have different number of lines. So that I am thinking that I am supposed to create multiple linked lists according to the actual number of lines. However, my current solution cannot accomplish this.

Below is my loadFile method

void loadFile(list< <list<char> > &rows, const string &file)
{
     list<char> elements;
     char ch;
     ifstream fin;
     fin.open(file.c_str());
     while(!fin.eof()){
          while(fin.get(ch))
          {
              if(ch != '\n')
               {
                    elements.push_back(ch);
               }
           rows.push_back(elements);
          }
      }
      fin.close();
}

Apparently, this method does not do what I am supposed to do. So I am wondering is there anyway that I could create as many as linked list according to the number of lines in the file, and push all linked lists into the row linked list? Or could anyone please advise my alternative solution? (The file has to be stored into linked lists tho, which means we cannot use array etc.) Appreciate for your help in advance.

Dorisacat
  • 109
  • 1
  • 9
  • 2
    Are you sure your assignment allowed you to use STL list? Usually when referring to linked lists, you're supposed to implement them on your own. – o_weisman Apr 16 '14 at 07:14
  • Yes, I know what you mean. That's why all solutions that I found on the internet is about manipulating linked list. This is our first C++ assignment, so we are allowed to use the STL list – Dorisacat Apr 16 '14 at 07:31

3 Answers3

2

Consider using strings instead of storing every single character individually

#include <iostream>
#include <list>
#include <string>

int main()
{
  std::list<std::string> lines;
  std::string line;

  while (getline(std::cin, line))
    lines.push_back(line);
}

Please don't do this:

 while(!fin.eof()){
Community
  • 1
  • 1
user657267
  • 20,568
  • 5
  • 58
  • 77
  • Thank you for your quick response. Does it mean that while(!fin.eof()) and while(fin.get(ch)) are doing the same thing so I shouldn't do that? – Dorisacat Apr 16 '14 at 07:33
  • `while(!fin.eof())` only checks if the end of file has been reached, if the file reading fails for any other reason (for instance if you try and extract an integer from alphabetic text) you'll be stuck in an infinite loop. `while(fin.get(ch))` will check for any error on the stream including `eof` (via the stream `fail()` method), and in your code `while(!fin.eof())` is not only unnecessary but potentially disastrous. Have a look at the linked question. – user657267 Apr 16 '14 at 07:44
  • That's considerate. Thanks again for the helpful hints : ) – Dorisacat Apr 16 '14 at 11:53
1

The inner while loop needs to be modified to cleanup elements when you encounter a \n.

while(fin.get(ch))
{
  if(ch != '\n')
  {
    elements.push_back(ch);
  }
  else
  {
    rows.push_back(elements);
    elements.clear();
  }
}

Everything else looks good to me.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
0

The code can be written simpler using std::getline. For example

void loadFile( std::list<std::list<char>> &rows, const std::string &file )
{
     std::ifstream fin( file );
     // or std::ifstream fin( file.c_str() );

     std::string record;
     while ( std::getline( fin, record ) )
     {
          rows.push_back( std::list<char>( record.begin(), record.end() ) );
     }
}

Take into account that in general case some lines can be empty. You could exclude such lines from the processing.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335