文章目錄
- 0 檔案I/O操作
- 1 文本檔案
-
- 1.1 寫檔案
- 1.2 讀檔案
- 2 二進制檔案
-
- 2.1 寫檔案
- 2.2 讀檔案
0 檔案I/O操作
程式運作時産生的資料均為臨時資料,臨時資料會在程式執行完畢時被釋放。可通過檔案持久化資料。
注:C++中操作檔案時,需包含檔案流相關的頭檔案 <fstream>
。
檔案分類:
(1)
文本檔案
:檔案以文本的ASCII碼形式存儲;
(2)
二進制檔案
:檔案以文本的二進制形式存儲,使用者一般無法直接閱讀。
檔案操作的類:
(1)
ofstream
:寫操作(Output File Stream)
(2)
ifstream
:讀操作(Input File Stream)
(3)
fstream
:讀/寫操作(File Stream)
1 文本檔案
1.1 寫檔案
寫檔案的步驟:
(1)包含頭檔案:
#include <fstream>
(2)建立輸出流對象:
ofstream ofs;
(建立檔案輸出流對象)
(3)以指定路徑和方式打開檔案:
ofs.open("檔案路徑", 打開方式);
(4)通過檔案輸出流對象和
左移運算符<<
寫資料:
ofs << "寫入資料";
(5)關閉檔案:
ofs.close();
注:通過檔案輸出流類的構造函數,在建立檔案輸出流對象時指定檔案的路徑及打開方式,進而省略
ofstream
函數:
ofs.open("檔案路徑", 打開方式);
ofstream ofs("檔案路徑", 打開方式);
檔案打開方式:
打開方式 | 解釋 |
---|---|
ios::in | 讀檔案 |
ios::out | 寫檔案 |
ios::ate | 打開的初始位置:檔案尾 |
ios::app | 以追加方式寫檔案(追加寫) |
ios::trunc | 若檔案已存在,則先删除,再建立 |
ios::binary | 二進制方式 |
注:檔案打開方式可通過位或操作符
|
組合使用。
例:以二進制方式寫檔案:
。
ios::binary | ios:: out
文本檔案-寫操作總結:
(1)檔案操作必須包含頭檔案
<fstream>
;
(2)寫檔案可使用
ofstream
或
fstream
類;
(3)打開檔案時,需指定檔案路徑與打開方式;
(4)可通過檔案輸出流對象和
左移運算符<<
向檔案寫資料;
(5)操作完畢後,需要關閉檔案。
示例:文本檔案-寫操作
#include <iostream>
using namespace std;
#include <fstream> //1.包含檔案流相關的頭檔案
void writeTextFile() {
//2.建立檔案輸出流對象
ofstream ofs;
//3.以指定方式打開
ofs.open("test.txt",ios::out);
//4.寫内容
ofs << "姓名:Tom" << endl;
ofs << "時間:2021年2月14日" << endl;
//5.關閉檔案流對象
ofs.close();
}
int main() {
writeTextFile();
return 0;
}
1.2 讀檔案
讀檔案的步驟:
(1)包含頭檔案:
#include <fstream>
(2)建立輸入流對象:
ifstream ifs;
(建立檔案輸入流對象)
(3)以指定路徑和方式打開檔案,并判斷檔案是否打開成功:
打開檔案:
ifs.open("檔案路徑", 打開方式);
判斷檔案是否打開成功:
ifs.is_open()
(4)通過檔案輸入流對象,以4種方式讀資料:
①字元數組和
右移運算符>>
char buffer[1024] = {0}; //初始化字元數組
while(ifs >> buffer){
cout << buffer << endl;
}
②字元數組和ifstream類的成員函數
ifstream& getline(char *_Str, std::streamsize _Count)
ifstream::getline(字元數組緩沖區, 緩沖區大小)
char buffer[1024] = { 0 }; //初始化字元數組
while (ifs.getline(buffer, sizeof(buffer))) {
cout << buffer << endl;
}
③字元串和全局函數
getline(istream &_istr, string &_str)
getline(輸入流對象, 字元串)
string str;
while(getline(ifs, str)){
cout << str << endl;
}
④逐字元讀取、ifstream類的成員函數
get()
和
檔案結束符EOF
(end of file)【不建議】
注:逐字元讀取方式的效率較低,不建議使用。
char ch;
while ((ch = ifs.get()) != EOF) {
cout << ch;
}
(5)關閉檔案:
ifs.close();
判斷文本檔案内容是否為空(檔案存在):
讀取文本檔案的1個字元,判斷該字元是否為EOF标志。
(1)建立檔案輸入流對象:
ifstream ifs;
(2)讀取文本檔案的1個字元:
char ch;
ifs >> ch;
或
ch = ifs.get();
(3)判斷目前讀取的字元,是否已達檔案末尾(即
檔案結束符EOF
):
①使用檔案輸入流類的成員函數
bool ifstream::eof();
;
②判斷目前字元是否為
檔案結束符EOF
。
示例:判斷文本檔案内容是否為空
//方式1:檔案輸入流對象調用成員函數ifs.eof()
ifstream ifs(FILENAME, ios::in);
char ch;
ifs >> ch;
if(ifs.eof()){
cout << "文本檔案内容為空..." << endl;
}
//方式2:判斷目前字元是否為EOF檔案結束符
ifstream ifs(FILENAME, ios::in);
char ch;
if((ch = ifs.get()) == EOF){
cout << "文本檔案内容為空..." << endl;
}
文本檔案-讀操作總結:
(1)檔案操作必須包含頭檔案
<fstream>
;
(2)寫檔案可使用
ifstream
或
fstream
類;
(3)打開檔案後,應使用ifstream類的
is_open()
函數可以判斷檔案是否打開成功;
(4)操作完畢後,需要關閉檔案。
示例:文本檔案-讀操作
#include <iostream>
using namespace std;
#include <fstream> //1.包含檔案流相關的頭檔案
#include <string>
void readTextFile() {
//2.建立檔案輸入流對象
ifstream ifs;
//3.打開檔案,并判斷是否打開成功
ifs.open("test.txt", ios::in);
if (!ifs.is_open()) {
cout << "檔案打開失敗" << endl;
return;
}
//4.讀資料
//第1種:字元數組和右移運算符>>
//char buffer[1024] = { 0 }; //初始化字元數組
//while (ifs >> buffer) {
// cout << buffer << endl;
//}
//第2種:字元數組和istream類成員函數getline()
//char buffer[1024] = { 0 }; //初始化字元數組
//while (ifs.getline(buffer, sizeof(buffer))) {
// cout << buffer << endl;
//}
//第3種:字元串和全局函數getline()
string str;
while(getline(ifs, str)){
cout << str << endl;
}
//第4種:按字元讀取和EOF檔案尾标志(end of file)【不建議】
//char ch;
//while ((ch = ifs.get()) != EOF) {
// cout << ch;
//}
//5.關閉檔案
ifs.close();
}
int main() {
readTextFile();
return 0;
}
2 二進制檔案
以二進制的方式對檔案進行讀寫操作,
open()函數
中的打開方式需額外使用
ios::binary
。
2.1 寫檔案
二進制方式的寫檔案,通過檔案輸出流對象
ofstream ofs;
調用成員函數
write()
。
函數原型 :
ostream& write(const char* buffer, int len);
參數解釋:字元指針
buffer
指向的記憶體位址;
len
為讀寫的位元組數。
注1:以二進制方式寫檔案時,支援寫入自定義資料類型,需将自定義資料類型對象的位址(如)強轉為
Object *
const char *
類型。
例:
ofs.write((const char*) &obj, sizeof(obj));
注2:二進制寫操作的檔案,内容可能顯示為亂碼,需使用二進制的讀操作解析。
注3:通過檔案輸出流類
的構造函數,在建立檔案輸出流對象時指定檔案的路徑及打開方式,進而省略
ofstream
函數:
ofs.open("檔案路徑", 打開方式);
ofstream ofs("檔案路徑", 打開方式);
示例:二進制方式寫入自定義資料類型
#include <iostream>
using namespace std;
#include <fstream> //1.包含檔案流相關的頭檔案
//自定義資料類型
class Student{
public:
char name[32];
int score;
};
int main() {
/*
//2.建立檔案輸出流對象
ofstream ofs;
//3.以二進制方式打開檔案,并執行寫操作
ofs.open("student.txt", ios::binary | ios::out);
*/
//簡化寫法
/* 通過輸出流類ofstream的構造函數,建立對象時指定檔案路徑及打開方式 */
ofstream ofs("student.txt", ios::binary | ios::out);
//4.寫檔案
Student stu = {"Tom", 99 };
//将自定義的資料類型指針,強轉為const char*
ofs.write((const char*)&stu, sizeof(stu));
//5.關閉檔案
ofs.close();
return 0;
}
2.2 讀檔案
二進制方式的讀檔案,通過檔案輸入流對象
ifstream ifs;
調用成員函數
read()
。
函數原型 :
istream& read(char* buffer, int len);
參數解釋:字元指針
buffer
指向的記憶體位址;
len
為讀寫的位元組數。
注1:以二進制方式讀檔案時,支援讀取自定義資料類型,需将自定義資料類型對象的位址(如)強轉為
Object *
char *
類型。
例:
注2:打開檔案後,應使用ifstream類的
ifs.read((char*) &obj, sizeof(obj));
函數可以判斷檔案是否打開成功。
is_open()
示例:二進制方式讀取自定義資料類型
#include <iostream>
using namespace std;
#include <fstream> //1.包含檔案流相關的頭檔案
//自定義資料類型
class Student {
public:
char name[32];
int score;
};
int main() {
/*
//2.建立輸入流對象
ifstream ifs;
//3.打開檔案并判斷是否打開成功
ifs.open("student.txt", ios::binary | ios::in);
*/
//簡化寫法
/* 通過輸出流類ofstream的構造函數,建立對象時指定檔案路徑及打開方式 */
ifstream ifs("student.txt", ios::binary | ios::in);
if (!ifs.is_open()) {
cout << "檔案打開失敗..." << endl;
return 0;
}
//4.讀檔案
Student stu;
ifs.read((char*)&stu, sizeof(stu));
cout << "姓名:" << stu.name << endl;
cout << "成績:" << stu.score << endl;
//5.關閉檔案
ifs.close();
return 0;
}