`std::istream::operator>>()` 可以接受像 stdio 的 %i 格式说明符这样的整数基数前缀吗?

发布于 2024-10-08 09:08:45 字数 702 浏览 4 评论 0原文

使用 scanf() 及其变体时,格式说明符 %i 将接受十六进制(前缀“0x”)、八进制(前缀“0”)或十进制(无前缀)数据,因此对于例如,字符串“0x10”、“020”和“16”都转换为十进制值为 16 的整数。

这可以通过 std::istream::operator>> 格式的输入来完成吗?

使用普通的 >> i 没有 i/o 操纵器“0x10”被转换为零(或者更确切地说,前导 0,“x10”部分不被处理),“020”被转换为 20。十六进制、octdec 操纵符的行为类似于 %x%o%d 分别。我正在寻找一个像 %i 一样工作的通用整数输入操纵器。

有趣的是,hex 操纵器可能接受“0x10”和“10”,并将其转换为十进制 16。

如果您可能想知道,我正在实现一个表达式计算器,并且我希望使用 C/C++ 前缀约定允许整数操作数为十六进制、八进制或十进制。当前使用 sscanf() 的实现使用 %i 自动执行此操作,我很好奇是否可以修改它以使用 iostream 而无需显式解析数字格式。

When using scanf() and its variants, the format specifier %i will accept data as hex (prefixed "0x"), octal (prefixed "0"), or decimal (no prefix), so for example the strings "0x10", "020", and "16" are all converted to an integer with decimal value 16.

Can this be done with std::istream::operator>> formatted input?

Using plain >> i with no i/o manipulator "0x10" is converted to zero (or rather the leading 0 is, the "x10" part is not processed), and "020" to 20. The hex, oct and dec manipulators behave like %x, %o and %d respectively. I am looking for a general integer input manipulator that works like %i.

Interestingly perhaps the hex manipulator accepts both "0x10" and "10" converting either to 16 decimal.

In case you might be wondering, I am implementing an expression evaluator, and I would like allowed integer operands to be hex, octal, or decimal using the C/C++ prefix convention. The current implementation using sscanf() does this automatically using %i, and I am curious as to whether this could be modified to use iostream without having to explicitly parse the numeric format.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

仅冇旳回忆 2024-10-15 09:08:45

basic_istream 格式标志中的基本字段指示如何解释数字。该字段可以设置为decocthex。默认情况下,它设置为dec。如果没有设置为其中任何一个,basic_istream 的行为将类似于 scanf%i 标志:

// automatically detect the base, depending on prefix
std::cin.unsetf(std::ios_base::basefield);

The base field in the format flags of basic_istream dictates how to interpret numbers. The field can be set to dec, oct and to hex. By default it's set to dec. If it's set to none of them, basic_istream will behave like scanf's %i flag:

// automatically detect the base, depending on prefix
std::cin.unsetf(std::ios_base::basefield);
月亮是我掰弯的 2024-10-15 09:08:45

不是直接重置基场,而是一个稍微直观一点的
解决方案是使用 setbase(int base)< /a> 操纵符:

#include <iomanip>
#include <iostream>

int main()
{
  int i;
  std::cin >> std::setbase(0) >> i;
  std::cout << i << std::endl;
}

引用 cppreference:

除 8、10 或 16 之外的基数值会将基域重置为零,这对应于十进制输出和依赖于前缀的输入。

Instead of resetting the basefield directly, a slightly more intuitive
solution is to use the setbase(int base) manipulator:

#include <iomanip>
#include <iostream>

int main()
{
  int i;
  std::cin >> std::setbase(0) >> i;
  std::cout << i << std::endl;
}

To quote cppreference:

Values of base other than 8, 10, or 16 reset basefield to zero, which corresponds to decimal output and prefix-dependent input.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文