为什么C++为IO引入了新函数,而它们已经存在于C中
Why did C++ introduce new functions for IO when they already exist in C?
IO涉及从内存位置读取字节或向内存位置写入字节。据我所知,这就是一切。因此,当printf、scanf、putch、getch和File IO函数等函数已经存在于stdio.h中的C中时,为什么在C++中为IO引入了新的流机制和概念?
当我们查看stdin和stdout时,C不是流的概念吗?
此外,我不断遇到"标准"IO这个术语。是否也有非标准IO之类的东西?
因此,当stdio.h中的C中已经存在printf、scanf、putch、getch和File IO函数时,为什么在C++中为IO引入了新的流机制和概念?
有几个原因(你需要读一本好的C++编程书)。但是std::ostream
和类似的类使您能够定义自己的
std::ostream& operator << (std::ostream& out, const MyClass& obj);
然后编码(假设您有一些MyClass obj;
实例)
std::cout << "two is " << 2 << " and obj is " << obj << std::endl;
这真的很好。标准printf
没有。GNU libc提供了printf
自定义作为扩展,没有人使用。printf
可能容易出错,并且具有未定义的行为,例如
// WRONG CODE: scary undefined behavior
const char* fmt = (rand()%2==0)?"this %s":"that %s";
printf(fmt, 34);
(您不应该希望静态地检测到这样的错误;在实践中,您会在运行时遇到分段错误)
但是C++流稍微安全一些(即使你可能也会对它们造成严重破坏)。您也可以将std::ostream
子类化(另请参阅std::ostrinstream)或拥有自己的操纵器。
此外,我不断遇到术语"标准"IO。是否也有非标准IO之类的东西?
是的,像read(2)这样的低级别系统调用只由POSIX标准化(而不是由你应该阅读的n3337中指定的C++11;而且,Windows有不同的阅读方式),其中一些(比如readahead(2)…)是Linux特有的。
您可能想阅读操作系统:三个简单的部分
您可以从流类派生并重载<lt;和>>运算符来实现您自己的兼容流行为,例如,到您必须为其编写驱动程序代码的固态存储设备。
也就是说,虽然流应该是多种类型的对象(文件、字符串流、内存流、与其他程序的连接),但旧的C++标准库并没有做得很好,许多人继续使用printf(),因为它更容易控制格式。
如今,编译重载<lt;和>>运算符通常只占C++编译器时间的很大一部分,即使在速度快的机器上,中等规模的项目也可能需要更长的时间来构建。所以我不会说这些问题已经消除了。仍然有一个引人注目的使用旧的C流并忽略std::提供的情况,然而这是一个意见问题,Herb Sutter可能不会同意。
据我所知,有三个主要原因导致了Iostreams的创建:
- 使用C的I/O设施时,格式化I/O不是类型安全的。尽管编译器可能会根据实际使用情况检查格式字符串,但
fprintf()
和fscanf()
的使用往往充满了类型错误。通过使用过载检测所涉及的类型,可以防止这些错误 - C格式的I/O无法扩展为以可预测的一致方式支持用户定义的类型。C++还通过重载运算符来解决这个问题
- 用户无法扩展C的I/O以支持其他源和/或目的地。C++流库定义了一个支持创建新型流的可扩展接口(
std::streambuf
)
C++还提供了对逐流本地化的支持,从而允许更改用于内置数字类型、字符分类以及内部和外部编码之间转换的格式。然而,本地化支持在某种程度上是事后添加的,并没有很好地集成。
tl;dr:C++IO流比C的I/O支持强大得多。
为什么有人会做出新的东西?为什么每年都有新车型问世?我们已经有车了,对吧?
引入C++流是因为它们的作者认为它们比C的I/O模型更好。
除其他外,它们具有类型安全性,缺乏类型安全性是C.中的一个大问题
我经常遇到术语"标准"IO。是否也有非标准IO之类的东西?
当然—任何进行I/O的库,而这些库不是C++标准库的一部分。
- C++模板来检查友元函数的存在
- C++quit()函数中可能存在作用域问题
- g++ 说函数不存在,即使包含正确的标头
- C++LinkedList问题.数据类型之间存在冲突?没有匹配的构造函数
- 我知道函数调用中存在歧义.有没有办法调用foo()函数
- 根据某个函数是否存在启用模板
- 尝试根据类中 typedef 的存在来专门化模板函数
- 无论如何,我可以确定构造函数是否存在吗?
- 当覆盖存在时调用基本虚拟"binded to object"函数
- 扩展类中的可选 vir 函数,测试它在运行时是否存在
- C++ 中的函数 GetCursorPos() 和 SetCursorPos() 存在一些问题
- C++ 用于检查容器类中是否存在函数和隐式推导规则的概念
- 当模板重载可用时,检查是否存在函数的自定义重载
- C++'Undefined reference to'错误,尽管包含路径中的头文件中存在函数定义
- 如何使用CPPCHECK查找CPP文件中是否存在函数
- 检查 Linux 库中是否存在函数
- 检查模板类是否存在函数
- 存在函数模板时的参数转换
- 如何检查 C/C++ 中是否存在函数
- 未定义的引用错误,即使存在函数