【问题标题】:how to use std::num_put for custom pointer output formatting?如何使用 std::num_put 进行自定义指针输出格式?
【发布时间】:2021-12-21 03:43:32
【问题描述】:
TLDR;

使用 c++ iostream 的指针的默认输出格式为 0xdeadbeef。 我想要的是以#xdeadbeef 形式输出的指针。

问题

出于测试目的,我以 s 表达式的形式输出一些 c++ 程序的内部数据,因此我将来可以选择使用 Common Lisp 来推理输出。 现在,十六进制数字以 #xdeadbeef 的形式编写,iostream 默认使用 C/C++ 典型的 0x... 语法。

所以,经过一番阅读,我想我已经接近找到解决方案了......只是,至少在 cppreference.com 上,没有足够的(演示代码或解释)让我理解,我如何我应该解决这个问题。

#include <iostream>
#include <locale>
#include <sstream>
#include <string>

struct lispy_num_put : std::num_put<char> {
  iter_type do_put(iter_type s, std::ios_base& f,
           char_type fill, const void* p) {
    std::ostringstream oss;
    oss << p;
    std::string zwoggle{oss.str()};
    if (zwoggle.length() > 2 && zwoggle.starts_with("0x")) {
      zwoggle[0] = '#';
    }
    // ... NOW WHAT TO DO??? I.e how to send the string along?
  }
};
// ...

如您所见,我现在有了我希望如何在输出中查看指针的字符串表示形式。只有我不清楚现在如何将该字符串发送到输出流中。

稍后,我将不得不使用一些imbue() 的东西来使我的输出流使用这个结构。我想,那部分我可以自己弄清楚。

【问题讨论】:

  • 一个简单的解决方法是定义一个函数/结构包装器来执行输出,而不是修改默认行为。
  • 看起来你可以使用默认的do_put——见C++ custom stream manipulator that changes next item on stream - Stack Overflow
  • @user202729 我认为这是这个用例的惯用方式,由 STL 支持...
  • 我认为改变全局打印指针的行为对于程序员来说是非常出乎意料的。包装在结构中会使其明确(如std::cout&lt;&lt; PrintPointerAsLisp{my_pointer};
  • 这是一整类用例的示例,没有真正解释(至少我在谷歌搜索时没有找到东西......)。同样的解决方案也适用于希望将其数字视为罗马文字的转世罗马皇帝;)问题是,如何使用 std::num_put 进行替代格式...

标签: c++ iostream


【解决方案1】:

使用iter_type s 参数输出字符。

*s++ = '#'; // outputs a hash 
while (...) *s++ = ...; // outputs digits
return s;

【讨论】:

  • 有这么简单吗?!正在验证... ;) for (auto c : zwoggle) { *s++ = c; } return s; ?
  • 我收到警告:mem-ref-test.cpp:19:13: warning: 'lispy_num_put::do_put' hides overloaded virtual functions [-Woverloaded-virtual] - 这是意料之中的吗?
  • and... 我仍然在输出中看到 0x... 而不是 #x...
  • do_put 应该是一个 const 函数。尝试添加const override
  • 宾果游戏!现在它可以工作了 - 非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-05
  • 2013-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多