从字符串流读取具有特定字段宽度的int

问题描述 投票:2回答:1

我正在尝试从字符串中以十六进制表示法读取字节。字节可能会或很不幸地不会被空格分隔,例如" 00 ffab c "是一个有效的示例,应读取4个字节,分别为0x00、0xff,0xab和0x0c。问题是跳过空格,但仅读取相邻的两个数字(如果存在)。

如果输入来自文件,则任务将像while(fscanf(f, "%2d", &i) == 1) ...一样容易,因为sscanf跳过空格,底层FILE跟踪读取位置,并且最大字段宽度仅应用于项目读取,而不读取包含空格的原始输入字符。但是当从字符串中读取时,位置跟踪是不可能的。我需要使用%n格式转换说明符,该说明符将迄今为止通过此调用读取的字符数存储到关联的变量中,例如scanf(f, "%2d%n", &i, &readIncr),并通过添加相应的增量来手动保持读取位置。

这有点麻烦,因此我想使用[[does跟踪底层字符串中的位置的std::istringstream

但是在输入流上设置宽度不会达到预期的效果。以下是一个最小的演示;为简单起见,我使用十进制整数。

input

字段宽度的文档和示例很少。我做错什么了吗?我这个用例根本不是故意的吗?

#include <iostream> #include <sstream> #include <iomanip> #include <cstdio> using namespace std; int main() { const char *s = " 1234"; int i; istringstream is(s); if (is >> setw(2) >> i) { cout << "stringstream i: " << i << '\n'; } if (sscanf(s, "%2d", &i) == 1) { cout << "scanf i: " << i << '\n'; } }

输出是(使用g ++和MSVC)

$ g++ -Wall -o fieldwidth fieldwidth.cpp && ./fieldwidth stringstream i: 1234 scanf i: 12

c++ width field istringstream setw
1个回答
0
投票
可怜的cpp流远非完美。 AFAIK std::setw仅适用于读取字符串。您可以做的是:

#include <iostream> #include <sstream> #include <iomanip> #include <cstdio> using namespace std; int main() { const char *s = " 1234"; std::string i; istringstream is(s); if (is >> setw(2) >> i) { cout << "stringstream i: " << std::stoi(i) << '\n'; } int j; if (sscanf(s, "%2d", &j) == 1) { cout << "scanf i: " << j << '\n'; } }

您将获得预期的输出:

stringstream i: 12 scanf i: 12

© www.soinside.com 2019 - 2024. All rights reserved.