Four digit numbers stored in a file are written in ASCII and separated by "Space", How do I read them as Integers. Example file: 53545153 49575150 56485654 53565257 52555756 51534850 56575356 56505055 55525453
Those look like 8 digit numbers.
To read a space separated number from a file simple use operator>>
from a stream to an integer.
int value;
if (stream >> value) {
// Successfully read a number.
}
If you want to read all the values from a file. You can use a loop:
int value;
while (stream >> value) {
// Enter the body of the loop each time a number is read.
}
Note: Your usage of eof() is bad practice:
while (!infile.eof()) {
// If you enter here the file may be open and readable
// BUT there may be no data left in the file and thus the next
// attempt to read will fail if there is no data.
//
// This happens because the last successful read will read up-to
// but not past the EOF. So you have read all the data but not read
// past the EOF so eof() will return false.
}
More Info
So how do we read 2 digit numbers from groups of 8 digit larger numbers that are space separated.
Well we want to make it work like standard stream readding so we still want to use the operator>>
to read from the stream. But none of the built in types read two digit numbers. So we need to define our own class that will read a two digit number.
struct TwoDigit
{
int value; // store the result here
operator int() {return value;} // Convert TwoDigit to integer
};
std::ostream& operator<<(std::ostream& str, TwoDigit const& data) {
str << data.value; // You can do something more complicated
// for printing but its not the current question
// so I am just going to dump the value out.
}
std::istream& operator>>(std::istream& str, TwoDigit& data) {
char c1 = 'X';
char c2 = 'Y';
if (str >> c1 >> c2) {
// successfully read two characters from the stream.
// Note >> automatically drops white space (space return etc)
// so we don't need to worry about that.
if (('0' <= c1 && c1 <= '9') && ('0' <= c2 && c2 <= '9')) {
// We have all good data.
// So let us update the vale.
data.value = ((c1 - '0') * 10) + (c2 - '0');
}
else {
// We have bad data read from the stream.
// So lets mark the stream as bad;
str.clear(std::ios::failbit);
}
}
return str;
}
Now in your code you can simply read
TwoDigit data;
if (stream >> data) {
// Read a single two digit value correctly.
}
// or for a loop:
while(stream >> data) {
// Keep reading data from the stream.
// Each read will consume two digits.
}
// or if you want to fill a vector from a stream.
std::vector<TwoDigit> data(std::istream_iterator<TwoDigit>(stream),
std::istream_iterator<TwoDigit>());
// You can even create a vector of int just as easily.
// Because the TwoDigit has an `operator int()` to convert to int.
std::vector<int> data(std::istream_iterator<TwoDigit>(stream),
std::istream_iterator<TwoDigit>());