【问题标题】:C specifier for printing type pair<size_t, bool>用于打印类型 pair<size_t, bool> 的 C 说明符
【发布时间】:2021-08-26 20:24:38
【问题描述】:

所以我正在开发一个使用 C++ 的项目。我制作了一个多图和以下类型的迭代器-

std::multimap < size_t, std::pair<size_t, bool> > position_seqsmapper;
std::multimap < size_t, std::pair<size_t, bool> > :: iterator position_seqsmap_iterator;

现在的问题是我需要使用 printf(不能使用 cout,因为该项目有一个相当大的代码库,已经 10 多年了,就是这样)。现在,当我尝试使用下面的代码打印它时,它会引发错误

for (position_seqsmap_iterator = position_seqsmapper.begin(); position_seqsmap_iterator != position_seqsmapper.end(); ++position_seqsmap_iterator)
{
    printf("%lu", position_seqsmap_iterator->first);
    printf("\t");
    printf("%lu", "%d", position_seqsmap_iterator->second);
    printf("\n");
}

给出这个错误

warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 2 has type ‘const char*’ [-Wformat=]
printf("%lu", "%d", position_seqsmap_iterator->second);`

当我注释掉 printf 中的第三行时,它工作正常。使用 printf 打印出 multimap 中的第二个元素对的说明符是什么??

【问题讨论】:

  • 你认为这条线到底是做什么的?里面的"%d" 是干什么用的?
  • @DavidSchwartz,我有一对 ,我以为 %d 会指定 bool 变量
  • 那么"%lu" 是干什么用的?

标签: c++ c printf


【解决方案1】:

当取消引用时,您的迭代器产生一个pair,其second 成员是另一个pairprintf() 不知道如何打印pair,因此您必须将每个firstsecond 成员分别传递给printf()

但是,对于那个 2nd 对,您尝试在单个 printf() 调用中使用 2 个格式字符串,这根本行不通。您的格式字符串只是"%lu",它需要unsigned long 作为输入,但您却给它一个字符串文字"%d",因此出现错误,position_seqsmap_iterator-&gt;second 被忽略。

您需要将2个格式字符串组合成1个格式字符串,例如:

for (position_seqsmap_iterator = position_seqsmapper.begin(); position_seqsmap_iterator != position_seqsmapper.end(); ++position_seqsmap_iterator)
{
    printf("%zu", position_seqsmap_iterator->first);
    printf("\t");
    printf("%zu%d", position_seqsmap_iterator->second.first, position_seqsmap_iterator->second.second);
    printf("\n");
}

或者,您可以将这 4 个 printf() 调用合并为 1 个单个调用:

for (position_seqsmap_iterator = position_seqsmapper.begin(); position_seqsmap_iterator != position_seqsmapper.end(); ++position_seqsmap_iterator)
{
    printf("%zu\t%zu%d\n", position_seqsmap_iterator->first, position_seqsmap_iterator->second.first, position_seqsmap_iterator->second.second);
}

然后可以进一步清理:

for (position_seqsmap_iterator = position_seqsmapper.begin(); position_seqsmap_iterator != position_seqsmapper.end(); ++position_seqsmap_iterator)
{
    const std::pair< size_t, std::pair<size_t, bool> > &elem = *position_seqsmap_iterator;
    const std::pair<size_t, bool> &val = elem.second;
    printf("%zu\t%zu%d\n", elem.first, val.first, val.second);
}

如果您使用的是 C++11 或更高版本,则进一步简化:

for (const auto &elem : position_seqsmapper)
{
    const auto &val = elem.second;
    printf("%zu\t%zu %d\n", elem.first, val.first, val.second);
}

在 C++17 及更高版本中更进一步:

for (const auto &elem : position_seqsmapper)
{
    const auto [first, second] = elem.second;
    printf("%zu\t%zu%d\n", elem.first, first, second);
}

【讨论】:

    【解决方案2】:

    由于您使用的是 C++,您可能会发现使用std::cout &lt;&lt; ... 比使用printf 更方便。但如果您愿意,可以使用printf

    std::pair&lt;size_t, bool&gt; 当然没有printf 格式说明符。您必须分别打印每个成员。

    size_tprintf 说明符是 "%zu"bool 没有,但你可以使用%d,因为bool 将被提升为int

    如果您使用 C++ 流,则只需将成员传递给输出流。

    std::pair<size_t, bool> p = ...;
    std::cout << p.first << ", " << p.second << "\n";
    

    默认情况下,bool 值打印为01。您可以使用std::boolalpha 操纵器将其打印为falsetrue

    如果您愿意,可以为您的类型定义重载的operator&lt;&lt; 运算符。

    【讨论】:

      猜你喜欢
      • 2012-10-06
      • 2018-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-05
      • 2021-07-13
      • 1970-01-01
      相关资源
      最近更新 更多