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::scanf
和ostream::printf
等功能?我无法理解为什么不能使以下内容成为可能的原因:
std::cout.printf("%d: %d, %d\n", foo, bar, baz);
std::cin.scanf("%d: %d, %d\n", foo, bar, baz);
我确定有人必须在某个时候为标准提出建议,而且一定是被拒绝了。为什么呢?
答案 0 :(得分:3)
首先,您始终可以使用C ++中的C函数。
其次,很少有“真正的”程序使用scanf,因为您通常需要能够让您更好地控制所读内容的内容,以及如何将其与您不想阅读的输入内容分开。程序从文件或可能是某些用户界面读取,但很少来自“标准输入”,如果他们这样做,就像过多的unix工具一样,它们通常不使用scanf。
使用printf,可能没有任何理由在C ++类中将printf或sprintf复制到字符串。
答案 1 :(得分:2)
您仍然可以在C ++中使用printf
和scanf
。那么,您的提案会带来什么好处?只要给他们不同的名字,你什么也得不到。
它们不是非常C ++风格的函数,主要是因为它们不是类型安全的,并且它们容易出现编译器检查无法避免的运行时错误。
这些函数的C ++类似于stringstream
。
答案 2 :(得分:2)
键入安全性,并使用数据以无法检查的方式确定程序流。
在C ++ 11之前,C ++中没有类型安全的variardic构造。因此禁止了变量printf
语法。现在你可以走近了:
cpprintf("bob %s your %s! %d\n")<< "is" << "uncle" << 42;
我们创建一个格式化程序对象,然后<<
参数。
这里的缺点是字符串"bob
...正在控制代码流 - 数据控制代码是错误和漏洞的严重来源。
当用户定义的constexpr文字到达时,我们终于可以“修复”这个,因此可以在编译时解析格式字符串,并检查参数是否为类型安全。
哦,最后一个问题是printf
不允许对象自行格式化 - 它不能由printf用户扩展。