简体   繁体   English

使用 C++ 替换文本文件中的单词

[英]Replace a word in text file using c++

I am looking for a way to replace a certain string (not an entire line) for my html file using C++.我正在寻找一种使用 C++ 为我的 html 文件替换某个字符串(不是整行)的方法。 For example, if I have a html file that contains:例如,如果我有一个包含以下内容的 html 文件:

</span><br><span class=text>morning<br></span></td>

And I want it to edited as:我希望它编辑为:

 </span><br><span class=text>night<br></span></td>

I need to replace "morning" by "night", and this is my code:我需要用“晚上”替换“早上”,这是我的代码:

  string strReplace = "morning";
  string strNew = "night";
  ifstream filein("old_file.html");
  ofstream fileout("new_file.html");
  string strTemp;
  while(filein >> strTemp)
  {
    if(strTemp == strReplace){
       strTemp = strNew;
    }
    strTemp += "\n";
    fileout << strTemp;
   }

This code did not take any effect on my file, and I guess the reason is that it is only able to change the entire line, instead of partial string.这段代码对我的文件没有任何影响,我猜原因是它只能更改整行,而不是部分字符串。 Can someone give me some suggestions to do the correct implementation?有人可以给我一些建议来正确实施吗? Thank you in advance.提前谢谢你。

From how I read the original question, you need to replace all instances of "morning" in your file with "night", not just one instance on a given line.从我阅读原始问题的方式来看,您需要用“晚上”替换文件中所有“早上”的实例,而不仅仅是给定行上的一个实例。 I would start by reading the entire file into a string.我首先将整个文件读入一个字符串。

std::string getfile(std::ifstream& is) {
  std::string contents;
  // Here is one way to read the whole file
  for (char ch; is.get(ch); contents.push_back(ch)) {}
  return contents;
}

Next, make a find_and_replace function:接下来,创建一个find_and_replace函数:

void find_and_replace(std::string& file_contents, 
    const std::string& morn, const std::string& night) {
  // This searches the file for the first occurence of the morn string.
  auto pos = file_contents.find(morn);
  while (pos != std::string::npos) {
    file_contents.replace(pos, morn.length(), night);
    // Continue searching from here.
    pos = file_contents.find(morn, pos);
  }
}

Then in main,然后在主要,

std::string contents = getfile(filein);
find_and_replace(contents, "morning", "night");
fileout << contents;

EDIT: find_and_replace() should not declare its file_contents string parameter to be const .编辑: find_and_replace()不应将其file_contents字符串参数声明为const Just noticed and fixed that.刚刚注意到并解决了这个问题。

You can take the entire line, and then search and replace the substring.您可以取整行,然后搜索并替换子字符串。 This way, you even skip the entire loop:这样,您甚至可以跳过整个循环:

std::string line;

//Get line in 'filein'
std::getline(filein, line);

std::string replace = "morning";

//Find 'replace'
std::size_t pos = line.find(replace);

//If it found 'replace', replace it with "night"
if (pos != std::string::npos)
    line.replace(pos, replace.length(), "night");

There's multiple ways you can handle it.有多种方法可以处理它。 A pretty common one is making a file with the new strings in it, deleting the old file, and then renaming the new file to the old file name.一个很常见的做法是创建一个包含新字符串的文件,删除旧文件,然后将新文件重命名为旧文件名。

If that suits you, you can snag this console application.如果这适合您,您可以使用此控制台应用程序。


Parameter 1 is the string to search for参数 1 是要搜索的字符串

Parameter 2 is the replacement text to use参数 2 是要使用的替换文本

Parameter 3 is the file path参数3为文件路径


Basically, I'm making some STD streams to the new file, and from the old file, locating the string in question if it exists, and if so, replace that string, and then pipe the result, regardless if substitution occurred as a new line for the new file.基本上,我正在将一些 STD 流发送到新文件,并从旧文件中找到有问题的字符串是否存在,如果存在,则替换该字符串,然后通过管道传输结果,无论替换是否作为新文件发生新文件的行。

Then, we're closing the streams, checking the file size, and if it succeeded to make a non-empty file, we're deleting the old file and renaming the new file to the old file name.然后,我们关闭流,检查文件大小,如果成功创建一个非空文件,我们将删除旧文件并将新文件重命名为旧文件名。

If the exit code aka errorlevel is 2, it means the input stream didn't work.如果退出代码又名 errorlevel 为 2,则表示输入流不起作用。 If it's -1, that means we didn't successfully find and replace with a new file in-tact.如果它是 -1,则意味着我们没有成功找到并替换为完整的新文件。 If it's 1, that means you didn't provide the correct parameters.如果为 1,则表示您没有提供正确的参数。 Only a zero exit will indicate success.只有零退出将表示成功。

If you want to use this, you should add some exception handling, and probably a more robust file backup solution.如果你想使用它,你应该添加一些异常处理,并且可能是一个更强大的文件备份解决方案。

#include <iostream>
#include <fstream>
#include <string>
#include <sys\stat.h>

using namespace std;

int main(int argc, char * argv[])
{
    if (argc != 4) { return 1; }
    int exit_code = -1;

    string textToFind = string(argv[1]);
    string replacementText = string(argv[2]);
    string fileToParse = string(argv[3]);
    string fileToWrite = fileToParse+".rep";

    ifstream inputFileStream(fileToParse, ifstream::in);
    if (!inputFileStream.good()) { return 2; }

    ofstream outputFileStream(fileToWrite);

    string fileLine;
    while (getline(inputFileStream, fileLine))
    {
        size_t substringPos = fileLine.find(textToFind);
        if (substringPos != string::npos)
        {
            fileLine.replace(substringPos, textToFind.size(), replacementText);
        }       
        outputFileStream << fileLine << '\n';
    }
    outputFileStream.close();
    inputFileStream.close();

    struct stat st;
    stat(fileToWrite.c_str(), &st);
    int new_file_size = st.st_size;

    if (new_file_size > 0)
    {
        if (remove(fileToParse.c_str())==0)
        {
            if (rename(fileToWrite.c_str(), fileToParse.c_str())==0)
            {
                exit_code = 0;
            }
        }
    }

    return exit_code;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM