C++中的cout、cerr、clog使用及說明
在C++編程里,cout、cerr和clog是標(biāo)準(zhǔn)庫提供的重要輸出流對象,在數(shù)據(jù)輸出方面發(fā)揮著關(guān)鍵作用。
一、cout:標(biāo)準(zhǔn)輸出流
cout 是 std::ostream 類的對象,其作用是向標(biāo)準(zhǔn)輸出設(shè)備(一般是控制臺)輸出數(shù)據(jù)。它和 C 語言中的 printf 函數(shù)類似,但 cout 具有類型安全和運(yùn)算符重載的優(yōu)勢,使用起來更加方便。
1. 基本用法
借助 << 運(yùn)算符,能把各種類型的數(shù)據(jù)輸出到 cout。
#include <iostream>
using namespace std;
int main() {
int num = 42;
double pi = 3.14159;
string name = "Alice";
cout << "Hello, World!" << endl;
cout << "Number: " << num << endl;
cout << "Pi: " << pi << endl;
cout << "Name: " << name << endl;
return 0;
}
輸出結(jié)果如下:
Hello, World! Number: 42 Pi: 3.14159 Name: Alice
2. 格式化輸出
通過操縱符(如 setw、setprecision 等)或者成員函數(shù)(像 width()、precision()),可以對輸出格式進(jìn)行控制。
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
double value = 123.456789;
// 設(shè)置寬度和填充字符
cout << setw(10) << setfill('*') << 42 << endl; // 輸出:********42
// 設(shè)置精度
cout << fixed << setprecision(3) << value << endl; // 輸出:123.457
// 科學(xué)計(jì)數(shù)法
cout << scientific << value << endl; // 輸出:1.234568e+02
// 布爾值以文字形式輸出
cout << boolalpha << true << endl; // 輸出:true
return 0;
}
3. 鏈?zhǔn)捷敵?/h3>
<< 運(yùn)算符返回的是對 cout 對象的引用,所以可以進(jìn)行鏈?zhǔn)捷敵觥?/p>
int a = 10, b = 20; cout << "a = " << a << ", b = " << b << endl; // 輸出:a = 10, b = 20
4. 重定向輸出
可以利用 rdbuf() 函數(shù)對 cout 的輸出緩沖區(qū)進(jìn)行重定向。
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ofstream file("output.txt");
streambuf* oldBuf = cout.rdbuf(); // 保存原來的緩沖區(qū)
cout.rdbuf(file.rdbuf()); // 將輸出重定向到文件
cout << "This will be written to the file." << endl;
cout.rdbuf(oldBuf); // 恢復(fù)原來的輸出
cout << "This will be written to the console." << endl;
file.close();
return 0;
}
二、cerr:標(biāo)準(zhǔn)錯(cuò)誤流
cerr 同樣是 std::ostream 類的對象,它專門用于輸出錯(cuò)誤信息。和 cout 的主要區(qū)別在于,cerr 的輸出是不經(jīng)過緩沖的,會立即顯示在終端上。
1. 基本用法
當(dāng)程序出現(xiàn)錯(cuò)誤時(shí),可使用 cerr 輸出錯(cuò)誤信息。
#include <iostream>
using namespace std;
int main() {
ifstream file("nonexistent.txt");
if (!file.is_open()) {
cerr << "Error: Could not open file!" << endl;
return 1;
}
// 其他操作
return 0;
}
2. 無緩沖特性
cerr 的輸出不會被緩沖,這在需要立即顯示錯(cuò)誤信息的場景下非常重要。
// 模擬一個(gè)長時(shí)間運(yùn)行的進(jìn)程
for (int i = 0; i < 1000000; ++i) {
if (i % 100000 == 0) {
cerr << "Processing iteration " << i << endl; // 立即顯示
}
// 處理邏輯
}
3. 重定向錯(cuò)誤輸出
和 cout 一樣,cerr 的輸出也能被重定向。
ofstream errorFile("errors.log");
streambuf* oldBuf = cerr.rdbuf();
cerr.rdbuf(errorFile.rdbuf());
cerr << "This error will be logged to errors.log" << endl;
cerr.rdbuf(oldBuf); // 恢復(fù)
三、clog:標(biāo)準(zhǔn)日志流
clog 也是 std::ostream 類的對象,用于輸出日志信息。它和 cerr 的區(qū)別在于,clog 的輸出是經(jīng)過緩沖的。
1. 基本用法
clog 適用于記錄程序的執(zhí)行狀態(tài)等日志信息。
#include <iostream>
using namespace std;
void log(const string& message) {
clog << "[LOG] " << message << endl;
}
int main() {
log("Starting application...");
// 程序邏輯
log("Application terminated successfully.");
return 0;
}
2. 緩沖特性
clog 的輸出會先被存儲在緩沖區(qū)中,直到緩沖區(qū)滿或者遇到刷新操作。
clog << "This is a log message."; // 可能不會立即顯示 clog << flush; // 手動刷新緩沖區(qū)
3. 日志重定向
同樣可以對 clog 的輸出進(jìn)行重定向。
ofstream logFile("app.log");
clog.rdbuf(logFile.rdbuf());
clog << "Logging to file..." << endl; // 寫入文件
四、三者的對比與選擇
| 特性 | cout | cerr | clog |
|---|---|---|---|
| 緩沖機(jī)制 | 有緩沖 | 無緩沖 | 有緩沖 |
| 默認(rèn)輸出目標(biāo) | 標(biāo)準(zhǔn)輸出 | 標(biāo)準(zhǔn)錯(cuò)誤 | 標(biāo)準(zhǔn)錯(cuò)誤 |
| 典型應(yīng)用場景 | 普通程序輸出 | 錯(cuò)誤信息 | 日志記錄 |
| 是否可重定向 | 是 | 是 | 是 |
選擇建議:
- 當(dāng)需要輸出程序的正常結(jié)果時(shí),應(yīng)使用
cout。 - 遇到錯(cuò)誤情況,需要立即顯示錯(cuò)誤信息時(shí),要使用
cerr。 - 進(jìn)行程序調(diào)試或者記錄執(zhí)行狀態(tài)等日志操作時(shí),適合使用
clog。
五、高級應(yīng)用場景
1. 自定義流緩沖區(qū)
可以通過繼承 streambuf 類來創(chuàng)建自定義的流緩沖區(qū)。
class MyBuffer : public streambuf {
protected:
int overflow(int c) override { //override C++11 特性,顯式聲明該函數(shù)重寫基類的虛函數(shù),提高代碼安全性
if (c != traits_type::eof()) { //獲取流特性中定義的 EOF(文件結(jié)束符)值
// 自定義處理邏輯
cout << "*" << static_cast<char>(c) << "*";
}
return traits_type::not_eof(c);
}
};
// 使用自定義緩沖區(qū)
MyBuffer buf;
ostream customOut(&buf);
customOut << "Test" << endl; // 輸出:*T*e*s*t*
2. 多線程環(huán)境下的輸出
在多線程環(huán)境中使用輸出流時(shí),需要進(jìn)行同步操作,以避免輸出混亂。
#include <iostream>
#include <mutex>
#include <thread>
using namespace std;
mutex coutMutex;
void worker(int id) {
lock_guard<mutex> lock(coutMutex);
cout << "Thread " << id << " is working." << endl;
}
int main() {
thread t1(worker, 1);
thread t2(worker, 2);
t1.join();
t2.join();
return 0;
}
3. 結(jié)合 RAII 管理流重定向
利用 RAII(資源獲取即初始化)技術(shù),可以更安全地管理流重定向。
class StreamRedirect {
public:
StreamRedirect(ostream& stream, streambuf* newBuf)
: stream(stream), oldBuf(stream.rdbuf()) {
stream.rdbuf(newBuf);
}
~StreamRedirect() {
stream.rdbuf(oldBuf);
}
private:
ostream& stream;
streambuf* oldBuf;
};
// 使用示例
ofstream file("output.txt");
{
StreamRedirect redirect(cout, file.rdbuf());
cout << "Redirected output" << endl; // 寫入文件
} // 離開作用域時(shí)自動恢復(fù)
六、注意事項(xiàng)
性能考量:
- 無緩沖的輸出(如
cerr)會帶來一定的性能開銷,所以在性能敏感的場景中應(yīng)當(dāng)謹(jǐn)慎使用。 - 有緩沖的輸出(如
cout、clog)在頻繁刷新緩沖區(qū)時(shí),也可能會影響性能。
線程安全:
- 標(biāo)準(zhǔn)輸出流本身并不是線程安全的,在多線程環(huán)境下使用時(shí)需要進(jìn)行同步處理。
資源管理:
- 重定向流緩沖區(qū)后,要確保在適當(dāng)?shù)臅r(shí)候恢復(fù)原來的緩沖區(qū)。
七、總結(jié)
- cout:是最常用的輸出流,適用于普通的程序輸出,輸出內(nèi)容會被緩沖。
- cerr:主要用于輸出錯(cuò)誤信息,輸出不會被緩沖,能保證錯(cuò)誤信息立即顯示。
- clog:適用于記錄日志,輸出會被緩沖,有助于提高性能。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
vs2022項(xiàng)目文件夾內(nèi).vs文件夾容量虛高問題的解決
經(jīng)常會發(fā)現(xiàn)VS的項(xiàng)目文件夾占用空間很大,本文主要介紹了vs2022項(xiàng)目文件夾內(nèi).vs文件夾容量虛高問題的解決,具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09
C/C++實(shí)現(xiàn)快速排序(兩種方式)圖文詳解
這篇文章主要介紹了C/C++實(shí)現(xiàn)快速排序的方法,這幾天在找工作,被問到快速排序,結(jié)果想不出來快速排序怎么弄的;回來搜索了一下,現(xiàn)在記錄下來,方便以后查看2021-08-08
C語言內(nèi)嵌匯編API內(nèi)存搜索引擎實(shí)例
這篇文章主要介紹了C語言內(nèi)嵌匯編API內(nèi)存搜索引擎實(shí)例,涉及匯編語言與內(nèi)存相關(guān)操作,需要的朋友可以參考下2014-10-10
Sublime Text 3 實(shí)現(xiàn)C++代碼的編譯和運(yùn)行示例
下面小編就為大家?guī)硪黄猄ublime Text 3 實(shí)現(xiàn)C++代碼的編譯和運(yùn)行示例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-09-09
c++ sqlite3如何利用事務(wù)(BEGIN;COMMIT;)批量操作
這篇文章主要介紹了c++ sqlite3如何利用事務(wù)(BEGIN;COMMIT;)批量操作,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08

