最近總在做文件讀入和寫出的事,索性來總結一下C/C++將內容寫入文件的方法吧。本篇分為C和C++兩種方式,C的方法有些單調,畢竟沒有庫函數。C++則豐富些,下面我把搜集到的整理一下,供大家參考。
目錄
一、C語言輸出內容到文件
使用 C 的文件 I/O 函數,例如 fopen(),(),fputs() 和 () 等。這些函數由 C 語言中的標準庫 stdio.h 提供。
#include
int main()
{
// 以寫入模式打開文件
FILE *fp = fopen("myfile.txt", "w");
if (fp == NULL)
{
// 打開文件失敗
printf("Error opening file!\n");
return 1;
}
// 使用 fprintf() 寫入字符串
fprintf(fp, "Hello, world!\n");
// 使用 fputs() 寫入字符串
fputs("This is another string.\n", fp);
// 使用 fwrite() 寫入二進制數據
int num = 42;
fwrite(&num, sizeof(int), 1, fp);
// 關閉文件
fclose(fp);
return 0;
}
在這個代碼示例中,我們首先使用 fopen() 函數以寫入模式打開了一個文件,然后使用 (),fputs() 和 () 向文件寫入了字符串和二進制數據,最后使用 () 函數關閉了文件。請注意,在使用 () 函數寫入二進制數據時,我們需要提供要寫入的數據的指針,以及每個數據單元的大小和要寫入的數據單元數。
二、C++文件輸入/輸出流
此種是C++標準的輸入輸出,一般不會帶來字符種類不同引發的問題,比如寬字節和窄字節之間的區別,肯能我們打開文件內容都一樣,但是涉及加密、編碼等操作寬窄字符是有區別的,這個是有教訓的,牢記。
下面是使用 C++ 中的文件輸入/輸出流的代碼示例:
#include
#include
int main()
{
// 以寫入模式打開文件
std::ofstream out("myfile.txt");
if (!out)
{
// 打開文件失敗
std::cerr << "Error opening file!" << std::endl;
return 1;
}
// 使用流操作符 << 寫入字符串
out << "Hello, world!" << std::endl;
out << "This is another string." << std::endl;
// 使用 write() 寫入二進制數據
int num = 42;
out.write(reinterpret_cast(&num), sizeof(int));
// 關閉文件
out.close();
// 以讀取模式打開文件
std::ifstream in("myfile.txt");
if (!in)
{
// 打開文件失敗
std::cerr << "Error opening file!" << std::endl;
return 1;
}

// 使用流操作符 >> 讀取字符串
std::string s;
in >> s;
std::cout << s << std::endl;
// 使用 read() 讀取二進制數據
in.read(reinterpret_cast(&num), sizeof(int));
std::cout << num << std::endl;
// 關閉文件
in.close();
return 0;
}
在這個代碼示例中,我們首先使用 對象以寫入模式打開了一個文件,然后使用流操作符 > 讀取了字符串,使用 read()讀取了二進制數據,最后使用 close() 關閉了文件。
請注意將文件內容輸出到屏幕,當使用 write() 寫入二進制數據時,我們需要將要寫入的數據的指針轉換為 char* 類型,并提供每個數據單元的大小和要寫入的數據單元數。當使用 read() 讀取二進制數據時,我們也需要將要讀取的數據的指針轉換為 char* 類型,并提供每個數據單元的大小和要讀取的數據單元數。
另一個 C++ 標準庫中的文件輸入/輸出流類型叫做 ,它可以通過標準輸入/輸出流來讀寫文件。例如,下面是使用 的代碼示例:
#include
#include
int main()
{
// 以寫入模式打開文件
std::filebuf fb;
fb.open("myfile.txt", std::ios::out);
if (!fb.is_open())
{
// 打開文件失敗
std::cerr << "Error opening file!" << std::endl;
return 1;
}
// 將文件緩沖區關聯到標準輸出流
std::ostream out(&fb);

// 使用標準輸出流寫入字符串
out << "Hello, world!" << std::endl;
out << "This is another string." << std::endl;
// 使用 sputn() 寫入二進制數據
int num = 42;
fb.sputn(reinterpret_cast(&num), sizeof(int));
// 關閉文件
fb.close();
// 以讀取模式打開文件
fb.open("myfile.txt", std::ios::in);
if (!fb.is_open())
{
// 打開文件失敗
std::cerr << "Error opening file!" << std::endl;
return 1;
}
// 將文件緩沖區關聯到標準輸入流
std::istream in(&fb);
// 使用標準輸入流讀取字符串
std::string s;
in >> s;
std::cout << s << std::endl;
// 使用 sgetn() 讀取二進制數據
fb.sgetn(reinterpret_cast(&num), sizeof(int));
std::cout << num << std::endl;
// 關閉文件
fb.close();

return 0;
}
在這個代碼示例中,我們首先使用 對象以寫入模式打開了一個文件,然后將文件緩沖區關聯到標準輸出流,使用標準輸出流寫入字符串,使用 sputn() 寫入了二進制數據,最后使用 close() 關閉了文件。然后,我們使用 對象以讀取模式打開了同一個文件,將文件緩沖區關聯到標準輸入流,使用標準輸入流讀取字符串,使用 sgetn() 讀取了二進制數據,最后使用 close() 關閉了文件。 請注意,當使用 sputn() 寫入二進制數據時,我們需要將要寫入的數據的指針轉換為 char* 類型,并提供每個數據單元的大小和要寫入的數據單元數。當使用 sgetn() 讀取二進制數據時,我們也需要將要讀取的數據的指針轉換為 char* 類型,并提供每個數據單元的大小和要讀取的數據單元數。希望這些代碼示例能幫助您理解 C++ 中的文件輸入/輸出流的使用方法。
三、文件輸入/輸出流迭代器
你是不是曾經有這樣的煩惱,想將數組或者一堆類型一樣的數據寫入文件,for循環太麻煩。其實,要想簡單有個前提,就是你的數據支持迭代器,例如這種類型,C++內部對其實現了迭代功能(),那么將數據一個一個寫入非常方便。
在使用文件輸入/輸出流迭代器之前,你需要先包含下面的頭文件:
#include
#include
然后,你可以使用下面的代碼來寫入數據到文件,這段代碼會將 data 中的數據寫入到文件 ".txt" 中,并在每個數據之間添加一個空格:
std::ofstream out_file("output.txt");
std::ostream_iterator out_iter(out_file, " ");
std::vector data = {1, 2, 3, 4, 5};
std::copy(data.begin(), data.end(), out_iter);
out_file.close();
讀取文件中的數據也很簡單,可以使用下面的代碼,這段代碼會從文件 "input.txt" 中讀取數據將文件內容輸出到屏幕,并將數據存儲在 中。文件輸入/輸出流迭代器很方便,因為它們可以像使用普通迭代器一樣使用,可以很容易地編寫模板代碼。
四、C++ 中的文件輸入/輸出流緩沖區
首先,你需要包含下面的頭文件:
#include
#include
接下來,你可以使用下面的代碼來寫入數據到文件:
std::ofstream out_file("output.txt");
std::streambuf* buf = out_file.rdbuf();
int data = 123;
buf->sputn((char*)&data, sizeof(int));
out_file.close();
上面這段代碼會將數據 123 寫入到文件 ".txt" 中。
讀取文件中的數據也很簡單,可以使用下面的代碼:
std::ifstream in_file("input.txt");
std::streambuf* buf = in_file.rdbuf();
int data;
buf->sgetn((char*)&data, sizeof(int));
in_file.close();
上面這段代碼會從文件 "input.txt" 中讀取一個整數,并將它存儲在變量 data 中。
使用文件輸入/輸出流緩沖區可以直接操縱底層文件描述符,這使得你可以實現更底層的文件操作。但是,這也意味著你需要自己處理底層細節,比如字節序轉換等等小問題。
五、C++ 中的文件輸入/輸出流預定義的操縱符
頭文件:
#include
#include
接下來,你可以使用下面的代碼來寫入數據到文件,這段代碼會將數據 123 寫入到文件 ".txt" 中,并在末尾添加一個換行符。
std::ofstream out_file("output.txt");
int data = 123;
out_file << data << std::endl;
out_file.close();
你也可以使用 std::flush 操縱符來立即刷新文件輸出緩沖區,例如:
std::ofstream out_file("output.txt");
int data = 123;
out_file << data << std::flush;
out_file.close();
這段代碼會將數據 123 寫入到文件 ".txt" 中,并立即刷新文件輸出緩沖區。
這種方法實在喜歡不起來,搞不懂他在干什么,有大神來給我解答一下吧。
六、 api
api寫和讀之前的博客有寫過,先然后、。這個會帶來寬字符問題,具體原因尚不清楚,慎用。貼個鏈接吧。
七、總結