文件中存储的四个数字以ASCII写入,并用“空格”分隔。如何将它们读为整数?
示例文件:
53545153 49575150 56485654 53565257 52555756 51534850 56575356 56505055 55525453
这是我尝试过的:
ifstream infile("afile2.txt");
if (infile.is_open())
{
string str2;
char c;
while (!infile.eof())
{
getline(infile, str2, ' ');
for (std::string::iterator it = str2.begin(); it != str2.end(); ++it)
cout << (char)*it;
cout << " ";
}
}
infile.close();
在上面的代码中,(char)*it
仅选择第一位数字,而ASCII码从2位数字开始,即48。
答案 0 :(得分:0)
文件中存储的四个数字以ASCII格式写入,并用“空格”分隔。如何将它们读取为整数。示例文件:53545153 49575150 56485654 53565257 52555756 51534850 56575356 56505055 55525453
看起来像8位数字。
要从文件中读取以空格分隔的数字,只需将operator>>
从流中转换为整数。
int value;
if (stream >> value) {
// Successfully read a number.
}
如果要从文件中读取所有值。您可以使用循环:
int value;
while (stream >> value) {
// Enter the body of the loop each time a number is read.
}
注意:您对eof()的使用不当:
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.
}
那么我们如何从8个大数字分隔的组中读取2个数字。
好吧,我们想使其像标准流读取一样工作,因此我们仍然想使用operator>>
从流中读取。但是,没有任何内置类型读取两位数字。因此,我们需要定义自己的类,该类将读取两位数字。
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;
}
现在在您的代码中,您只需阅读即可
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>());
答案 1 :(得分:0)
如果我正确理解了这个问题,这可能是一种方法。
#include <cmath>
#include <iostream>
#include <string>
#include <vector>
std::vector<int> conv(std::istream& is) {
std::vector<int> retval;
std::string group;
while(is >> group) { // read "53545153" for example
int mul =
static_cast<int>(std::pow(10, (group.size() / 2) - 1)); // start at 1000
int res = 0;
for(size_t i = 0; i < group.size(); i += 2, mul /= 10) {
// convert "53" to dec ASCII char 53 ('5') and then to an int 5 and
// multiply by 1000 (mul)
res += (((group[i] - '0') * 10 + (group[i + 1] - '0')) - '0') * mul;
}
retval.emplace_back(res); // store
}
return retval;
}
测试功能:
#include <sstream>
int main() {
std::istringstream is(
"53545153 49575150 56485654 53565257 52555756 51534850 56575356 56505055 55525453");
auto r = conv(is);
for(int x : r) {
std::cout << x << "\n";
}
}
输出:
5635
1932
8086
5849
4798
3502
8958
8227
7465