Reputation: 128
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;
}
Upvotes: 1
Views: 298
Reputation: 7933
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" );
}
}
Upvotes: 0
Reputation: 1
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);
// ....
}
Upvotes: 3