品牌网站建设设计公司,网络型网站分为,手游网站怎么做的,凡客诚品是什么文件比较和文件流 一、文本比较工具 diff1.基本用法1.1输出格式 2.常用选项 二、文件流1.文件的打开模式2.文件流的分类ifstreamofstreamfstrem区别 3.文件流的函数1. 构造函数2. is_open 用于判断文件是否打开3. open4. getline5. close6. get()7. read8. write9. put10. gcou… 文件比较和文件流 一、文本比较工具 diff1.基本用法1.1输出格式 2.常用选项 二、文件流1.文件的打开模式2.文件流的分类ifstreamofstreamfstrem区别 3.文件流的函数1. 构造函数2. is_open 用于判断文件是否打开3. open4. getline5. close6. get()7. read8. write9. put10. gcount11. seekg12. peek13. ignore14. 文件流状态检查函数 一、文本比较工具 diff
diff 是 文件和内容比较工具主要用于比较文件的差异、跟踪修改以及生成补丁。这类工具可以比较文本文件、二进制文件、目录结构等广泛用于开发、配置管理和系统运维中
1.基本用法
diff file1 file2 比较两个文件的差异输出显示如何将 文件1 转换为 文件2以最小的编辑操作实现
1.1输出格式
diff 的输出结果以 行号 和 更改说明 表示
表示 文件1 中的内容。表示第一个文件独有的行表示 文件2 中的内容。表示第二个文件独有的行
[行号]动作[行号]文件1中的行
---文件2中的行动作:aadd添加操作将内容从 文件2 添加到 文件1。ddelete删除操作从 文件1 中删除内容。cchange修改操作将 文件1 的内容替换为 文件2 的内容。2.常用选项
-u生成统一格式(unified format)的输出更易读
-r递归比较目录
-i忽略大小写差异
-w忽略空白字符差异
-b忽略空行差异
-y以并排显示模式输出其中| 表示此行有差异
--suppress-common-lines隐藏相同的行
可以生成补丁文件用于修改diff -u file1 file2 patch.diff
#应用补丁 //file2是新文件通过patch.diff的修改给了file1patch file1.txt patch.diff
#撤销补丁使用R关键字patch -R file1.txt patch.diff二、文件流
C的文件流头文件fstream允许程序通过文件进行输入读取数据和输出写入数据。它是 I/O 流库的一部分主要通过 fstream 类和相关子类来实现。
1.文件的打开模式
它们之间可以组合使用
打开模式描述std::ios::in打开文件以进行输入读取默认用于 ifstream。如果文件不存在则操作失败。std::ios::out打开文件以进行输出写入默认用于 ofstream。如果文件不存在则创建新文件如果存在则清空内容。std::ios::app打开文件以追加内容到文件末尾。写入的数据保留原内容不会清空文件。std::ios::ate打开文件并将文件指针定位到文件末尾可同时进行读写操作。std::ios::trunc如果文件已存在清空其内容默认用于 ofstream仅在与 std::ios::out 结合使用时生效。std::ios::binary以二进制模式打开文件而非文本模式。数据读写时不会进行格式转换。std::ios::in | std::ios::out以读写模式打开文件允许同时进行读取和写入操作。std::ios::out | std::ios::app打开文件以追加模式写入保留文件原内容仅在末尾追加。std::ios::in | std::ios::binary以二进制模式打开文件并读取数据。
2.文件流的分类
ifstream
输入文件流用于从文件中读取数据。
ofstream
输出文件流用于向文件中写入数据。
fstrem
文件流同时支持从文件读取数据和向文件写入数据ifstream 和 ofstream 的结合。
区别
虽然 std::fstream 是通用的文件流可以替代 std::ifstream 和 std::ofstream但后两者的存在有以下好处 - 明确性更清楚地表达代码的意图。 - 简洁性减少代码复杂度减少模式设置的错误。 - 效率性为单一任务设计内部更优化。 - 降低误用风险避免由于未正确指定模式导致的运行时错误。
3.文件流的函数
1. 构造函数
explicit ifstream(const char* filename, ios_base::openmode mode ios_base::in);
explicit ofstream(const char* filename, ios_base::openmode mode ios_base::out);
explicit fstream(const char* filename, ios_base::openmode mode ios_base::in | ios_base::out);示例std::ofstream outfile(example.txt, std::ios::out); // ofstream outfile(example.txt); /*std::ofstream outfile;outfile.open(example.txt,std::ios::out);//outfile.open(example.txt);*/std::ifstream infile(example.txt, std::ios::in); // ifstream infile(example.txt); /*std::ifstream infile;infile.open(example.txt, std::ios::in); // infile.open(example.txt);*/std::fstream file(example.txt, std::ios::in | std::ios::out); // fstream file(example.txt, ios::in | ios::out); /*fstream 必须显式指定打开模式不能省略 ios::in | ios::out。std::fstream file;file.open(example.txt, std::ios::in | std::ios::out); */2. is_open 用于判断文件是否打开
bool is_open() const;
返回值返回 true文件成功打开且未关闭返回 false文件未打开或已关闭用法// 场景1检查文件是否成功打开if (!infile.is_open()) {std::cerr 无法打开文件 std::endl;return -1;
}// 场景2循环读取多个文件
std::vectorstd::string filenames {file1.txt, file2.txt, file3.txt};
for (const auto filename : filenames) {std::ifstream file(filename);if (!file.is_open()) {std::cerr 无法打开文件: filename std::endl;continue; // 跳过这个文件继续处理下一个}// 处理文件...file.close();
}3. open
类似于标准文件打开
void open(const char* filename, ios_base::openmode mode ios_base::in | ios_base::out);
// 或
void open(const string filename, ios_base::openmode mode ios_base::in | ios_base::out);打开模式有如上表
示例fstream file;file.open(test.txt, ios::out | ios::in);4. getline
getline函数用于从输入流中读取一行文本
// 形式1从输入流读取到string
istream getline(istream is, string str, char delim \n);// 形式2从输入流读取到字符数组
istream getline(istream is, char* str, streamsize n, char delim \n);
参数说明is: 输入流(如cin或文件流)str: 存储读取内容的字符串或字符数组delim: 分隔符(默认为换行符\n)n: 最多读取的字符数(用于字符数组形式)
示例:// 1. 从标准输入读取一行string line;getline(std::cin, line);// 2. 使用自定义分隔符string data;getline(cin, data, ,); // 以逗号为分隔符// 3. 从文件读取所有行ifstream file(test.txt);string textLine;while (getline(file, textLine)) {cout textLine endl;}// 返回引用允许我们进行链式操作
string line1, line2;
getline(getline(cin, line1), line2); // 连续读取两行
5. close
关闭文件流
#include fstream
using namespace std;int main() {ofstream file(test.txt);// 文件操作...file.close(); // 关闭文件return 0;
}
void processFile() {fstream file(test.txt); // 打开文件// 文件操作...// 不需要显式调用close()// 当file离开作用域时会自动关闭
} // 自动调用析构函数关闭文件6. get()
// 主要的几种形式
int get(); // 形式1读取单个字符
istream get(char ch); // 形式2读取到字符引用
istream get(char* str, streamsize n); // 形式3读取到字符数组
istream get(char* str, streamsize n, char delim); // 形式4带分隔符读取示例// 逐字符读取文件
void readFileChar() {ifstream file(test.txt);char ch;while (file.get(ch)) {cout ch;}file.close();
}// 读取到特定字符为止
void readUntilChar(char delim) {char buffer[1024];cin.get(buffer, sizeof(buffer), delim);cout Read: buffer endl;
}// 处理二进制数据
void processBinaryData() {ifstream file(data.bin, ios::binary);char byte;while (file.get(byte)) {// 处理每个字节processBytes(byte);}
}
// 高效的文件读取
void efficientReading() {ifstream file(largefile.txt);constexpr size_t BUFFER_SIZE 4096;char buffer[BUFFER_SIZE];while (file) {file.get(buffer, BUFFER_SIZE);// 处理buffer中的数据}
}get()函数保留分隔符在流中读取字符数组时要注意留出空间给结束符’\0’
7. read
read 函数是一个重要的成员函数用于以 二进制模式从文件中读取固定数量的字节。它非常适合处理 非文本文件如图片、音频或需要高效读取大量数据的场景
istream read(char* buffer, streamsize count);char* buffer缓冲区的大小必须至少为 count否则可能导致溢出。一个指向目标缓冲区的指针读取的数据将存储在这个缓冲区中。streamsize count表示要从文件中读取的字节数。类型为 std::streamsize通常是一个有符号整数类型。
返回值返回对输入流对象的引用istream支持链式操作。如果读取成功流的状态仍然有效如果读取失败如到达文件末尾流的状态会变为 失败状态。
示例int main() {ifstream file(test.bin, ios::binary);char buffer[100];// 读取100字节file.read(buffer, 100);// 检查实际读取的字节数cout 读取了 file.gcount() 字节 endl;file.close();return 0;
}
读取结构体struct Student {char name[50];int age;double score;
};void readStudentData() {ifstream file(students.dat, ios::binary);Student student;// 读取整个结构体file.read(reinterpret_castchar*(student), sizeof(Student));cout 姓名: student.name endl;cout 年龄: student.age endl;cout 分数: student.score endl;
}
// 读取大文件
void readLargeFile(const string filename) {ifstream file(filename, ios::binary);constexpr size_t BUFFER_SIZE 4096;char buffer[BUFFER_SIZE];while (file) {file.read(buffer, BUFFER_SIZE);streamsize bytesRead file.gcount();if (bytesRead 0) {// 处理读取的数据processData(buffer, bytesRead);}}
}// 读取数组
void readArray() {ifstream file(numbers.dat, ios::binary);int numbers[100];file.read(reinterpret_castchar*(numbers), sizeof(int) * 100);
}// 读取固定大小的记录
struct Record {int id;char data[256];
};void readRecord(int position) {ifstream file(records.dat, ios::binary);Record record;// 定位到特定记录file.seekg(position * sizeof(Record));file.read(reinterpret_castchar*(record), sizeof(Record));
}8. write
write() 函数是一个用于二进制写入的低级函数它属于 ostream 类(因此也被 ofstream 继承)。
ostream write(const char* buffer, streamsize count);
参数buffer指向要写入数据的字符缓冲区count要写入的字节数返回对流对象的引用支持链式操作按照原始二进制格式写入不进行任何转换
示例
//写入字符串
ofstream file(test.bin, ios::binary);
const char* str Hello;
file.write(str, 5); // 写入5个字节//写入数值
int number 42;
file.write(reinterpret_castconst char*(number), sizeof(number));//写入结构体
struct Person {char name[20];int age;
};Person person {John, 25};
file.write(reinterpret_castconst char*(person), sizeof(Person));//写入数组
int arr[] {1, 2, 3, 4, 5};
file.write(reinterpret_castconst char*(arr), sizeof(arr));//图像文件处理class ImageProcessor {struct BMPHeader {char signature[2];uint32_t fileSize;uint32_t reserved;uint32_t dataOffset;// ... 其他头部信息};public:static void convertToBW(const std::string filename) {std::fstream file(filename, std::ios::binary | std::ios::in | std::ios::out);BMPHeader header;file.read(reinterpret_castchar*(header), sizeof(header));// 定位到图像数据file.seekg(header.dataOffset);std::vectorunsigned char pixels;pixels.resize((header.fileSize - header.dataOffset));file.read(reinterpret_castchar*(pixels.data()), pixels.size());// 转换为黑白for (size_t i 0; i pixels.size(); i 3) {unsigned char gray (pixels[i] pixels[i1] pixels[i2]) / 3;pixels[i] pixels[i1] pixels[i2] gray;}// 写回文件file.seekp(header.dataOffset);file.write(reinterpret_castchar*(pixels.data()), pixels.size());}
};9. put
put() 函数用于写入单个字符属于 ostream 类
ostream put(char ch);
参数ch要写入的字符返回对流对象的引用支持链式操作
示例
//写入单个字符
ofstream file(test.txt);
file.put(A);//链式写入多个字符
file.put(H).put(i).put(!);//配合循环使用
const char* str Hello;
for(int i 0; str[i]; i) {file.put(str[i]);
}//写入特殊字符
file.put(\n); // 换行符
file.put(\t); // 制表符10. gcount
gcount() 函数返回上一次输入操作读取的字符数属于 istream 类
treamsize gcount() const;
参数返回值返回上一次读取操作实际读取的字符数
示例
//基本使用
ifstream file(test.txt);
char buffer[100];
file.read(buffer, 100);
cout 读取了 file.gcount() 个字符 endl;//配合getline使用
string line;
getline(file, line);
cout 本行读取了 file.gcount() 个字符 endl;//错误检查
if (file.read(buffer, 100) file.gcount() 0) {cout 成功读取数据 endl;
}//读取整个文件
ifstream file(data.bin, ios::binary);
vectorchar data;
while (file.read(buffer, sizeof(buffer))) {data.insert(data.end(), buffer, buffer file.gcount());
}11. seekg
seekg() 函数用于设置输入流的读取位置属于 istream 类
istream seekg(streampos pos); // 绝对定位
istream seekg(streamoff off, ios_base::seekdir way); // 相对定位
参数pos新的绝对位置off相对偏移量way移动方向ios::beg开头ios::cur当前ios::end末尾
示例
//移动到文件开头
ifstream file(test.bin, ios::binary);
file.seekg(0, ios::beg);//移动到文件末尾
file.seekg(0, ios::end);//获取文件大小
file.seekg(0, ios::end);
streampos fileSize file.tellg();
file.seekg(0, ios::beg);//跳过文件头
struct Header {int version;int dataSize;
};
file.seekg(sizeof(Header), ios::beg);//读取文件中间的数据块
file.seekg(1024, ios::beg); // 跳过前1024字节
char buffer[256];
file.read(buffer, 256);//在文件中来回移动
int pos file.tellg(); // 保存当前位置
file.seekg(100, ios::cur); // 向前移动100字节
file.seekg(pos); // 返回之前的位置12. peek
peek() 函数用于查看输入流中的下一个字符但不从流中提取它
int peek();
返回值成功返回下一个要读取的字符失败返回 EOF不移动流位置指针示例
//基本使用
ifstream file(test.txt);
char next file.peek();
cout 下一个字符是: next endl;//用于判断行尾
while (file.peek() ! EOF file.peek() ! \n) {char ch;file.get(ch);cout ch;
}//检查数字开头
if (isdigit(file.peek())) {int number;file number;
}//格式化读取示例
class Parser {
public:static void parseData(istream input) {while (input.peek() ! EOF) {// 跳过空白字符while (isspace(input.peek())) {input.ignore();}if (isdigit(input.peek())) {int num;input num;cout Found number: num endl;}else if (isalpha(input.peek())) {string word;input word;cout Found word: word endl;}}}
};13. ignore
ignore() 函数用于跳过输入流中的字符
istream ignore(streamsize n 1, int delim EOF);
参数n: 要忽略的最大字符数默认为1delim: 分隔符读到这个字符就停止默认为EOF返回对流的引用示例
//忽略单个字符
ifstream file(test.txt);
file.ignore(); // 跳过一个字符//忽略整行
file.ignore(numeric_limitsstreamsize::max(), \n);//跳过特定字符前的所有内容
file.ignore(numeric_limitsstreamsize::max(), :);//清除缓冲区
cin.ignore(numeric_limitsstreamsize::max(), \n);//处理CSV文件示例
class CSVParser {
public:static vectorstring parseLine(istream input) {vectorstring fields;string field;while (input.peek() ! EOF input.peek() ! \n) {if (input.peek() ,) {input.ignore(); // 跳过逗号fields.push_back(field);field.clear();}else {char ch;input.get(ch);field ch;}}if (!field.empty()) {fields.push_back(field);}input.ignore(); // 跳过换行符return fields;}
};//配合peek()实现高级解析
class DataParser {
public:static void parseStructuredData(istream input) {while (input.peek() ! EOF) {// 跳过注释行if (input.peek() #) {input.ignore(numeric_limitsstreamsize::max(), \n);continue;}// 处理数据行string data;getline(input, data);processData(data);}}static void skipWhitespace(istream input) {while (input.peek() ! EOF isspace(input.peek())) {input.ignore();}}static string readToken(istream input) {skipWhitespace(input);string token;while (input.peek() ! EOF !isspace(input.peek())) {char ch;input.get(ch);token ch;}return token;}
};14. 文件流状态检查函数
返回值都是bool类型
good() 检查流是否处于良好状态没有错误。
eof() 检查是否到达文件末尾。
fail() 检查是否发生了文件流错误如文件打开失败。
bad() 检查是否发生了严重错误如硬件故障。
clear() 清除流的所有错误状态标志。
//基本检查
ifstream file(data.txt);
if (file.good()) {cout 文件流状态正常 endl;
}
//读取整个文件
ifstream file(input.txt);
string content;
while (!file.eof()) {char ch;file.get(ch);if (!file.eof()) { // 重要避免重复最后一个字符content ch;}
}
//文件打开检查
ifstream file(config.txt);
if (file.fail()) {cerr 无法打开配置文件 endl;return;
}//类型转换错误检查
int number;
cin number;
if (cin.fail()) {cerr 输入的不是有效数字 endl;cin.clear(); // 清除错误状态cin.ignore(numeric_limitsstreamsize::max(), \n); // 清除错误输入
}
//硬件错误检查
ofstream file(data.dat, ios::binary);
file.write(data, size);
if (file.bad()) {cerr 发生严重的I/O错误 endl;return;
}
//基本使用
ifstream file(data.txt);
if (file.fail()) {file.clear(); // 清除错误状态
}//恢复流状态
class StreamResetter {
public:static void resetStream(istream stream) {stream.clear(); // 清除所有错误标志stream.seekg(0, ios::beg); // 重置读取位置}
};