为什么C++为IO引入了新函数,而它们已经存在于C中

Why did C++ introduce new functions for IO when they already exist in C?

本文关键字:存在 函数 IO C++ 新函数 为什么      更新时间:2023-10-16

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的创建:

  1. 使用C的I/O设施时,格式化I/O不是类型安全的。尽管编译器可能会根据实际使用情况检查格式字符串,但fprintf()fscanf()的使用往往充满了类型错误。通过使用过载检测所涉及的类型,可以防止这些错误
  2. C格式的I/O无法扩展为以可预测的一致方式支持用户定义的类型。C++还通过重载运算符来解决这个问题
  3. 用户无法扩展C的I/O以支持其他源和/或目的地。C++流库定义了一个支持创建新型流的可扩展接口(std::streambuf)

C++还提供了对逐流本地化的支持,从而允许更改用于内置数字类型、字符分类以及内部和外部编码之间转换的格式。然而,本地化支持在某种程度上是事后添加的,并没有很好地集成。

tl;dr:C++IO流比C的I/O支持强大得多。

为什么有人会做出新的东西?为什么每年都有新车型问世?我们已经有车了,对吧?

引入C++流是因为它们的作者认为它们比C的I/O模型更好。

除其他外,它们具有类型安全性,缺乏类型安全性是C.中的一个大问题

我经常遇到术语"标准"IO。是否也有非标准IO之类的东西?

当然—任何进行I/O的库,而这些库不是C++标准库的一部分。