C++ 如何更新文件中特定行的数据?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30827126/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to update data at a particular line in a file?
提问by bikrathor
Consider i have following file ("testt.txt")
考虑我有以下文件(“testt.txt”)
abc
123
def
456
ghi
789
jkl
114
Now if i wanted to update the figure next to name ghi
(i.e. 789
),
how would i do it?
现在,如果我想更新 name 旁边的数字ghi
(即789
),我该怎么做?
The following code helps me reach there quickly no doubt, but how to update it quickly?
毫无疑问,以下代码可以帮助我快速到达那里,但是如何快速更新它?
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
int main()
{
int counter = 0;
string my_string;
int change = 000;
ifstream file ( "testt.txt" );
while(!file.eof())
{
counter = counter + 1;
getline(file, my_string, '\n');
if (my_string == "ghi")
{
ofstream ofile ( "testt.txt" );
for (int i = 0; i < counter + 1; i++)
{
//reached line required i.e. 789
//how to process here?
}
ofile.close();
break;
}
}
cout << counter << endl;
file.close();
return 0;
}
Clearly the counter here is 5 corresponding to "ghi",
so counter + 1 would point to value 789
. How to change it to 000
?
显然这里的计数器是 5 对应于“ghi”,所以 counter + 1 将指向 value 789
。怎么改成000
?
------------SOLVED-----------FINAL CODE------
------------解决了-----------最终代码------
#include<iostream>
#include<fstream>
#include<string>
#include <cstdio>
using namespace std;
int main()
{
string x;
ifstream file ( "testt.txt" );
ofstream ofile ( "test2.txt" );
while (!file.eof())
{
getline(file,x);
if (x == "789")
{
ofile << "000" << endl;
}
else
ofile << x << endl;
}
file.close();
ofile.close();
remove("testt.txt");
return 0;
}
Output ("test2.txt")
输出(“test2.txt”)
abc
123
def
456
ghi
000
jkl
114
回答by anatolyg
If you open a file with ifstream
for reading, and then with ofstream
for writing, the ofstream
will either not work or overwrite the file - I am not sure which option is right, but neither is what you want.
如果你打开一个文件ifstream
用于读取,然后ofstream
用于写入,ofstream
要么不起作用,要么覆盖文件 - 我不确定哪个选项是正确的,但也不是你想要的。
So use std::fstream
to open a file for reading and writing:
所以使用std::fstream
打开一个文件进行读写:
fstream file ( "testt.txt" );
After arriving to the proper place, use the seekp
method to enable writing to the stream after reading from it (it often works without seekp
, but when it fails, the bug is very difficult to find), as required by the Standard:
到了合适的地方后,使用seekp
方法开启读取流后的写入(通常不使用也可以seekp
,但是失败的时候,bug很难发现),按照标准的要求:
if (my_string == "ghi")
{
file.seekp(file.tellg());
...
break;
}
When modifying files, you have to replace the existing bytes with the new ones. It's important to write exactly 3 bytes, so the value 789
is overwritten properly. So you may want to check the range:
修改文件时,您必须用新的字节替换现有的字节。准确写入 3 个字节很重要,因此该值789
会被正确覆盖。因此,您可能需要检查范围:
if (change < 0 || change > 999)
abort(); // or recover from the error gracefully
And set the width of the output field before writing it:
并在写入之前设置输出字段的宽度:
file << setw(3) << change;
If your code switches from writing back to reading, use file.seekg(file.tellp())
to ensure it works properly.
如果您的代码从写回切换为读取,请使用file.seekg(file.tellp())
以确保其正常工作。
回答by Marcus Müller
Doing that is not generally easy, because file systems don't store files line-wise, but instead as sequence of bytes. So if you replace a line with let's say 4 characters in it by a line with 5 characters, you will overwrite something in your next line. You'd have to read the file into memory, and then re-write everything from your changed line on.
这样做通常并不容易,因为文件系统不会按行存储文件,而是按字节序列存储文件。因此,如果您将一行 4 个字符替换为 5 个字符的行,您将在下一行中覆盖某些内容。您必须将文件读入内存,然后从更改的行开始重写所有内容。
That's a horrible approach, because it is incredibly slow, and if you can avoid it by not using a text file to store this kind of information, you should do that. I generally recommend using something like sqlite
, for which libraries for all relevant languages exist, if you need to store data in things that feel like tables; for other kind of data, there's other approaches than relational databases, but that depends on what you want to actually store.
这是一种可怕的方法,因为它非常慢,如果您可以通过不使用文本文件来存储此类信息来避免它,那么您应该这样做。sqlite
如果您需要将数据存储在类似于表的东西中,我通常建议使用类似,所有相关语言的库都存在;对于其他类型的数据,除了关系数据库还有其他方法,但这取决于您想要实际存储的内容。