C++:搜索并写入文件以替换字符串
C++: Searching and writing to a file to replace a string
所以我创建了一个简单的测试应用程序。它的目的是读取或写入文本文件。它正在寻找字符串"固件:"。这个想法是,一个设备将有一个包转移到它上面并存储,然后激活。我想存储该包的名称(例如:Update1),当我需要时,查询它并获取包名称(从文件中读取)。
问题1:它似乎没有写入文件。问题2:当我将其写入文件时,如果存在"Firmware:pkgName"行,我如何用新的程序包名称替换pkgName?
这个程序运行和编译,所以可以把它放在IDE或文本编辑器中,它只是不能完全实现我想要的。我正在使用log.txt作为我的示例文件进行读取。我相信有一种更简单的方法可以做到这一点。我已经做了一段时间了,我已经被难住了。
谢谢你的帮助!
#include <cstdlib>
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int writeFile(string filename, string pkgName);
int readFile(string filename);
int main(void) {
string filename = "log.txt", userInput, pkgName;
system("touch log.txt");
while (true) {
cout << "Write or Read?n>>>";
cin >> userInput;
if (userInput == "Write") {
cout << "What's your package name?n>>>";
cin >> pkgName;
writeFile(filename, pkgName);
} else if (userInput == "Read") {
readFile(filename);
} else {
cout << "Invalid Input";
}
}
}
int writeFile(string filename, string pkgName) {
bool found, exists = true;
string line, word;
fstream firmwareFile;
int pos, size, num = 1;
firmwareFile.open(filename.c_str(), ios::in | ios::out | ios::app);
//firmwareFile << "This is a test.";
if (firmwareFile.is_open()) {
while (!found) {
getline(firmwareFile, line);
pos = line.find("Firmware: ");
if (pos != string::npos) {
//Found It
found = true;
exists = true;
size = line.size();
word = line.substr(10, ((size - pos) + 10));
cout << word << " is the old package name" << endl;
//TODO - Replace that with the new package name
firmwareFile.close();
} else if (firmwareFile.eof()) {
//Doesn't Exist
found = true;
exists = false;
cout << "No last firmware package available.n";
} else {
//Still Looking
found = false;
cout << "Searching line #" << num << endl;
}
num++;
if (!exists) {
firmwareFile << endl << "Firmware: " << pkgName << endl;
cout << "Wrote package name to filen" << endl;
}
firmwareFile.close();
}
} else {
cout << "Unable to open file";
}
}
int readFile(string filename) {
bool found;
string line, word;
fstream firmwareFile;
int pos, size, num = 1;
firmwareFile.open(filename.c_str(), ios::in | ios::out | ios::app);
if (firmwareFile.is_open()) {
while (!found) {
getline(firmwareFile, line);
pos = line.find("Firmware: ");
if (pos != string::npos) {
found = true;
size = line.size();
word = line.substr(10, ((size - pos) + 10));
cout << word << endl;
} else if (firmwareFile.eof()) {
found = true;
cout << "No last firmware package available.n";
firmwareFile << endl << "Firmware: ";
} else {
cout << "Searching line #" << num << endl;
}
num++;
}
firmwareFile.close();
} else {
cout << "Unable to open file";
firmwareFile.close();
}
firmwareFile.close();
}
以下是我的log.txt文件的内容(除了包含"Firmware:"的行之外,其他内容都很琐碎)
You
Think
It's
Here
But
It's
Not
So
That
Sucks
Doesn't
It
?
Firmware: Update1
I
Hope
You
Caught
It
!
好吧。第一个问题,在函数编写文件中,您有一个变量found
,您在while条件while (!found) { ... }
中测试它。问题是,当您第一次测试这个变量时,您没有将其设置为任何值。所以你有不明确的行为。看看您的其他代码,我认为应该使用do-while循环do { ... } while (!found);
,而不是while循环。看起来你在readFile中也有同样的问题。
第二个问题恐怕是个坏消息。除非替换为长度完全相同的字符串,否则无法替换文件中的字符串。这只是磁盘上文件组织方式的一个限制。实现替换的唯一方法是将整个文件读取到内存中,在内存中进行替换,然后将整个文件写回磁盘。
@jrok回答了您的问题2,但我怀疑您的代码并不是每次都写,因为find没有初始化,因此是未定义的,所以有一半时间(大约)您的while循环根本不会执行。您需要初始化已找到的和已存在的,如:bool found = false, exists = true;
如果您编写另一个文件时只更改了相关行,则可以简化操作:
std::ifstream cfg("log.txt");
std::ofstream tmp("log.tmp");
std::string line;
std::string pkgName;
while(std::getline(cfg, line)) {
if (line.find("Firmware:") != std::string::npos) {
line = "Firmware: " + pkgName;
}
tmp << line << 'n';
}
现在,重命名和删除文件是特定于平台的。如果您想要一个可移植的解决方案,我建议您查看Boost文件系统库。
如果你必须替换一个文件的内容(不需要删除另一个文件并将其重命名为其名称),那么你需要读入整个文件,对内存中的文件进行必要的更改,然后将内存中文件的全部内容写入磁盘文件,覆盖它。
如果允许您删除源文件,那么执行这些转换会容易得多。你只需要读入你的源文件,打开一个临时文件并写出来,随时进行你需要的任何更改。处理完源文件后,将其删除,并将新文件重命名为与原始源文件相同的名称。
- 生成随机.txt文件,10行,10列。充满随机:"*"、"#"、"@"。然后将随机字符替换为'P'
- 从文件中查找单词并替换到其他文件中
- 尝试将文本文件中的整数替换为用户输入的整数 [C++]
- 创建程序以从给定的.txt文件中查找文本,替换并计算单词
- 使用 std::文件系统替换文件
- 在 Python/C++ 中用更改文件中的随机数替换数字
- 我可以通过设置工具链文件来替换调用 cmake -G<generator> 选项和调用 vcvarsall.bat吗?
- 当多个进程尝试同时替换同一文件时,Linux 如何处理这种情况?
- 如何替换QML(QT)文件上的图像中的图像中没有资源中的图像
- 如何在不重写整个视频文件的情况下仅替换流中的一个数据框架?(ffmpeg)
- 在 c++ 中替换文件中特定位置的元素
- 如果在执行过程中替换二进制文件,"const"数组是否驻留在内存中?
- 标准目录中包含的文件可以静默替换现有宏
- 在文件中找到字符串后替换旁边的字符
- 如何将文件复制到另一个文件中,但是用用户输入的单词替换单词
- 使用C 替换文件中的字符
- C 字符串匹配和使用查找文件替换
- 用另一个文件替换文件,但保持文件名不变
- 输出到c++中的文件(替换现有文件)
- 处理文件-替换一行