2016-06-20 48 views
-1

我正在寻找一种方法来使用C++替换我的html文件中的某个字符串(而不是整行)。举例来说,如果我有一个HTML文件,其中包含:使用C++替换文本文件中的单词

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

而且我希望它编辑为:

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

我需要通过“空中飞人”,以取代“早晨”,这是我的代码:

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; 
    } 

此代码没拿我的文件有任何影响,我想原因是,它是唯一能够改变整条生产线,而不是局部的字符串。有人能给我一些建议来做正确的实施吗?先谢谢你。

+0

filein >>读入令牌。令牌被空白消除。尝试'class = text> morning
'。 –

+0

尝试使用http://www.cplusplus.com/reference/string/string/getline/逐行读取文件,然后使用http://www.cplusplus.com/reference/string/string/find/查找子字符串如果你发现它,请用http://www.cplusplus.com/reference/string/string/replace/ – Marandil

回答

0

从我如何读了原来的问题,则需要更换“早晨”的所有实例与“飞人”的文件,在给定的不只是一个实例线。我首先将整个文件读入一个字符串。

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)) {} 
} 

接着,建立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); 
    } 
} 

然后在主,

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

编辑:find_and_replace()不应该宣布其file_contents字符串参数为常量。只是注意到并修复了这一点

+0

非常感谢您的详细解答! – Saintycer

1

您可以占用整行,然后搜索并替换子字符串。通过这种方式,你甚至可以跳过整个循环:

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"); 
+0

替换谢谢!它完美地解决了这个问题。 – Saintycer

0

有多种方式可以处理它。一个非常普遍的方法是使用新字符串创建一个文件,删除旧文件,然后将新文件重命名为旧文件名。

如果适合您,您可以阻止此控制台应用程序。


参数1是要搜索的字符串

参数2是使用

参数3是文件路径


基本上替换文本,我正在做一些STD流到新文件,并从旧文件中找到存在的字符串,如果存在,则替换该字符串,然后管理结果,而不管是否替换发生器编辑为新文件的新行。

然后,我们关闭流,检查文件大小,如果它成功地创建一个非空文件,我们删除旧文件并将新文件重命名为旧文件名。

如果退出代码aka errorlevel为2,则表示输入流不起作用。如果它是-1,那意味着我们没有成功查找并替换为新文件。如果它是1,那意味着你没有提供正确的参数。只有零出口才能表明成功。

如果你想使用这个,你应该添加一些异常处理,并可能是一个更强大的文件备份解决方案。

#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; 
} 
相关问题