如何将ASCII数字转换为从文件中提取的整数

How to convert ASCII Number to Integer which are taken from a file

本文关键字:文件 提取 整数 ASCII 数字 转换      更新时间:2023-10-16

文件中存储的四位数字用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。

文件中存储的四位数字用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>());

如果我正确理解了问题,这可能是一种方法。

#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