文章目录
- [1. C语言](#1. C语言)
-
- [1.1 打开并读取文件](#1.1 打开并读取文件)
- [1.2 写入文件](#1.2 写入文件)
- [1.3 读取二进制文件](#1.3 读取二进制文件)
- [1.4 写入二进制文件](#1.4 写入二进制文件)
- [1.5 文件指针的移动](#1.5 文件指针的移动)
- [2. C++](#2. C++)
-
- [2.1 包含头文件](#2.1 包含头文件)
- [2.2 打开文件](#2.2 打开文件)
- [2.3 检查文件是否成功打开](#2.3 检查文件是否成功打开)
- [2.4 读取文件](#2.4 读取文件)
- [2.5 写入文件](#2.5 写入文件)
- [2.6 关闭文件](#2.6 关闭文件)
- [2.7 文件指针的移动和获取位置](#2.7 文件指针的移动和获取位置)
- [2.8 实例](#2.8 实例)
- [3. C语言和C++文件打开模式](#3. C语言和C++文件打开模式)
- [4. MFC](#4. MFC)
-
- [4.1 头文件](#4.1 头文件)
- [4.2 打开文件](#4.2 打开文件)
- [4.3 写入文件](#4.3 写入文件)
- [4.4 读取文件](#4.4 读取文件)
- [4.5 关闭文件](#4.5 关闭文件)
1. C语言
在C语言中,文件访问是通过一系列标准库函数来完成的,这些函数被定义在stdio.h(标准输入输出库)头文件中。
文件的访问主要通过以下几个函数实现:
函数 | 说明 |
---|---|
fopen() | 打开一个文件 |
fclose() | 关闭一个文件 |
fread() | 读取文件 |
fwrite() | 写入文件 |
fseek() | 移动文件指针到指定位置 |
ftell() | 获取文件指针当前位置 |
fgetc() | 从文件中读取一个字符 |
fputc() | 写入一个字符到文件中 |
- Note:通过文件指针来实现文件的访问。
-
打开文件:
FILE *fopen(const char *filename, const char *mode);
此函数打开一个文件并返回一个文件指针,该文件指针可用于后续的文件操作。如果文件无法打开,则返回NULL。
- filename 是文件名(可以包含路径)。
- mode 是打开文件的模式,例如 "r"(只读)、"w"(只写,创建新文件或覆盖旧文件)、"a"(追加,写入数据到文件末尾)、"r+"(读写)等。
-
关闭文件:
int fclose(FILE *stream);
此函数关闭一个打开的文件。如果成功关闭文件,则返回0;否则返回EOF(一个定义在stdio.h中的特殊值,表示文件结束或发生错误)。
-
读取文件:
size_t fread(void *ptr, size_t size, size_t count, FILE *stream);
此函数从文件中读取数据。函数返回实际读取的数据项的数量,如果发生错误或到达文件末尾,则可能小于count。
- ptr 是一个指向内存块的指针,该内存块用于存储从文件中读取的数据。
- size 是每个数据项的大小(以字节为单位)。
- count 是要读取的数据项的数量。
- stream 是文件指针。
-
写入文件:
size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);
此函数将数据写入文件。函数返回实际写入的数据项的数量,如果发生错误,则可能小于count。
- ptr 是一个指向要写入文件的数据的指针。
- size、count 和 stream 的含义与fread相同。
-
文件定位:
int fseek(FILE *stream, long offset, int whence);
此函数设置文件位置指针。如果成功,则返回0;否则返回非零值。
- offset 是相对于whence指定的位置的偏移量(以字节为单位)。
- whence 可以是 SEEK_SET(文件开头)、SEEK_CUR(当前位置)或 SEEK_END(文件末尾)。
-
获取当前位置:
long ftell(FILE *stream);
此函数返回文件位置指针的当前位置(以字节为单位)。如果发生错误,则返回-1L。
-
检查文件结束:
int feof(FILE *stream);
此函数检查文件是否已到达末尾。如果到达末尾,则返回非零值;否则返回0。
-
清除文件结束和错误标志:
void clearerr(FILE *stream);
此函数清除与stream关联的文件结束和错误标志。
-
检查文件错误:
int ferror(FILE *stream);
此函数检查与stream关联的文件是否发生错误。如果发生错误,则返回非零值;否则返回0。
-
格式化输出或输入:
int fscanf(FILE *fp, char *format, ...);
int fprintf(FILE *fp, char *format, ...);
-
行输入和输出
char *fgets(char *line, int maxline, FILE *fp);
int fputs(char *line, FILE *fp);
1.1 打开并读取文件
cpp
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *file = fopen("test.txt", "r");
if (file == NULL) {
printf("无法打开文件\n");
return -1;
}
char ch;
while ((ch = fgetc(file)) != EOF) {
printf("%c", ch);
}
fclose(file);
return 0;
}
1.2 写入文件
cpp
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *file = fopen("test.txt", "w");
if (file == NULL) {
printf("无法打开文件\n");
return -1;
}
fputc('A', file);
fputc('B', file);
fclose(file);
return 0;
}
1.3 读取二进制文件
cpp
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int a;
char b;
} Data;
int main() {
FILE *file = fopen("test.bin", "rb");
if (file == NULL) {
printf("无法打开文件\n");
return -1;
}
Data data;
fread(&data, sizeof(Data), 1, file);
printf("a: %d, b: %c\n", data.a, data.b);
fclose(file);
return 0;
}
1.4 写入二进制文件
cpp
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int a;
char b;
} Data;
int main() {
FILE *file = fopen("test.bin", "wb");
if (file == NULL) {
printf("无法打开文件\n");
return -1;
}
Data data = {1, 'A'};
fwrite(&data, sizeof(Data), 1, file);
fclose(file);
return 0;
}
1.5 文件指针的移动
cpp
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *file = fopen("test.txt", "r");
if (file == NULL) {
printf("无法打开文件\n");
return -1;
}
fseek(file, 2, SEEK_SET); // 将文件指针移动到第3个字符的位置
printf("%c\n", fgetc(file));
fclose(file);
return 0;
}
2. C++
在C++中,文件访问与C语言非常相似,因为C++是在C语言的基础上构建的,并保留了C语言的大部分I/O功能。C++使用相同的文件操作函数,这些函数在(或<stdio.h>)头文件中定义。然而,C++还提供了自己的文件流类(如std::ifstream、std::ofstream和std::fstream),这些类位于头文件中,提供了更加面向对象的文件操作方式。
2.1 包含头文件
cpp
#include <fstream>
2.2 打开文件
使用 std::ifstream(输入文件流)或 std::ofstream(输出文件流)来打开文件。例如:
cpp
std::ifstream inputFile("input.txt"); // 打开文件以进行读取
std::ofstream outputFile("output.txt"); // 打开文件以进行写入
可以使用 std::fstream(文件流)来同时读取和写入文件。
2.3 检查文件是否成功打开
可以通过检查文件流对象是否有效来确认文件是否成功打开。
cpp
if (!inputFile) {
std::cerr << "无法打开文件\n";
return 1;
}
2.4 读取文件
使用 >> 运算符或 getline() 函数来从文件中读取数据。
cpp
int number;
inputFile >> number; // 读取一个整数
std::string line;
std::getline(inputFile, line); // 读取一行文本
2.5 写入文件
使用 << 运算符来将数据写入文件。
cpp
outputFile << "Hello, World!\n"; // 写入一行文本
outputFile << 42; // 写入一个整数
2.6 关闭文件
当文件流对象超出范围或被销毁时,文件会自动关闭。但是,你也可以显式地调用 close() 方法来关闭文件。
cpp
outputFile.close();
2.7 文件指针的移动和获取位置
使用 seekg()(对于输入流)和 seekp()(对于输出流)来移动文件指针。使用 tellg()(对于输入流)和 tellp()(对于输出流)来获取当前文件指针的位置。
cpp
inputFile.seekg(10, std::ios::beg); // 将输入文件的指针移动到第10个字节
std::streampos pos = inputFile.tellg(); // 获取当前输入文件的指针位置
2.8 实例
cpp
//读取文件
#include <fstream>
#include <iostream>
#include <string>
int main() {
std::ifstream file("test.txt"); // 打开文件以供读取
if (!file) { // 检查文件是否成功打开
std::cerr << "无法打开文件\n";
return 1;
}
std::string line;
// 逐行读取文件
while (std::getline(file, line)) {
std::cout << line << '\n';
}
file.close(); // 关闭文件
return 0;
}
cpp
//写入文件
#include <fstream>
#include <iostream>
int main() {
std::ofstream file("test.txt"); // 打开文件以供写入(如果文件不存在,则创建它)
if (!file) { // 检查文件是否成功打开
std::cerr << "无法打开文件\n";
return 1;
}
file << "Hello, World!" << std::endl; // 写入数据到文件
file.close(); // 关闭文件
return 0;
}
C++的文件流类同样支持二进制文件的读写。你可以通过文件流的binary模式标志来指定文件应以二进制模式打开。但是,在大多数系统中,这并不是必须的,因为文件流默认就是二进制安全的。然而,在某些情况下(特别是跨平台操作时),明确指定二进制模式可能是有必要的。
cpp
std::ifstream file("test.bin", std::ios::binary); // 以二进制模式打开文件
// ... 读取操作 ...
std::ofstream file("test.bin", std::ios::binary); // 以二进制模式打开文件
// ... 写入操作 ...
note:使用文件流类进行文件操作通常比使用C风格的函数更加直观和易于管理,因为它们提供了更丰富的错误处理和更面向对象的接口。此外,文件流还支持更多的操作,如格式化输入/输出、操纵符重载等.
3. C语言和C++文件打开模式
C++和C语言在文件打开模式上有很多相似之处,但由于C++提供了更高级的封装,其使用方式略有不同。以下是一个简化的表格,列出了C++和C语言中常用的文件打开模式:
模式 | 描述 | C++示例 | C示例 |
---|---|---|---|
"r" | 以只读方式打开文件,文件必须存在 | std::ifstream file("test.txt", std::ios::in); | FILE *file = fopen("test.txt", "r"); |
"w" | 以写入方式打开文件,如果文件不存在则创建新文件,如果文件已存在则清空内容 | std::ofstream file("test.txt", std::ios::out); | FILE *file = fopen("test.txt", "w"); |
"a" | 以追加方式打开文件,如果文件不存在则创建新文件,如果文件已存在则在文件末尾追加内容 | std::ofstream file("test.txt", std::ios::out/std::ios::app); | FILE *file = fopen("test.txt", "a"); |
"r+" | 以读写方式打开文件,文件必须存在 | std::fstream file("test.txt", std::ios::in/std::ios::out); | FILE *file = fopen("test.txt", "r+"); |
"w+" | 以写读方式打开文件,如果文件不存在则创建新文件,如果文件已存在则清空内容 | std::fstream file("test.txt", std::ios::in/std::ios::out/std::ios::trunc | FILE *file = fopen("test.txt", "w+"); |
"a+" | 以追加写读方式打开文件,如果文件不存在则创建新文件,如果文件已存在则在文件末尾追加内容 | std::fstream file("test.txt", std::ios::in /std::ios::out) | |
"b" | 以二进制模式打开文件(可以与上述模式组合使用) | std::ifstream file("test.bin", std::ios::in/std::ios::binary); |
4. MFC
在MFC(Microsoft Foundation Classes)中,CFile 类是一个用于文件操作的封装类,它提供了比标准C语言I/O函数更高级和面向对象的接口。使用 CFile 类,你可以更方便地打开、读取、写入和关闭文件。
4.1 头文件
cpp
#include <afxwin.h> // MFC 头文件
#include <afx.h> // 包含CFile类的定义
4.2 打开文件
cpp
CFile file(_T("example.txt"), CFile::modeCreate | CFile::modeWrite | CFile::shareExclusive);
if (!file.Open()) {
AfxMessageBox(_T("无法打开文件"));
return;
}
试图以创建(如果不存在)、写入和独占模式打开一个名为 example.txt 的文件。如果文件打开失败,显示一个消息框。
4.3 写入文件
cpp
CString str = _T("Hello, World!");
ULONGLONG pos = file.GetPosition(); // 获取当前文件指针位置
file.Write(str, (UINT)str.GetLength() * sizeof(TCHAR)); // 写入字符串到文件
file.Seek(pos, CFile::begin); // 如果需要,可以将文件指针移回原位
将一个字符串写入文件。Write 函数需要两个参数:要写入的数据的指针和要写入的数据的大小(以字节为单位)。
4.4 读取文件
cpp
ULONGLONG len = file.GetLength(); // 获取文件长度
if (len > 0) {
CFileException e;
char* buffer = new char[len];
try {
file.Read(buffer, len); // 读取整个文件
}
catch (CFileException* pEx) {
e = *pEx;
pEx->Delete();
// 处理异常
}
// 使用 buffer 中的数据...
delete[] buffer; // 释放内存
}
在这个例子中,我们首先获取文件的长度,然后分配足够的内存来存储整个文件的内容。我们使用 Read 函数来读取文件内容。注意,我们使用 CFileException 来处理可能发生的异常。
4.5 关闭文件
cpp
file.Close(); // 关闭文件
在完成文件操作后,使用 Close 函数关闭文件。虽然 CFile 的析构函数会自动关闭文件(如果尚未关闭),但显式关闭文件是一个好习惯。
MFC 主要用于Windows桌面应用程序的开发,并且依赖于Microsoft的Visual C++环境。如果你正在开发跨平台应用程序或不想依赖MFC,那么使用标准C++的 库可能是更好的选择。