C++ 在C++;使用win32 API

C++ 在C++;使用win32 API,c++,winapi,string,C++,Winapi,String,我试图找到一种方法,用另一个字符串替换文件中字符串标记的所有实例

我试图找到一种方法,用另一个字符串替换文件中字符串标记的所有实例

<如何在C++中用Win32 API来实现这一点? 在其他语言中,这是一件容易的事情,但是在C++中,我只是丢失了。
编辑:对于某些上下文,这是用于WiX自定义操作。因此,可移植性不是主要的优先事项,只是最简单的解决方案。

如果文件适合内存,它会更简单。调用OpenFile()打开文件,GetFileSize()确定文件大小,分配足够的内存,调用ReadFile()读取文件,然后关闭文件。在内存中进行替换(使用strstr()或类似函数),然后再次执行OpenFile()、WriteFile()和CloseFile()

如果文件较大-创建一个临时文件,分块读取源文件,并将过滤后的文本写入临时文件,然后调用DeleteFile()删除原始文件,调用MoveFile()移动过滤后的文件。

您可以使用该库,它应该类似于您在其他平台上找到的大多数功能

它的工作原理如下:

在本文中,您将发现如何替换与模式匹配的字符串

#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;
}
#包括
#包括
int main()
{
boost::regex模式(“b.lug”,boost::regex_常量::icase | boost::regex_常量::perl);
std::stringstringa(“搜索bolug”);
标准:字符串替换(“BgLug”);
std::字符串新闻字符串;
newString=boost::regex_replace(stringa,pattern,replace);
printf(“新字符串是:|%s |\n”,newString.c_str());
返回0;
}

但是您当然需要添加文件读取/写入。

为什么必须使用Win32 API?使用C++是非常容易的,我不会通过添加人工约束来混淆这个问题。只需打开输入文件,打开输出文件,然后从输入中读取一行即可。当您的输入文件中没有点击EOF时,使用正则表达式查找您的令牌。如果你找到了它,那么用你的文本替换它。将该行写入输出文件。从输入中读取另一行。当你在输入端得到EOF时,关闭它。确保从输出缓冲区刷新任何挂起的输出。关闭输出文件。完成。

根据sharptooth的解决方案,我编写了一些C代码来查找并替换文件。我使用stdio调用(strlen、strstrstr、strcpy和strcat)来执行字符串操作(而不是win32调用),因此您唯一的依赖性是C运行时

这肯定不是我在生产系统中使用的代码。我会使用工具箱字符串操纵库中的东西来让它更干净(对于固定长度的缓冲区就不那个么干净了)。我可能不会使用boost,我不喜欢它的开销。但我想您可能会喜欢一个只包含基本内容的示例(注意,这会将修改后的缓冲区写入.temp)

#包括
#定义BUF_LEN 2048
int findandplace(常量字符*文件,常量字符*查找,常量字符*替换)
{
int replacecont=0;
文件*f=fopen(文件“rt”);
if(strstr(更换,查找))
返回0;//将blah替换为stuff_blah_stuff
无符号整数findLen=strlen(find);
字符临时文件[BUF_LEN];
strcpy(临时文件,文件);
strcat(临时文件“.temp”);
FILE*writeF=fopen(tempFile,“wt”);
如果(!f | |!writeF)
返回0;
printf(“正在处理%s-%s到%s\n”,文件,查找,替换);
char lineBuf[BUF_LEN];
memset(lineBuf,0,BUF_LEN);
char templanebuf[BUF_LEN];
memset(templanebuf,0,BUF_LEN);
//读取文件的每一行
while(fgets(lineBuf,BUF_LEN,f))
{
//获取find在行缓冲区中的位置
char*pos=strstrstr(lineBuf,find);
while(pos)
{
strncpy(templanebuf、lineBuf、pos-lineBuf);
strcat(tempLineBuf,更换);
strcat(templanebuf,pos+findLen);
replaceCount++;
//用替换的缓冲区替换当前buf
strncpy(lineBuf、templanebuf、BUF_LEN);
memset(templanebuf,0,BUF_LEN);
pos=strstr(lineBuf,find);
}
printf(“写入新行%s\n”,lineBuf);
fputs(lineBuf、writeF);
}
fclose(f);
fclose(writeF);
返回替换计数;
}
int main()
{
printf(“进行了%d次替换\n”,findandplace(“blah.txt”,“marker”,“testing_blah”);
}

这是用于msi自定义操作的。外部库是不可行的。在这种情况下,它会变得更加复杂。也许你可以使用C++流创建一个机械手,它可以替换某些字符串。你说的“外部库”是指DLL吗?因为Boost可以静态链接到可执行文件。实际上,如果您使用xpressive而不是regex,那么它是一个只包含头的库。根本没有链接。你在评论中说“这是一个msi自定义操作。外部库是不行的。”。你能在你的问题中详细说明这个想法/限制吗?
#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"));
}