1

I have seen a lot of similar posts regarding very similar cases but my case is a bit different. I'm a newbie to c++, so any help would be appreciated.

I have a large file full of lines full of integers. Each number is separated by blank spaces. I need diferent lines to stay seperate, i don't want to read all the file on one go. I want to read line by line and parse each line in to a vector of integers. The code I've got is this:

int main () {
  string line;
  ifstream myfile;
  myfile.open ("numbers.txt");
  vector<int> vec1;
  int const2=0;
  int a;
  while ( getline (myfile,line) ){ // I understand that this reads line 
                                   // by line and stores the string to "line"
    while (line >> a){  // this part is the one i can't get right, i 
                        // want to push_back every int from
                        // the string to vec1 but doesn't work
      vec1.push_back(a); 
      // More stuff
    }
    // more stuff
  }
  myfile.close();   
  return 0;
}
Estcc
  • 119
  • 1
  • 2
  • 12
  • What part are you having issues with: reading the file? creating vectors of vectors? inserting into a vector? – Thomas Matthews Apr 29 '15 at 13:48
  • @ThomasMatthews It's probably the part in the code that says "This is the part I can't get right" – lcs Apr 29 '15 at 13:48
  • [link](http://stackoverflow.com/questions/7663709/convert-string-to-int-c) but there is a lot of different ways, and you even dont need to read line. if in file is only ints you can do something like `while(myfile >> a) { vec1.push_back(a); }` – POTEMKINDX Apr 29 '15 at 13:50
  • If you just want one vector with all the data you only need `while (myfile >> a)...`. – molbdnilo Apr 29 '15 at 13:52
  • possible duplicate of [Parsing a comma-delimited std::string](http://stackoverflow.com/questions/1894886/parsing-a-comma-delimited-stdstring) – Jonathan H Apr 29 '15 at 13:57
  • Like ThomaMatthews said I have probles where it says so, and I need all the integers from every line in diferent vectors/arrays so reading each number at a time doesn't work for me, thanks. – Estcc Apr 29 '15 at 13:57

2 Answers2

3

You need a std::istringstream:

std::istringstream iss(line);
while(iss >> a) {
     vec1.push_back(a);
     // ....
}

But in fact if you only have numbers in that file, it would be enough to leave out the while ( getline (myfile,line) ){ loop completely and just write

while(myfile >> a) {
     vec1.push_back(a);
     // ....
}
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • The last part doesn't work because I need the numbers of every line in different vectors/arrays. – Estcc Apr 29 '15 at 13:59
  • @MikeCC So well, you didn't state this in your question. Anyway the `std::istringstream` solution does what you want. – πάντα ῥεῖ Apr 29 '15 at 14:01
  • I did, ". I want to read line by line and parse each line in to a vector of integers." That was on the original post. – Estcc Apr 29 '15 at 14:03
  • And yes, it does, when I tried to up vote your first comment i was in the first 5 min window and it didn't let me ;) – Estcc Apr 29 '15 at 14:04
0

Here is the C++11 way (use -std=c++0x with g++ or clang++), you can google each function that you don't know. Using back_inserter and istream_iterator is much cleaner than any while/for loop you would come up with on your own. Using deque in this context is also more efficient. Obviously you can also take the file name from the main input.

#include <algorithm>
#include <iterator>
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <deque>

int main()
{
    const std::string filename = "/path/to/file.txt";

    std::string    line_buf;
    std::ifstream  file( filename );

    std::deque< std::deque<int> > parsed_data;
    if (file) while ( std::getline(file,line_buf) )
    {
        std::deque<int>    parsed_line;
        std::stringstream  ss( line_buf );

        std::copy( std::istream_iterator<int>(ss), std::istream_iterator<int>(), std::back_inserter(parsed_line) );

        parsed_data.emplace_back();
        parsed_data.back().swap( parsed_line );
    }
}

To check the result in your console, you can use this function

#include <cstdio>
void show_result( const std::deque< std::deque<int> >& data )
{
    size_t line_count = 0;
    for ( auto& line: data )
    {
        printf( "Line %02ld: ", ++line_count );
        for ( auto& num: line )
            printf( "%d ", num );
            printf( "\n" );
    }
}
Jonathan H
  • 7,591
  • 5
  • 47
  • 80