Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
cstdio流与iostream流? 我刚刚了解了 iSyBase::SycCyWiStdio函数的存在,它基本上允许您关闭(或如果已经关闭它)在C++中使用的代码> IOSWATE/流和CSTIDO 流,它是标准C.的一部分。 现在,我一直认为 StdOut,代码> STRRR 和 STDIN < /C> >基本上被封装在一组C++中的对象中。但如果它们必须相互同步,这将表明C++的iostream类不是C的stdin等的包装器_C++_C_Stream_Iostream_Cstdio - Fatal编程技术网

cstdio流与iostream流? 我刚刚了解了 iSyBase::SycCyWiStdio函数的存在,它基本上允许您关闭(或如果已经关闭它)在C++中使用的代码> IOSWATE/流和CSTIDO 流,它是标准C.的一部分。 现在,我一直认为 StdOut,代码> STRRR 和 STDIN < /C> >基本上被封装在一组C++中的对象中。但如果它们必须相互同步,这将表明C++的iostream类不是C的stdin等的包装器

cstdio流与iostream流? 我刚刚了解了 iSyBase::SycCyWiStdio函数的存在,它基本上允许您关闭(或如果已经关闭它)在C++中使用的代码> IOSWATE/流和CSTIDO 流,它是标准C.的一部分。 现在,我一直认为 StdOut,代码> STRRR 和 STDIN < /C> >基本上被封装在一组C++中的对象中。但如果它们必须相互同步,这将表明C++的iostream类不是C的stdin等的包装器,c++,c,stream,iostream,cstdio,C++,C,Stream,Iostream,Cstdio,我被这搞糊涂了?有人能澄清C++的iostream和C的stdio是如何在不同的抽象层次上做完全相同的事情的吗?我以为他们是一样的 它们是如何被同步的?我一直认为它们是相同的东西,一个包裹另一个,本质上。实际上stdout,stderr和stdin是操作系统的文件处理程序。和代码>文件> />结构C,以及 IoSturi类C++都是这些文件处理程序的包装器。iostream类和文件结构可能都有自己的缓冲区或其他需要相互同步的东西,以确保文件的输入或输出正确。好的,下面是我的发现 实际上,I/O最

我被这搞糊涂了?有人能澄清C++的iostream和C的stdio是如何在不同的抽象层次上做完全相同的事情的吗?我以为他们是一样的


它们是如何被同步的?我一直认为它们是相同的东西,一个包裹另一个,本质上。

实际上
stdout
stderr
stdin
是操作系统的文件处理程序。和<>代码>文件> />结构C,以及 IoSturi类C++都是这些文件处理程序的包装器。iostream类和文件结构可能都有自己的缓冲区或其他需要相互同步的东西,以确保文件的输入或输出正确。

好的,下面是我的发现

实际上,I/O最终由本机系统调用和函数执行

现在,以Microsoft Windows为例。实际上,
STDIN
STDIO
等都有可用的句柄(请参阅)。基本上,C++ C++代码> IoSoS
和C<代码> STDIO < /CUL>调用本机系统函数,C++ <代码> IOSROUND> /COMPUT>不包绕C的I/O函数(在现代实现中)。它直接调用本机系统方法

此外,我发现:

一旦stdin、stdout和stderr被重定向,就可以使用标准C函数(如printf()和get())与Win32控制台进行通信,而无需更改。但是C++ I/O流呢?由于cin、cout、cerr和clog与C的stdin、stdout和stderr密切相关,因此您希望它们的行为类似。这是正确的一半

C++I/O流实际上有两种风格:模板和非模板。旧的非模板版本的I/O流正在慢慢被一个新的模板样式所取代,这些模板首先由标准模板库(STL)定义,现在正在被吸收到ANSI C++标准中。VisualC++提供了两种类型,并允许您通过包含不同的头文件来在两者之间进行选择。STL I/O流按照您的预期工作,自动使用任何新重定向的stdio句柄。但是,非模板I/O流不能按预期工作。为了发现原因,我查看了源代码,方便地在Visual C++ CD-ROM上提供。 问题在于,较旧的I/O流被设计为使用UNIX风格的“文件描述符”,其中使用整数而不是句柄(0表示stdin,1表示stdout,等等)。这对于UNIX实现很方便,但是Win32 C编译器必须提供另一个I/O层来表示这种类型的I/O,因为Win32不提供兼容的函数集。在任何情况下,当您调用_open_osfhandle()将新的Win32句柄与(例如)标准输出关联时,它对其他层的I/O代码没有影响。因此,文件描述符1将继续使用与以前相同的底层Win32句柄,并且将输出发送到cout将不会产生所需的效果

幸运的是,原始I/O流包的设计者预见到了这个问题,并提供了一个干净而有用的解决方案。基类ios提供了一个静态函数sync_with_stdio(),该函数使库更改其底层文件描述符以反映标准I/O层中的任何更改。尽管这对于STL I/O流来说并不是严格必需的,但它并没有坏处,可以让我编写能够正确处理新形式或旧形式I/O流的代码

()

因此,调用
sync\u with_stdio()
实际上会更改底层文件描述符。事实上,设计师们增加了一个新的设计,以确保老的C++ I/O与Windows 32使用的是使用句柄而不是整数的系统兼容。

注意,使用“代码> SycIsIdStdioOver()/Cyto>与基于现代C++模板的STL I/O

< P>不可能是一个绕在另一个上的包装器(可以双向工作)。您可以使用<代码> IoSturiS/<代码>实现<代码> STDIO < /代码>函数,反之亦然。或者可以完全独立地编写。 而且
sync_with_stdio
保证了如果启用了这两个流,那么这两个流将同步。但是,如果用户真的想这样做,在禁用这两个流时,它们仍然可以同步


但是,如果一个是一个包装器,一个可能还有一个缓冲区,另一个不共享,例如,同步仍然是必要的。

< P> C++并没有对如何实现这些东西提出要求,只是在某些操作的影响是什么。对于<代码> <代码> vs.代码> <代码>功能这意味着一个可以包装另一个,两者本质上可以相同,或者它们要么完全独立(例如,对于用户定义的系统,不需要显式同步,并且有一个定义的机制来扩展
文件*
)但我不知道有哪一个系统真正做到了这一点。让一个实现成为另一个实现的包装是可能的,在
方面实现
是一个典型的实现选择,尽管它有一个缺点,那就是它会给某些实现带来额外的成本
std::cout << "Hello ";
printf("%s", "world");
std::cout << "!\n";