C++作为一门入门容易,精通难的语言,具有许多丰富多彩的用法,但是也许不能找到相应的算法题,随开本篇博客进行记录,长期更新,共勉!
目录
1.文件操作<fstream>
当然,更简单的方法是利用命令行中的重定向来进行文件的读入和读取,比如一个test.exe文件,我们可以让命令行转移到此根目录下,然后使用test.exe < in.txt > out.txt命令来重定向文件输入和文件输出,不过,这里将要介绍的是<fstream>这个头文件。
cpp
#include <fstream>
struct Data {
int id;
double value;
};
int main() {
Data data = {1, 3.14};
// 写入 data 到文件
std::ofstream outfile("data.bin", std::ios::binary);
if (outfile) {
outfile.write(reinterpret_cast<const char*>(&data), sizeof(Data));
outfile.close();
}
// 从文件读取 data
Data readData;
std::ifstream infile("data.bin", std::ios::binary);
if (infile) {
infile.read(reinterpret_cast<char*>(&readData), sizeof(Data));
infile.close();
}
return 0;
}
cpp
#include <fstream>
#include <iostream>
int main() {
// 使用 put() 写入文件
std::ofstream outfile("example.txt");
if (outfile) {
outfile.put('A');
outfile.close();
}
// 使用 get() 读取文件
std::ifstream infile("example.txt");
if (infile) {
char c;
infile.get(c); // 读取一个字符
std::cout << "Read from file: " << c << std::endl;
infile.close();
}
return 0;
}
cpp
#include <fstream>
#include <iostream>
int main() {
std::fstream file("example.bin", std::ios::binary | std::ios::in | std::ios::out);
// 写入数据
if (file) {
file.write("Hello, World!", 13);
}
// 移动到文件开始
file.seekg(0);
// 读取数据
char buffer[14] = {};
if (file) {
file.read(buffer, 13);
std::cout << "Read from file: " << buffer << std::endl;
}
file.close();
return 0;
}
cpp
#include <fstream>
#include <iostream>
int main() {
std::fstream file("example.bin", std::ios::binary | std::ios::in | std::ios::out | std::ios::app);
// 写入数据并获取写入位置
file.write("Hello, World!", 13);
std::streampos writePos = file.tellp();
std::cout << "Write position: " << writePos << std::endl;
// 重置位置,并读取数据
file.seekg(0);
char buffer[14] = {};
file.read(buffer, 13);
std::streampos readPos = file.tellg();
std::cout << "Read position: " << readPos << std::endl;
file.close();
return 0;
}
注意
对于一个 fstream
对象,tellg()
和 tellp()
得到的指针位置并不总是一样的 。这是因为 fstream
同时继承自 ifstream
和 ofstream
,分别管理输入和输出流。在某些情况下,输入指针(get pointer)和输出指针(put pointer)可能会分别移动,导致它们指向的位置不同。
-
当你使用
fstream
以读写模式打开文件时,如果仅进行写操作(如使用<<
操作符或write()
方法),则只会更新输出指针(put pointer)的位置。相应地,使用读操作(如使用>>
操作符或read()
方法)会更新输入指针(get pointer)的位置。 -
如果在写入操作后立即进行读取操作,或者在读取操作后立即写入,可能需要手动同步两个指针的位置。例如,在写入后想要读取相同的数据,可能需要使用
seekg()
将读取指针移动到写入的起始位置。同样地,如果在读取某些数据后想要在相同的位置开始写入,可能需要使用seekp()
来更新写入指针的位置。 -
在某些实现中,进行输出操作(如写入)可能会自动移动输入指针(get pointer)到文件末尾,反之亦然。但这种行为并不是所有环境下都一致的,因此依赖于此行为的代码可能不具有移植性.
cpp
#include <fstream>
#include <iostream>
int main() {
std::fstream file("example.txt", std::ios::binary | std::ios::in | std::ios::out | std::ios::trunc);
if (!file) {
std::cerr << "File could not be opened." << std::endl;
return 1;
}
// 写入数据
file << "Hello, world!";
std::cout << "After writing, put pointer is at: " << file.tellp() << std::endl;
// 读取数据之前,需要同步get和put指针
file.seekg(0);
std::string content;
file >> content;
std::cout << "After reading, get pointer is at: " << file.tellg() << std::endl;
file.close();
return 0;
}
当你观察到 tellp()
和 tellg()
返回相同位置的情况,这通常是因为在某些标准库实现中,对于 fstream
对象,即使是分别用于输入和输出的指针,它们在某些操作之后可能会被同步更新,特别是在对文件进行写入后立即查询位置、或在读取操作后进行位置查询的场景中。
这种行为部分取决于具体的标准库实现和文件模式。当 fstream
被以读写模式打开时,某些实现可能会选择在每次写操作后同步两个指针的位置,以简化文件指针管理逻辑。这意味着,当你写入数据后(使用 <<
运算符或其他写入方法),并查询写入指针 (tellp()
) 和读取指针 (tellg()
) 的位置,你可能会看到它们指向同一个位置,即最后一次操作的位置。
此外,标准库的实现可能会在你执行读取操作前后自动调整这些指针,以确保数据的一致性和访问的有效性。这种自动同步的行为有时候可以方便开发者,但也可能导致一些混淆,尤其是当你期望这两个指针能够独立移动时。
在你的示例代码中,你首先进行写入操作,然后立即查询了 tellp()
和 tellg()
的值,此时它们显示为相同。这可能是因为在你的标准库实现中,写操作后自动同步了输出和输入指针。随后,你使用 seekg()
调整了读取位置,并进行了读取操作。如果在这之后 tellp()
和 tellg()
依旧相同,这也可能是因为你的读取操作触发了某种同步机制。
需要注意的是,这种行为并不是所有编译器或标准库实现都会这样处理。因此,编写依赖于这种特定行为的代码时要小心,因为它可能不具备跨编译器的可移植性。