C++ cerr和clog之间的区别
在C++编程中,有许多输出信息的方法。其中常用的就是使用流操作符“<<”以及使用两个标准流对象cerr和clog。这两个流对象之间有什么不同呢?本文将详细说明两者之间的区别。
cerr和clog的定义
cerr和clog都是C++中的标准输出流。它们都是ostream类的对象。在iostream头文件中定义,它们都是全局变量。
在标准流之间切换的函数对于cerr和clog是相同的:
std::cout << "This is an output to cout." << std::endl;
std::cerr << "This is an error message to cerr." << std::endl;
std::clog << "This is a logging message to clog." << std::endl;
以上代码片段输出了三个不同的信息。第一个输出了一句话到标准输出(cout),而第二个则是将一条错误信息输出到标准错误输出(stderr),最后一个语句输出一条日志信息到标准日志输出流(clog)中。
cerr和clog的区别
cerr和clog间的区别在于它们的缓冲区。cerr使用无缓冲流,而clog则使用缓冲流。
缓冲区是指用来存储数据的内存块,当缓冲已满(或缓冲区终止)时会触发网络IO操作或文件IO操作,以便将缓冲区中的数据发送给目的地(console或日志文件)。
具体而言,cerr没有缓冲区。这样,每次调用cerr输出时都会直接输出到设备。这在编写需要及时获得日志信息的场景时是非常有用的,比如在调试期间,想要立即在控制台上输出某些信息。
相反,clog缓冲区的默认行为是行缓冲,这意味着缓冲区会在新行到达时刷新,或者缓冲区已满时刷新。这有利于将来的网络IO操作或文件IO缩减为一组单独的数据包,相对于每个放置缓冲区的单独数据包,这有利于优化IO速度。
综合示例
下面是一个综合示例,演示了缓冲问题:
#include <iostream>
#include <fstream>
#include <cstdlib>
int main () {
std::ofstream file("output.txt");
std::cout << "This is a normal message to cout." << std::endl;
std::cerr << "This is an error message to cerr." << std::endl;
std::clog << "This is a logging message to clog." << std::endl;
file << "This is an output to a file." << std::endl;
std::cerr << "This is an error message to cerr." << std::endl;
std::clog << "This is a logging message to clog." << std::endl;
std::cout << "This is a normal message to cout." << std::endl;
file << "This is an output to a file." << std::endl;
std::cerr << "This is an error message to cerr." << std::endl;
std::clog << "This is a logging message to clog." << std::endl;
std::exit(0);
}
在上述示例中,演示了如何将不同的消息发送到不同的流对象中。示例代码中,先将内容间隔着输出到控制台及文件,然后输出两个错误信息。在最后演示了将同样的消息输出到不同的目标:一个是文件,一个是控制台。在输出日志信息的时候会出现问题,当然是因为缓冲区与日志记录方式的选择。
结论
cerr和clog之间的区别在于其缓冲机制。cerr使用无缓冲流,每次输出操作即时输出;而clog使用缓冲流默认情况下是行缓冲,会在新行到达或者缓冲区已满时刷新缓冲区,从而输出缓冲区中的数据。因此,cerr用于输出实时信息,而clog用于输出缓存日志信息。
在编程中,开发者应该根据不同的场景选择合适的流对象。如果需要即时输出信息,应该选择cerr对象;如果需要输出缓冲日志信息,则应该选择clog对象。