scanf和printf在C ++流中没有模拟这一事实的历史原因是什么?

时间:2014-05-04 20:50:09

标签: c++ c++11 iostream history c++-standard-library

printf("%d: %d, %d\n", foo, bar, baz);

更清洁
std::cout << foo << ": " << bar << ", " << baz << "\n";

并没有明显的方法来重写

scanf("%d: %d, %d\n", &foo, &bar, &baz);

除了,说

std::cin >> foo;
std::cin.ignore();
std::cin >> bar;
std::cin.ignore();
std::cin >> baz;
std::cin.ignore();

由于显而易见的原因而劣等。

为什么不存在istream::scanfostream::printf等功能?我无法理解为什么不能使以下内容成为可能的原因:

std::cout.printf("%d: %d, %d\n", foo, bar, baz);
std::cin.scanf("%d: %d, %d\n", foo, bar, baz);

我确定有人必须在某个时候为标准提出建议,而且一定是被拒绝了。为什么呢?

3 个答案:

答案 0 :(得分:3)

首先,您始终可以使用C ++中的C函数。

其次,很少有“真正的”程序使用scanf,因为您通常需要能够让您更好地控制所读内容的内容,以及如何将其与您不想阅读的输入内容分开。程序从文件或可能是某些用户界面读取,但很少来自“标准输入”,如果他们这样做,就像过多的unix工具一样,它们通常不使用scanf。

使用printf,可能没有任何理由在C ++类中将printf或sprintf复制到字符串。

答案 1 :(得分:2)

您仍然可以在C ++中使用printfscanf。那么,您的提案会带来什么好处?只要给他们不同的名字,你什么也得不到。

它们不是非常C ++风格的函数,主要是因为它们不是类型安全的,并且它们容易出现编译器检查无法避免的运行时错误。

这些函数的C ++类似于stringstream

答案 2 :(得分:2)

键入安全性,并使用数据以无法检查的方式确定程序流。

在C ++ 11之前,C ++中没有类型安全的variardic构造。因此禁止了变量printf语法。现在你可以走近了:

cpprintf("bob %s your %s! %d\n")<< "is" << "uncle" << 42;

我们创建一个格式化程序对象,然后<<参数。

这里的缺点是字符串"bob ...正在控制代码流 - 数据控制代码是错误和漏洞的严重来源。

当用户定义的constexpr文字到达时,我们终于可以“修复”这个,因此可以在编译时解析格式字符串,并检查参数是否为类型安全。

哦,最后一个问题是printf不允许对象自行格式化 - 它不能由printf用户扩展。