printf()函数的C++等价物或格式化输出

6

我是C++世界的新手。 我知道在C++中,std::cout被用于控制台输出。但考虑以下C语言代码:

#include<stdio.h>

int main(){
    double dNum=99.6678;
    printf("%.02lf",dNum);
    //output: 99.67
 return 0;
}

如何使用 cout 在 C++ 中将 double 类型的值格式化为保留 2 位小数?

我知道 C++ 向后兼容 C。但是如果有 printf() 的等效函数,请问它在 C++ 中定义在哪里?


3
使用 setprecisionstd::cout << std::fixed << std::setprecision(2) << dNum;。该语句用于输出变量dNum的值,并指定输出小数点后保留两位数字。要使用该语句,请确保包含头文件 <iomanip> - Hatted Rooster
9个回答

12

这就是你想要的:

std::cout << std::fixed << std::setprecision(2);
std::cout << dNum;

不要忘记:

#include <iostream>
#include <iomanip>

7

没有等效的方法。使用cout进行格式化输出很麻烦。

所有建议使用setprecision等函数的解决方案在使用长格式时都很糟糕。

boost::format不支持一些非常好用的功能。与printf的不兼容之处。我仍然使用printf,因为它是无可争议的最佳选择。


2

如果你需要使用类似于printf的格式化输出,你应该使用snprintf(或在其基础上构建一个分配变体)。请注意,sprintf要求您能够保证结果不会超出您所定义的缓冲区,以保持定义行为。另一方面,snprintf可以保证不会溢出缓冲区,因为您规定了将写入字符串的最大字符数(它会截断输出)。

您甚至可以构建一些可以直接馈送到ostream的东西,在snprintf之上自动分配缓冲区并放置在一个对象中,在销毁该内存后释放它。再加上一种将对象馈送到ostream的方法,就可以完成它了。

struct FMT {
  char buf[2048];
  FMT(const char* fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    vsnprintf(buf, sizeof(buf), fmt, ap);
    va_end(ap);
  }
};

inline std::ostream& operator<< (std::ostream& os, FMT const& str) { os << (const char*)str.buf; return os; }

然后你可以这样使用:

 cout << FMT("The answer is %d", 42) << endl;

如果您正在使用GNU库,当然可以直接使用printf,因为coutstdout是同一个对象。否则,您应该避免混合使用stdioiostreams,因为这些对象之间没有同步的保证。

1
如果使用GCC,您可以给构造函数添加__attribute__ ((format (printf, 1, 2))),以获得一些类型的编译检查。 - jxh

2

如果您真的想要重复使用与C语言相同的格式化技术,您可以使用Boost::format,它正是这样做的:

cout << boost::format("%.02lf") % dNum;

1
非常好的建议。Boost.Format将C风格的灵活性(包括动态提供格式化的能力)与C++类型安全相结合。 - Christian Hackl

2
在C++中,是否有类似于printf()的函数?如果有,它在哪里定义?
有一个标准提案P0645旨在向C++中添加类似的格式化功能。与此同时,您可以使用{fmt}库来实现此提案和更多功能。
#include <fmt/core.h>

int main()
  fmt::print("{:.02f}", 99.6678);
}

P0645和{fmt}使用类似Python的格式字符串语法,与printf相似,但使用{}作为分隔符,而不是%
此外,类型信息得到保留,因此您无需使用l或其他嘈杂的说明符。

0

使用std::cout的函数等效于您的printf()调用,即:

 std::cout << fixed << setprecision(2) << dNum;

需要使用#include <iomanip><iostream>

C++中的printf()等效函数是std::printf(),声明在<cstdio>中。

此外,由于向后兼容C语言 - 特别是C++98需要最大限度地向后兼容C89 - C的printf()声明在<stdio.h>中也可用于C++。但请注意,<stdio.h>已被弃用(标记为将来版本的C++标准中删除)。另外,并非所有在C99(1999年C标准)或更高版本中引入的printf()功能都一定支持C++。


2
printf没有被弃用。<stdio.h>已经被弃用,推荐使用<cstdio>,就是这样。 - Christian Hackl

0
使用C++将值输出到控制台,您需要全局的ostream对象cout和<<运算符。endl是另一个全局的ostream对象,用作换行符。
所有这些都在头文件中定义。您还可以使用各种格式化标志来控制输出的呈现方式...
#include<iostream>
using namespace std;

int main() {

    double dNum = 99.6678;

    cout << dNum;
    cout.setf(ios::scientific, ios::floatfield); // format into scientific notation
    cout << dNum;
    cout.precision(8); // change precision
    cout << dNum;

    system("pause");
    return 0;
}

cout写入标准输出(stdout)。通常情况下,stdout与终端相关联。在非常罕见的情况下,该终端是一个控制台(console)。'cout'代表"字符输出",与控制台完全无关。 - William Pursell

0

将您的程序保存为CPP并运行它。

它会运行并打印答案。

因为C++也有像C一样的printf()scanf()


3
你应该小心使用printf,因为它会将内容打印到stdout,而这个输出流不一定与cout同步。除非你知道自己在做什么,否则不应同时使用stdoutcout。请注意避免这种情况的发生。 - skyking

0

你也可以在 C++ 中使用 sprintf 将内容“打印”到一个字符串,然后使用 cout 输出这个字符串。这种策略利用了你对 printf 格式化的经验。


2
这样做比直接使用 printf 更好吗? - Christian Hackl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接