I have a bunch of input files that look like the following:
(8,7,15)
(0,0,1) (0,3,2) (0,6,3)
(1,0,4) (1,1,5)
I need to write a function that parses these inputs one number at a time, so I need to be able to separate the input by numbers, e.g.: 8, then 7, then 15, then 0, another 0, so on.
The only way I've thought of so far is to use istream.get() which returns the next character's ASCII code, which I can convert back to its character format by casting it to char. Then I'd check if the character was a number or not (so the brackets are ignored) but this way, any double (or triple) digit numbers are only read one digit at a time.
What would be the best way to achieve this?
By the way, I must use istream. It's part of the specification that I'm not allowed to change
Thanks
This is one solution:
struct integer_only: std::ctype<char>
{
integer_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['9'+1], std::ctype_base::digit);
return &rc[0];
}
};
int main() {
std::cin.imbue(std::locale(std::locale(), new integer_only()));
std::istream_iterator<int> begin(std::cin);
std::istream_iterator<int> end;
std::vector<int> vints(begin, end);
std::copy(vints.begin(), vints.end(), std::ostream_iterator<int>(std::cout, "\n"));
return 0;
}
Input:
(8,7,15)
(0,0,1) (0,3,2) (0,6,3)
(1,0,4) (1,1,5)
Output:
8 7 15 0 0 1 0 3 2 0 6 3 1 0 4 1 1 5
Online demo : http://ideone.com/Lwx9y
In the above, you've to replace std::cin
with the file stream after opening the file successfully, as:
std::ifstream file("file.txt");
file.imbue(std::locale(std::locale(), new integer_only()));
std::istream_iterator<int> begin(file);
std::istream_iterator<int> end;
std::vector<int> vints(begin, end); //container of integers!
Here, vints
is a vector which contains all the integers. You would like work with vints
to do something useful. Also, you can use it where int*
is expected as:
void f(int *integers, size_t count) {}
f(&vints[0], vints.size()); //call a function which expects `int*`.
Similar trick can be applied when reading only words from a file. Here is an example:
Here's some code, you can adapt to meet your precise needs
for (;;)
{
int ch = in.get();
if (ch == EOF)
break;
if (isdigit(ch))
{
int val = ch - '0';
for (;;)
{
ch = in.get();
if (!isdigit(ch))
break;
val *= 10;
val += ch - '0';
}
// do something with val
}
}
This is untested code.
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