我正在尝试找到一种方法,用另一个字符串替换文件中字符串标记的所有实例。
如何使用win32 API在C ++中执行此操作?
在其他语言中,这是一件容易的事,但在C ++中,我只是迷失了。
编辑:在某些情况下,这是针对WiX自定义操作。因此,可移植性不是主要优先事项,只是最简单的解决方案。
答案 0 :(得分:5)
如果文件适合内存 - 它更简单。调用OpenFile()打开文件,GetFileSize()确定文件大小,分配足够的内存,调用ReadFile()读取文件,然后调用CloseFile。在内存中替换(使用strstr()或类似的函数),然后再次使用OpenFile(),WriteFile(),CloseFile()。
如果文件很大 - 创建一个临时文件并以块的形式读取源文件并将过滤后的文本写入临时文件,然后调用DeleteFile()删除原始文件,调用MoveFile()移动过滤后的文件。 / p>
答案 1 :(得分:3)
您可以使用Boost.Regex库,它应该类似于您在其他平台上找到的大多数功能。
它会像这样工作:
在这个example中,您将找到如何替换匹配模式的字符串。
#include <boost/regex.hpp>
#include <string>
int main()
{
boost::regex pattern ("b.lug",boost::regex_constants::icase|boost::regex_constants::perl);
std::string stringa ("Searching for bolug");
std::string replace ("BgLug");
std::string newString;
newString = boost::regex_replace (stringa, pattern, replace);
printf("The new string is: |%s|\n",newString.c_str());
return 0;
}
但你当然要添加文件读/写。
答案 2 :(得分:2)
根据sharptooth的解决方案,我敲了一些C代码来对文件进行查找和替换。我使用stdio调用(strlen,strstr,strcpy和strcat)来进行字符串操作(而不是win32调用),所以你唯一的依赖是C运行时。
这肯定不是我在生产系统中使用的代码。我会使用工具包字符串操作库中的东西来使它更清晰(而不是使用固定长度的缓冲区)。我可能不会使用boost,我不喜欢开销。但我想你可能只想要一个基本的例子(N.B.这会将改变后的缓冲区写入.temp)。
#include <stdio.h>
#define BUF_LEN 2048
int findAndReplace (const char * file, const char * find, const char * replace)
{
int replaceCount = 0;
FILE * f = fopen (file, "rt");
if (strstr(replace, find))
return 0; // replacing blah with stuff_blah_stuff
unsigned int findLen = strlen (find);
char tempFile [BUF_LEN];
strcpy (tempFile, file);
strcat (tempFile, ".temp");
FILE * writeF = fopen (tempFile, "wt");
if (!f || !writeF)
return 0;
printf ("Processing %s - %s to %s\n", file, find, replace);
char lineBuf [BUF_LEN];
memset (lineBuf, 0, BUF_LEN);
char tempLineBuf [BUF_LEN];
memset (tempLineBuf, 0, BUF_LEN);
// read each line of the file
while (fgets (lineBuf, BUF_LEN, f))
{
// get the position of find in the line buffer
char * pos = strstr (lineBuf, find);
while (pos)
{
strncpy (tempLineBuf, lineBuf, pos - lineBuf);
strcat (tempLineBuf, replace);
strcat (tempLineBuf, pos + findLen);
replaceCount++;
// replace the current buf with the replaced buffer
strncpy (lineBuf, tempLineBuf, BUF_LEN);
memset (tempLineBuf, 0, BUF_LEN);
pos = strstr (lineBuf, find);
}
printf ("writing new line %s\n", lineBuf);
fputs (lineBuf, writeF);
}
fclose (f);
fclose (writeF);
return replaceCount;
}
int main ()
{
printf ("Made %d replacements\n", findAndReplace ("blah.txt", "marker", "testing_blah"));
}
答案 3 :(得分:1)
为什么必须使用Win32 API?使用直接C ++很容易,我不会通过添加人为约束来混淆问题。只需打开输入文件,打开输出文件,然后从输入中读取一行。虽然您没有在输入文件中点击EOF,但使用正则表达式来查找令牌。如果找到它,请将其替换为您的文本。将该行写入输出文件。从输入中读取另一行。当您在输入上获得EOF时,请将其关闭。确保从输出缓冲区刷新任何挂起的输出。关闭输出文件。完成。