如何在 C++ 中写入文件的中间?
How to write to middle of a file in C++?
我认为这应该很简单,但到目前为止我的谷歌搜索没有帮助...我需要用 C++ 写入现有文件,但不一定在文件末尾。
我知道当我只想将文本附加到我的文件时,我可以在我的流对象上调用 open
时传递标志 ios:app
。但是,这只能让我写入文件的末尾,而不是中间。
我做了一个小程序来说明这个问题:
#include <iostream>
#include <fstream>
using namespace std;
int main () {
string path = "../test.csv";
fstream file;
file.open(path); // ios::in and ios::out by default
const int rows = 100;
for (int i = 0; i < rows; i++) {
file << i << "\n";
}
string line;
while (getline(file, line)) {
cout << "line: " << line << endl; // here I would like to append more text to certain rows
}
file.close();
}
不能在文件中间插入。您必须将旧文件复制到新文件,并在复制到新文件的过程中在中间插入任何内容。
否则,如果您打算覆盖现有文件中的 data/lines,可以使用 std::ostream::seekp()
来标识文件中的位置。
您可以写到末尾并换行,直到它在正确的位置结束。
这是我必须做的。
这是之前的 test.txt 文件:
12345678
12345678
12345678
12345678
12345678
这是我的程序示例
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
fstream& goToLine(fstream& file, int line){
int charInLine = 10; //number of characters in each line + 2
//this file has 8 characters per line
int pos = (line-1)*charInLine;
file.seekg(pos);
file.seekp(pos);
return file;
}
fstream& swapLines(fstream& file, int firstLine, int secondLine){
string firstStr, secondStr;
goToLine(file,firstLine);
getline(file,firstStr);
goToLine(file,secondLine);
getline(file,secondStr);
goToLine(file,firstLine);
file.write(secondStr.c_str(),8); //Make sure there are 8 chars per line
goToLine(file,secondLine);
file.write(firstStr.c_str(),8);
return file;
}
int main(){
fstream file;
int numLines = 5; //number of lines in the file
//open file once to write to the end
file.open("test.txt",ios::app);
if(file.is_open()){
file<<"someText\n"; //Write your line to the end of the file.
file.close();
}
//open file again without the ios::app flag
file.open("test.txt");
if(file.is_open()){
for(int i=numLines+1;i>3;i--){ //Move someText\n to line 3
swapLines(file,i-1,i);
}
file.close();
}
return 0;
}
这是 test.txt 之后的文件:
12345678
12345678
someText
12345678
12345678
12345678
希望对您有所帮助!
根据我对操作系统的基本了解,我认为这是不可能的。
我的意思是,用当前的存储技术制作一个可以实现此类功能的 OS 并非不可能,但这样做总是会导致 space 分段浪费。
但我不知道有什么技术可以做到这一点。虽然一些基于云的数据库确实使用了这种功能(比如在文件中间插入内容),但它们是专门为该 DBMS 软件制作的,具有非常特定的目标硬件,它们也可能有一些定制的内核来执行此类任务。
我认为这应该很简单,但到目前为止我的谷歌搜索没有帮助...我需要用 C++ 写入现有文件,但不一定在文件末尾。
我知道当我只想将文本附加到我的文件时,我可以在我的流对象上调用 open
时传递标志 ios:app
。但是,这只能让我写入文件的末尾,而不是中间。
我做了一个小程序来说明这个问题:
#include <iostream>
#include <fstream>
using namespace std;
int main () {
string path = "../test.csv";
fstream file;
file.open(path); // ios::in and ios::out by default
const int rows = 100;
for (int i = 0; i < rows; i++) {
file << i << "\n";
}
string line;
while (getline(file, line)) {
cout << "line: " << line << endl; // here I would like to append more text to certain rows
}
file.close();
}
不能在文件中间插入。您必须将旧文件复制到新文件,并在复制到新文件的过程中在中间插入任何内容。
否则,如果您打算覆盖现有文件中的 data/lines,可以使用 std::ostream::seekp()
来标识文件中的位置。
您可以写到末尾并换行,直到它在正确的位置结束。 这是我必须做的。 这是之前的 test.txt 文件:
12345678
12345678
12345678
12345678
12345678
这是我的程序示例
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
fstream& goToLine(fstream& file, int line){
int charInLine = 10; //number of characters in each line + 2
//this file has 8 characters per line
int pos = (line-1)*charInLine;
file.seekg(pos);
file.seekp(pos);
return file;
}
fstream& swapLines(fstream& file, int firstLine, int secondLine){
string firstStr, secondStr;
goToLine(file,firstLine);
getline(file,firstStr);
goToLine(file,secondLine);
getline(file,secondStr);
goToLine(file,firstLine);
file.write(secondStr.c_str(),8); //Make sure there are 8 chars per line
goToLine(file,secondLine);
file.write(firstStr.c_str(),8);
return file;
}
int main(){
fstream file;
int numLines = 5; //number of lines in the file
//open file once to write to the end
file.open("test.txt",ios::app);
if(file.is_open()){
file<<"someText\n"; //Write your line to the end of the file.
file.close();
}
//open file again without the ios::app flag
file.open("test.txt");
if(file.is_open()){
for(int i=numLines+1;i>3;i--){ //Move someText\n to line 3
swapLines(file,i-1,i);
}
file.close();
}
return 0;
}
这是 test.txt 之后的文件:
12345678
12345678
someText
12345678
12345678
12345678
希望对您有所帮助!
根据我对操作系统的基本了解,我认为这是不可能的。 我的意思是,用当前的存储技术制作一个可以实现此类功能的 OS 并非不可能,但这样做总是会导致 space 分段浪费。
但我不知道有什么技术可以做到这一点。虽然一些基于云的数据库确实使用了这种功能(比如在文件中间插入内容),但它们是专门为该 DBMS 软件制作的,具有非常特定的目标硬件,它们也可能有一些定制的内核来执行此类任务。