【发布时间】:2023-03-07 18:22:01
【问题描述】:
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);
我敢肯定,一定有人在某个时候为标准提出了它,但它一定被拒绝了。为什么?
【问题讨论】:
-
因为 scanf 和 printf 本质上是不安全的。他们使用数据来查找代码,这是致命错误的良好来源。在 boost 库中有一个基于模板的安全模拟 printf。
-
偶尔,我将
template<int N> std::istream& operator>> (std::istream& i, char const(&)[N]) { return i.ignore(N); }用于非常基本的输入任务(可能加上错误检查)。然后你可以写std::cin >> foo >> ": " >> bar >> ", " >> baz >> "\n";但是,运算符中仍然存在不对称性。 -
我们现在有可变参数模板;在原始流设计中,这些函数必须使用可变参数列表(带有省略号和
va_args)。您会丢失类型信息(安全性)并且无法恢复类型以允许自定义类型重载(输出MyClassType)。所以也许这个问题的一部分是为什么它没有被添加到 C++11? -
与 dyp 类似,我有一个
ignore类,它允许我写std::cin >> foo >> ignore(": ") >> bar >> ignore(", ") >> baz;我觉得额外的冗长是值得的。
标签: c++ c++11 iostream history c++-standard-library