I have a file full of lines in this format:
1 - 2: 3
I want to only load numbers using C++ streams. Whats the most elegant way to do it? I only thought about cin.get() and checikng each char if it is number or not.
I think this one would be the fastest -yet elegant- way:
int a, b, c;
scanf("%d-%d:%d", &a, &b, &c);
You can use a locale to change what things are read from the file as it is being read. That is, you will filter out all non-numeric values:
struct numeric_only: std::ctype<char>
{
numeric_only(): std::ctype<char>(get_table()) {}
static std::ctype_base::mask const* get_table()
{
static std::vector<std::ctype_base::mask>
rc(std::ctype<char>::table_size,std::ctype_base::space);
std::fill(&rc['0'], &rc[':'], std::ctype_base::digit);
return &rc[0];
}
};
std::fstream myFile("foo.txt");
myfile.imbue(std::locale(std::locale(), new numeric_only()));
Then when you read your file, it'll convert all non digits to spaces while leaving you only the numbers. After that, you can simply use your normal conversions to transform what is being read into ints.
std::vector<int> intFromFile;
std::istream_iterator<int> myFileIter(myFile);
std::istream_iterator<int> eos;
std::copy(myFileIter, eos, std::back_inserter(intFromFile));
Response to the comments below:
Here is what I did to get it to work
int main(int args, char** argv){
std::fstream blah;
blah.open("foo.txt", std::fstream::in);
if(!blah.is_open()){
std::cout << "no file";
return 0;
}
blah.imbue(std::locale(std::locale(), new numeric_only()));
std::vector<int> intFromFile;
std::istream_iterator<int> myFileIter(blah);
std::istream_iterator<int> eos;
std::copy(myFileIter, eos, std::back_inserter(intFromFile));
return 0;
}
And this put only the ints into the vector, nothing more, nothing less. The reason it wasn't working before was two fold:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With