【问题标题】:printf formatting equivalent in cpp's cout在 cpp 的 cout 中等效的 printf 格式
【发布时间】:2017-07-29 02:26:28
【问题描述】:

我现在是一名计算机科学专业的学生,​​今天收到了一个非常普通的作业,应该是用 C++ 编写的。直到今天我一直在学习全 C。这更像是一个盲目的任务。

在 C 中,我通常使用这个:

printf("\n\n\t%-30s %-7d liters\n\t%-30s %-7d liters\n\t%-30s %-7d km",
       "Current gasoline in reserve:",
       db.currentGas,
       "Total gasoline used:",
       db.usedGas,
       "Total travel distance:",
       db.usedGas);

由于作业的条件是它应该用 C++ 编写,这就是我尝试过的:

cout << setw(30) << "\n\n\tCurrent gasoline in reserve: "
     << setw(7) << db.currentGas << "litres"
     << setw(30) << "\n\tTotal gasoline used: "
     << setw(7) << db.usedGas << "litres"
     << setw(30) << "\n\tTotal travel distance: "
     << setw(7) << db.travelDistance << "km";

但看起来 C 的 %-30s 和 C++ 的 setw(30) 之间存在差异?

【问题讨论】:

  • 我永远不会理解人们对一个完全有效的问题投反对票,包括已经尝试过的代码以及具体提出的问题。可能是巨魔?
  • 实际上,在 C++ 中使用 printf 也是绝对合法的……不过,你宁愿使用 #include &lt;cstdio&gt; 而不是 #include &lt;stdio.h&gt;。我个人经常使用 printf(有时是 (s)scanf)函数,因为它比 C++ 流更方便。另一方面,如果涉及复杂的类或您不希望在所涉及的所有平台上都相同的类型定义(例如uint32_t...),则后者会非常方便。因此,如果分配只需要 C++,您可以保留对 printf 的调用 - 如果要求明确使用流,那么您需要更改...
  • @Aconcagua:避免 printf() / scanf() 系列函数仍然是一种很好的做法,因为它们允许出现各种潜在的致命错误(由于是可变参数函数,即没有类型检查)。另外,即使在 C 语言中,我也会远离任何 scanf() —— 它唯一略微比使用 get() 更容易获得 scanf() 调用...
  • @DevSolar 真相,scanf 我通常不使用 - 更喜欢一次读取整行(fgets)并使用 sscanf之后 - 如果 我愿意...不要误会我的意思,我非常欣赏 C++ 流。但有时,好的旧 printf 系列比流更方便,比较 fprintf(stderr, "[...] failed with error %d (%s)\n", errno, strerror(errno));std::cerr &lt;&lt; "[...] failed with error " &lt;&lt; errno &lt;&lt; " (" &lt;&lt; strerror(errno) &lt;&lt; ')' &lt;&lt; std::endl;。如果有代码已经正常工作,我会坚持下去,遵循永不接触正在运行的系统的准则..
  • @Aconcagua:同意,如果它在那里并且经过测试,请不要触摸它。但我会尽量避免在 new 代码中使用此类结构。

标签: c++ c io formatting iomanip


【解决方案1】:

确实有区别,像这样:

Georgioss-MacBook-Pro:~ gsamaras$ g++ -Wall main.cpp
Georgioss-MacBook-Pro:~ gsamaras$ ./a.out 


    Current gasoline in reserve:       6litres       
    Total gasoline used:       5litres     
    Total travel distance:       4kmGeorgioss-MacBook-Pro:~ gsamaras$ gcc -W
Georgioss-MacBook-Pro:~ gsamaras$ ./a.out 


    Current gasoline in reserve:   6       liters
    Total gasoline used:           5       liters
    Total travel distance:         4       kmGeorgioss-MacBook-Pro:~ gsamaras$ 

但问题是在哪里有区别?

setw(30) 等价于%30s但是,您使用了-30s,它使输出左对齐!为了获得类似的行为,请使用std::left,如下所示:

cout << "\n\n" << left << setw(30) << "\tCurrent gasoline in reserve: " << left << setw(7) << 6 << "litres\n" << left << setw(30) << "\tTotal gasoline used: " << left << setw(7) << 5 << "litres\n" << left << setw(30) << "\tTotal travel distance: " << left << setw(7) << 4 << "km";

【讨论】:

  • 感谢您的详细解释!如果问题有点愚蠢,我很抱歉,我对 C++ 完全陌生 :)
  • 几年前,当我开始在 uni 中学习 C++ 时,我和你处于同一水平,所以没有愚蠢的问题,我赞成 @TenzoNakami! =) 不客气。
  • 它应该是cout &lt;&lt; "\n\n\t" &lt;&lt; setw(30) &lt;&lt; left &lt;&lt; "Current gasoline...",因为您不想计算换行符/制表符。
  • 确实@KlitosKyriacou,我正要修改我的答案,但谢谢! :)
  • 感谢大家对我的支持!从上大学的第一天起,我就一直在使用 StackOverflow,但社区总是很棒 :) 感谢您支持像我这样处于学习曲线上的人!
【解决方案2】:

printf 中的减号进行左对齐。

要在 C++ 中执行此操作,您需要 std::left

【讨论】:

  • 根据gsamaras的回答,这确实是一个真实的答案。但总是感谢更多的解释! :)
【解决方案3】:

在 C++20 中,您将能够为此使用 std::format,这很容易从 printf 翻译:

std::cout << std::format(
       "\n\n\t{:30} {:<7} liters\n\t{:30} {:<7} liters\n\t{:30} {:<7} km",
       "Current gasoline in reserve:",
       db.currentGas,
       "Total gasoline used:",
       db.usedGas,
       "Total travel distance:",
       db.usedGas);

同时你可以使用the {fmt} librarystd::format是基于。 {fmt} 还提供了print 函数,使这更容易和更高效(godbolt):

fmt::print(
       "\n\n\t{:30} {:<7} liters\n\t{:30} {:<7} liters\n\t{:30} {:<7} km",
       "Current gasoline in reserve:",
       db.currentGas,
       "Total gasoline used:",
       db.usedGas,
       "Total travel distance:",
       db.usedGas);

免责声明:我是 {fmt} 和 C++20 std::format 的作者。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-12
    • 2013-08-12
    • 1970-01-01
    • 2020-09-30
    • 1970-01-01
    • 1970-01-01
    • 2011-08-05
    • 1970-01-01
    相关资源
    最近更新 更多