c++ std庫中的文件操作學習筆記

1. 概述

C++標準庫提供了 頭文件中的幾個類來進行文件操作,這些類封裝了底層的文件操作,提供了面向對象和類型安全的接口,使得文件讀寫更加便捷和高效。主要的文件流類包括:

std::ifstream:用于從文件中讀取數據。

std::ofstream:用于向文件中寫入數據。

std::fstream:用于同時讀取和寫入文件。

這些文件流類(std::ifstreamstd::ofstreamstd::fstream)繼承自 std::istreamstd::ostreamstd::iostream,這些類本身繼承自 std::ios,從而提供了豐富的成員函數和操作符來處理文件I/O。

2. 文件流類詳解

2.1 std::ifstream:輸入文件流

std::ifstream 用于從文件中讀取數據。它繼承自 std::istream,具備所有輸入流的功能,同時添加了文件特有的操作。


#include <fstream>
#include <iostream>
#include <string>int main() {// 創建并打開輸入文件流std::ifstream infile("input.txt"); // "input.txt" 是要讀取的文件名// 檢查文件是否成功打開if (!infile) {std::cerr << "無法打開文件 input.txt" << std::endl;return 1;}// 讀取并輸出文件內容std::string line;while (std::getline(infile, line)) {std::cout << line << std::endl;}// 關閉文件流(可選,因為析構函數會自動關閉)infile.close();return 0;
}

要點:

  • 構造函數可以在創建對象時指定文件名和打開模式。

  • 檢查文件是否成功打開,以避免后續操作錯誤。

  • 使用 std::getline 逐行讀取文件內容。

2.2 std::ofstream:輸出文件流

std::ofstream 用于向文件中寫入數據。它繼承自 std::ostream,具備所有輸出流的功能,同時添加了文件特有的操作。


#include <fstream>
#include <iostream>
#include <string>int main() {// 創建并打開輸出文件流std::ofstream outfile("output.txt"); // "output.txt" 是要寫入的文件名// 檢查文件是否成功打開if (!outfile) {std::cerr << "無法打開文件 output.txt" << std::endl;return 1;}// 寫入數據到文件outfile << "Hello, World!" << std::endl;outfile << "這是第二行文本。" << std::endl;// 關閉文件流(可選,因為析構函數會自動關閉)outfile.close();return 0;
}

要點:

  • 默認情況下,std::ofstream 以寫入模式打開文件。如果文件不存在,會創建新文件;如果文件存在,會截斷文件內容。

  • 使用<<操作符向文件中插入數據。

2.3 std::fstream:文件流(讀寫)

std::fstream 用于同時讀取和寫入文件。它繼承自std::iostream,結合了 std::istream 和 std::ostream 的功能


#include <fstream>
#include <iostream>
#include <string>int main() {// 創建并打開文件流,設置為讀寫模式std::fstream file("file.txt", std::ios::in | std::ios::out | std::ios::app);// 檢查文件是否成功打開if (!file) {std::cerr << "無法打開文件 file.txt" << std::endl;return 1;}// 寫入數據到文件file << "追加一行內容。" << std::endl;// 移動讀指針到文件開頭file.seekg(0, std::ios::beg);// 讀取并輸出文件內容std::string line;while (std::getline(file, line)) {std::cout << line << std::endl;}// 關閉文件流file.close();return 0;
}

要點:

  • 通過構造函數的第二個參數指定文件打開模式,可以組合多個模式。

  • 適用于需要同時進行讀取和寫入操作的場景。

3. 打開和關閉文件

文件流類提供了多種方式來打開和關閉文件。

可以在創建文件流對象時,通過構造函數直接指定文件名和打開模式。


std::ifstream infile("input.txt"); // 以默認模式(即只讀方式)打開 input.txt
std::ofstream outfile("output.txt", std::ios::out | std::ios::trunc); // 以寫入和截斷模式打開 output.txt

如果在創建對象時沒有指定文件名,可以使用 open() 成員函數在后續打開文件。


#include <fstream>
#include <iostream>int main() {std::ifstream infile; // 創建輸入文件流對象infile.open("input.txt"); // 打開文件if (!infile.is_open()) {std::cerr << "無法打開文件 input.txt" << std::endl;return 1;}// 進行讀取操作...infile.close(); // 關閉文件return 0;
}

使用 close() 成員函數可以顯式關閉文件流。盡管在對象銷毀時,析構函數會自動關閉文件,但在需要提前釋放資源時,顯式調用 close() 是必要的。


infile.close();
outfile.close();

4. 文件打開模式

文件打開模式通過 std::ios::openmode 枚舉類型指定,可以組合使用多個模式。

常用的打開模式:

- std::ios::in:以讀取模式打開文件。

  • std::ios::out:以寫入模式打開文件。

  • std::ios::app:以追加模式打開文件,寫入操作將添加到文件末尾。

  • std::ios::ate:打開文件后,將文件指針定位到文件末尾。

  • std::ios::trunc:如果文件已存在,則截斷文件長度為0(默認與 std::ofstream 相關)。

  • std::ios::binary:以二進制模式打開文件。


// 以讀寫模式打開文件,不截斷現有內容
std::fstream file("data.txt", std::ios::in | std::ios::out);// 以二進制模式寫入數據, 截斷現有文件內容std::ofstream binaryOut("data.bin", std::ios::out | std::ios::binary | std::ios::trunc);

說明:

  • 組合使用:通過按位或操作符 | 組合多個打開模式,如 std::ios::in | std::ios::out 表示同時具備讀取和寫入權限。

  • 二進制模式:對于非文本文件(如圖片、音頻等),應使用 std::ios::binary 模式,以防止數據在讀取或寫入過程中被轉換。

5. 讀取文件

5.1 使用 >> 操作符讀取單詞

>> 操作符用于從文件中提取數據,自動跳過空白字符(如空格、換行符、制表符)。

假設 words.txt 文件內容如下:
在這里插入圖片描述


#include <fstream>
#include <iostream>
#include <string>int main() {std::ifstream infile("words.txt");if (!infile) {std::cerr << "無法打開文件 words.txt" << std::endl;return 1;}std::string word;while (infile >> word) { // 逐詞讀取std::cout << "讀取到的單詞: " << word << std::endl;}infile.close();return 0;
}

輸出如下:
在這里插入圖片描述
說明:

  • 適用于逐詞讀取數據,適合處理由空白字符分隔的數據。

  • 無法讀取包含空格的完整句子或短語。

5.2 使用 std::getline 逐行讀取

std::getline 函數用于從文件中逐行讀取數據,適用于處理文本文件中的行數據。

假設 lines.txt 文件內容如下:
在這里插入圖片描述


#include <fstream>
#include <iostream>
#include <string>int main() {std::ifstream infile("lines.txt");if (!infile) {std::cerr << "無法打開文件 lines.txt" << std::endl;return 1;}std::string line;while (std::getline(infile, line)) { // 逐行讀取std::cout << "讀取到的行: " << line << std::endl;}infile.close();return 0;
}

輸出如下:
在這里插入圖片描述
說明:

  • 適用于逐行處理文件內容,保留每行的完整信息。

  • 可以處理包含空格和其他特殊字符的行。

5.3 讀取整個文件內容

有時需要一次性讀取整個文件內容,尤其適用于小文件或需要對整個文件內容進行處理的場景。
假設 content.txt 文件內容如下:
在這里插入圖片描述


#include <fstream>
#include <iostream>
#include <string>int main() {std::ifstream infile("content.txt");if (!infile) {std::cerr << "無法打開文件 content.txt" << std::endl;return 1;}// 使用迭代器讀取整個文件內容到字符串std::string content((std::istreambuf_iterator<char>(infile)),std::istreambuf_iterator<char>());std::cout << "文件內容:\n" << content << std::endl;infile.close();return 0;
}

輸出如下:
在這里插入圖片描述
說明:

使用 std::istreambuf_iterator 迭代器可以高效地讀取整個文件內容。

適用于小至中等大小的文件,對于非常大的文件,可能需要分塊讀取以避免內存問題。

對此行代碼的理解:

std::string content((std::istreambuf_iterator<char>(infile)),std::istreambuf_iterator<char>());
  • 這行代碼使用了 std::istreambuf_iterator 來從輸入文件流 infile 讀取內容并構建一個 std::string 對象。具體理解如下:

  • std::istreambuf_iterator(infile):創建一個輸入迭代器,從 infile 的緩沖區讀取字符。

  • std::istreambuf_iterator():這是一個空的迭代器,用于表示輸入結束。
    構造 std::string:通過傳入兩個迭代器,構造函數會從 infile 中讀取所有字符,直到遇到結束迭代器。

  • 最終,這行代碼的作用是將整個文件的內容讀入到 content 字符串中。這樣,你就可以方便地對文件內容進行操作。

5.4 讀取二進制數據

對于非文本文件(如圖片、音頻、視頻等),需要以二進制模式讀取數據,以防止數據在讀取過程中被轉換或丟失。
假設需要讀取一個圖片文件 image.jpg 并輸出其大小。
在這里插入圖片描述


#include <fstream>
#include <iostream>
#include <vector>int main() {// 以二進制模式打開文件std::ifstream infile("image.jpg", std::ios::binary);if (!infile) {std::cerr << "無法打開文件 image.jpg" << std::endl;return 1;}// 移動讀指針到文件末尾以獲取文件大小//這行代碼將文件指針移動到文件的末尾。seekg 函數用于設置輸入流的位置,0 是偏移量infile.seekg(0, std::ios::end);//tellg 函數返回當前文件指針的位置(即文件的長度)std::streamsize size = infile.tellg();//這行代碼將文件指針重置回文件的開頭infile.seekg(0, std::ios::beg);// 讀取文件內容到緩沖區std::vector<char> buffer(size);if (infile.read(buffer.data(), size)) {std::cout << "成功讀取 " << size << " 字節。" << std::endl;} else {std::cerr << "讀取文件失敗!" << std::endl;}infile.close();return 0;
}

輸出如下:
在這里插入圖片描述
說明:

  • 使用 std::ios::binary 模式打開文件,確保數據按原樣讀取。

  • 通過 seekg tellg獲取文件大小,預分配緩沖區。

  • 使用read函數讀取二進制數據到緩沖區。

6. 寫入文件

6.1 使用 << 操作符寫入數據

<< 操作符用于向文件中插入數據,類似于向標準輸出流 std::cout 中插入數據。

將用戶信息寫入文件 users.txt。


#include <fstream>
#include <iostream>
#include <string>int main() {std::ofstream outfile("users.txt");if (!outfile) {std::cerr << "無法打開文件 users.txt" << std::endl;return 1;}// 寫入用戶信息outfile << "用戶名: Alice\n年齡: 30\n" << std::endl;outfile << "用戶名: Bob\n年齡: 25\n" << std::endl;outfile << "用戶名: Charlie\n年齡: 35\n" << std::endl;outfile.close();std::cout << "用戶信息已寫入 users.txt" << std::endl;return 0;
}

輸出如下:
在這里插入圖片描述
文件即自動創建于當前工程根目錄下

說明:

  • 使用 << 操作符可以方便地將各種數據類型寫入文件。

  • std::endl 用于插入換行符并刷新緩沖區。

6.2 使用 std::ofstream::write 寫入二進制數據

對于需要寫入二進制數據的場景,使用 write() 成員函數更為合適。

將一個字符數組寫入二進制文件 output.bin。


#include <fstream>
#include <iostream>
#include <vector>int main() {std::ofstream outfile("output.bin", std::ios::binary | std::ios::trunc);if (!outfile) {std::cerr << "無法打開文件 output.bin" << std::endl;return 1;}// 準備二進制數據std::vector<char> data = {'H', 'e', 'l', 'l', 'o', '\0'};// 寫入二進制數據到文件outfile.write(data.data(), data.size());if (!outfile) {std::cerr << "寫入文件失敗!" << std::endl;} else {std::cout << "成功寫入 " << data.size() << " 字節到 output.bin" << std::endl;}outfile.close();return 0;
}

data.data():獲取 data 字符串的指針,指向字符串的首字符。這是寫入的起始地址。
data.size():返回字符串 data 的長度,表示要寫入的字節數。
outfile.write(data.data(), data.size());:調用 write 函數,將從 data 指針開始的 data.size() 字節寫入 outfile 中。

輸出如下:
在這里插入圖片描述
說明:

  • 使用 write() 可以指定要寫入的數據地址和字節數,適用于二進制數據。

  • 確保文件以二進制模式打開,防止數據被意外轉換。

7. 一個實際使用的示例

讀取mysql中conf文件的配置:

bool ConnectionPool::loadConfigFile()
{//setenv("MYSQL_CONF_PATH","/home/kyros1ee/QtEnviroment/WeChat-main/chatserver/conf/mysql.conf",1);// 設置環境變量或絕對路徑const char* configPath = getenv("MYSQL_CONF");	//if (!configPath){LOG_ERROR << " mysql.conf MYSQL_CONF_PATH not set!";return false;}ifstream file(configPath);if (!file.is_open()){LOG_ERROR << "mysql.conf 文件不存在!";return false;}string line;while (getline(file, line)){// 忽略空行和注釋行if (line.empty() || line.find('=') == string::npos)continue;if (line.back() == '\r') {line.pop_back();}istringstream iss(line);string key, value;if (getline(iss, key, '=') && getline(iss, value)){// 去除可能存在的前后空白key = trim(key);value = trim(value);if (key == "ip") _ip = value;else if (key == "port") _port = stoi(value);else if (key == "username") _username = value;else if (key == "password") _password = value;else if (key == "dbname") _dbname = value;else if (key == "initSize") _initSize = stoi(value);else if (key == "maxSize") _maxSize = stoi(value);else if (key == "maxIdleTime") _maxIdleTime = stoi(value);else if (key == "connectionTime") _connectionTimeout = stoi(value);}}return true;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/80230.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/80230.shtml
英文地址,請注明出處:http://en.pswp.cn/web/80230.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【網絡安全】SQL注入

如果文章不足還請各位師傅批評指正&#xff01; 想象一下&#xff0c;你經營著一家咖啡店&#xff0c;顧客可以通過店內的點單系統下單。這個系統會根據顧客的輸入&#xff0c;向后廚發送指令&#xff0c;比如“為顧客A準備一杯拿鐵”。 然而&#xff0c;如果有個不懷好意的顧客…

解決Mawell1.29.2啟動SQLException: You have an error in your SQL syntax問題

問題背景 此前在openEuler24.03 LTS環境下的Hive使用了MySQL8.4.2&#xff0c;在此環境下再安裝并啟動Maxwell1.29.2時出現如下問題 [ERROR] Maxwell: SQLException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version f…

Oracle APEX IR報表列寬調整

目錄 1. 問題&#xff1a;如何調整Oracle APEX IR報表列寬 2. 解決辦法 1. 問題&#xff1a;如何調整Oracle APEX IR報表列寬 1-1. 防止因標題長而數據短&#xff0c;導致標題行的文字都立起來了&#xff0c;不好看。 1-2. 防止因數據太長而且中間還沒有空格&#xff0c;把列…

pytorch 14.3 Batch Normalization綜合調參實踐

文章目錄 一、Batch Normalization與Batch_size綜合調參二、復雜模型上的Batch_normalization表現1、BN對復雜模型&#xff08;sigmoid&#xff09;的影響2、模型復雜度對模型效果的影響3、BN對復雜模型&#xff08;tanh&#xff09;的影響 三、包含BN層的神經網絡的學習率優化…

Model.eval() 與 torch.no_grad() PyTorch 中的區別與應用

Model.eval() 與 torch.no_grad(): PyTorch 中的區別與應用 在 PyTorch 深度學習框架中&#xff0c;model.eval() 和 torch.no_grad() 是兩個在模型推理&#xff08;inference&#xff09;階段經常用到的函數&#xff0c;它們各自有著獨特的功能和應用場景。本文將詳細解析這兩…

Swagger go中文版本手冊

Swaggo(github.com/swaggo/swag)的注解語法是基于 OpenAPI 2.0 (以前稱為 Swagger 2.0) 規范的,并添加了一些自己的約定。 主要官方文檔: swaggo/swag GitHub 倉庫: 這是最權威的來源。 鏈接: https://github.com/swaggo/swag重點關注: README.md: 包含了基本的安裝、使用…

物聯網設備遠程管理:基于代理IP的安全固件更新通道方案

在物聯網設備遠程管理中&#xff0c;固件更新的安全性直接關系到設備功能穩定性和系統抗攻擊能力。結合代理IP技術與安全協議設計&#xff0c;可構建安全、高效的固件更新通道。 一、代理IP在固件更新中的核心作用 網絡層隱匿與路由優化 隱藏更新源服務器&#xff1a;通過代理I…

【C++重載操作符與轉換】句柄類與繼承

目錄 一、句柄類的基本概念 1.1 什么是句柄類 1.2 句柄類的設計動機 1.3 句柄類的基本結構 二、句柄類的實現方式 2.1 基于指針的句柄類 2.2 值語義的句柄類 2.3 引用計數的句柄類 三、句柄類與繼承的結合應用 3.1 實現多態容器 3.2 實現插件系統 3.3 實現狀態模式…

谷歌曾經的開放重定向漏洞(如今已經修復) -- noogle DefCamp 2024

題目描述: 上周&#xff0c;我決定創建自己的搜索引擎。這有點難&#xff0c;所以我背上了另一個。我也在8000端口上嘗試了一些東西。 未發現題目任何交互,但是存在一個加密js const _0x43a57f _0x22f9; (function(_0x3d7d57, _0x426e05) {const _0x16c3fa _0x22f9, _0x3187…

【C#】ToArray的使用

在 C# 中&#xff0c;ToArray 方法通常用于將實現了 IEnumerable<T> 接口的集合&#xff08;如 List<T>&#xff09;轉換為數組。這個方法是 LINQ 提供的一個擴展方法&#xff0c;位于 System.Linq 命名空間中。因此&#xff0c;在使用 ToArray 方法之前&#xff0…

資產管理平臺—chemex

1、簡介 Chemex CMDB&#xff08;Configuration Management Database&#xff09;是一個基于現代微服務架構的資產管理與自動化平臺&#xff0c;專為 IT 基礎設施與業務資產管理而設計。其核心目標是解決大規模系統運維中資產信息混亂、配置分散、數據不一致等問題&#xff0c…

【AI】mcp server是什么玩意兒

文章目錄 背景mcp server的必要性mcp server的基本概念mcp server的架構與核心組件總結 背景 劈里啪啦的整了一堆概念&#xff0c;對mcp server還是只停留在知道個詞的地步。 雖然目前大模型的對話生成能力很強&#xff0c;但是大模型&#xff08;如deepseek&#xff09;并不能…

c# 數據結構 樹篇 入門樹與二叉樹的一切

事先聲明,本文不適合對數據結構完全不懂的小白 請至少學會鏈表再閱讀 c# 數據結構 鏈表篇 有關單鏈表的一切_c# 鏈表-CSDN博客 數據結構理論先導:《數據結構&#xff08;C 語言描述&#xff09;》也許是全站最良心最通俗易懂最好看的數據結構課&#xff08;最遲每周五更新~~&am…

《Cookie Cutter》中2000多張精靈表與10000個2D光源的管理之道

一個小團隊如何在多個平臺上以優秀的效果展示手繪動畫&#xff1f;Subcult Joint 工作室給出了答案。他們用六年時間開發出了游戲《Cookie Cutter》。游戲中使用了數千個使用傳統動畫技術制作的高分辨率資產&#xff0c;而且這些資產都在 Unity 中進行了優化。由于工作室需要在…

什么是實景VR?實景VR應用場景

實景VR&#xff0c;即基于真實場景的虛擬現實技術&#xff0c;是利用計算機技術生成三維環境&#xff0c;以模擬并再現真實世界場景的技術。 用戶通過佩戴VR設備&#xff08;如VR頭盔、手柄等&#xff09;或通過電腦設備&#xff0c;可以沉浸在一個高度仿真的虛擬環境中&#…

內核性能測試(60s不丟包性能)

以xGAP-200-SE7K-L&#xff08;雙口10G&#xff09;在飛騰D2000上為例&#xff08;單通道最高性能約2.8Gbps) 單口測試 0口&#xff1a; tcp&#xff1a; taskset -c 4 iperf -c 1.1.1.1 -i 1 -t 60 -p 60001 taskset -c 4 iperf -s -i 1 -p 60001 udp&#xff1a; taskse…

58. 區間和

題目鏈接&#xff1a; 58. 區間和 題目描述&#xff1a; 給定一個整數數組 Array&#xff0c;請計算該數組在每個指定區間內元素的總和。 輸入描述 第一行輸入為整數數組 Array 的長度 n&#xff0c;接下來 n 行&#xff0c;每行一個整數&#xff0c;表示數組的元素。隨后…

C#進階(2)stack(棧)

前言 我們前面介紹了ArrayList,今天就介紹另一種數據結構——棧。 這是棧的基本形式,博主簡單畫了一下,你看個意思就行,很明顯,這種數據有一種特征:先進后出。因為先進來的數據會在下面,下面是密閉的,所以只能取后面進來的。 C#為我們封好了這種數據結構,我們不用擔…

汽車工廠數字孿生實時監控技術從數據采集到三維驅動實現

在工業智能制造推動下&#xff0c;數字孿生技術正成為制造業數字化轉型的核心驅動力。今天詳細介紹數字孿生實時監控技術在汽車工廠中的應用&#xff0c;重點解析從數據采集到三維驅動實現的全流程技術架構&#xff0c;并展示其在提升生產效率、降低成本和優化決策方面的顯著價…

git|gitee倉庫同步到github

參考&#xff1a;一次提交更新兩個倉庫&#xff0c;Get 更優雅的 GitHub/Gitee 倉庫鏡像同步 文章目錄 進入需要使用鏡像功能的倉庫&#xff0c;進入「管理」找到「倉庫鏡像管理」選項&#xff0c;點擊「添加鏡像」按鈕綁定github綁定成功后再次點擊添加鏡像如何申請 GitHub 私…