2013-09-23 19 views
0

所以基本上我想創建一個接受字符串的格式函數,並將該字符串中的單詞替換爲用戶想要替換的任何字符。起初,我有一些問題與不可判定的迭代器,直到我意識到當你改變一個字符串的大小時,你可以使任何迭代器失效。現在它不會再拋出異常現在輸出與輸入相同。任何建議?需要幫助擦除並在C++中插入

string& formatFn(string& s, string& oldWord, string& newWord) 
{ 
    string word = ""; 
    for (auto iter1 = s.begin(); iter1 != s.end(); ++iter1) 
    {  
      string tmpWord = "";       
     if (!isblank(*iter1))  // Testing for whitespace 
     { 
      tmpWord += *iter1; 
      if (tmpWord == oldWord) 
      { 
       string::iterator beg = iter1 - word.size(); 
       string::iterator end = iter1; 
       auto sIter = s.erase(beg, end);     // Get the position returned by erase 
       auto i = sIter - s.begin();      // Get an index 
       s = s.insert(s[i], newWord); 
      } 
     } 
     if (isblank(*iter1)) 
     { 
      tmpWord.clear(); 
     } 
    } 
    return s; 
} 
+3

爲什麼不你使用'string :: find'和'string :: replace'來做這個? – us2012

回答

0
string::iterator beg = iter1 - word.size(); 

我不知道什麼word實際上做。您正試圖刪除oldWord,對不對?然後,它應該是:

string::iterator beg = iter1 - oldWord.size(); 

編輯:這是你的代碼的改進版本:

string formatFn(const string& s, const string& oldWord, const string& newWord) { 
    string result = "";  // holds the string we want to return 
    string word = "";  // while iterating over 's', holds the current word 

    for (auto iter1 = s.begin(); iter1 != s.end(); ++iter1) {  
     if (!isblank(*iter1)) 
      word += *iter1; 
     else { // if it is a whitespace, it must be the end of some word 
      // if 'word' is not same as 'oldword', just append it 
      // otherwise append 'newWord' instead 

      if (word == oldWord) 
       result += newWord; 
      else 
       result += word; 
      result += *iter1; 
      word.clear(); // reset 'word' to hold the next word in s 
     } 
    } 

    // the end of the string might not end with a whitespace, so the last word 
    // might be skipped if you don't make this test 

    if (word == oldWord) 
     result += newWord; 
    else 
     result += word; 

    return result; 
} 
0

如果您已經使用字符串爲什麼不`噸使用的所有方法?

for (auto it = text.find(o_text); it != string::npos; it = text.find(o_text)){ 
    text.replace(it, o_text.size(), n_text); 
} 
+0

看來OP想要替換* words *,找到會找到任何子字符串,而不僅僅是整個單詞。 – john

0

您是過於複雜的:

std::string replace_all(std::string s, const std::string& sOld, const std::string& sNew) 
{ 
    std::size_t p = s.find(sOld); 
    while (p != std::string::npos) 
    { 
     s.replace(p, sOld.length(), sNew); 
     p = s.find(sOld, p + sNew.length()); 
    } 
    return s; 
} 

如果您正在尋找只能更換整個單詞(當前您的圖謀是不會做):

#include <iostream> 
#include <string> 

bool test(const std::string& s, const std::string& sOld, std::size_t pos) 
{ 
    return (pos == 0 || !::isalpha(s[pos - 1])) && (!::isalpha(s[pos + sOld.length()]) || pos + sOld.length() >= s.length()); 
} 

std::size_t find_word(const std::string& s, const std::string& sOld, std::size_t pos) 
{ 
    pos = s.find(sOld, pos); 
    while (pos != std::string::npos && (!test(s, sOld, pos) && pos < s.length())) 
    { 
     pos++; 
     pos = s.find(sOld, pos); 
    } 
    return pos; 
} 

std::string replace_all(std::string s, const std::string& sOld, const std::string& sNew) 
{ 
    std::size_t p = find_word(s, sOld, 0); 
    while (p != std::string::npos && p < s.length()) 
    { 
     s.replace(p, sOld.length(), sNew); 
     p = find_word(s, sOld, p + sNew.length()); 
    } 
    return s; 
} 

int main() 
{ 
    std::string sOrig = "eat Heat eat beat sweat cheat eat"; 
    std::string sOld = "eat"; 
    std::string sNew = "ate"; 
    std::string sResult = replace_all(sOrig, sOld, sNew); 
    std::cout << "Result: " << sResult << std::endl; 
    // Output: "ate Heat ate beat sweat cheat ate" 
    return 0; 
} 
+0

我認爲OP的要求是取代* words *,而不是任何子字符串。這就是爲什麼他擁有所有空白處理。 – john

+0

爲什麼不接受對字符串的引用並改變它?然後你可以返回被替換的字數,例如'std :: size_t replace_all(std :: string&s,const std :: string&old,const std :: string & new);' – rwols

+0

@rwols:你可以這樣做,但這樣會改變原來的。它(相當於通過const引用並複製),保留原始的原始數據,如果原始的修改是可接受的,那麼返回'void'並且通過引用傳遞也是可行的,這點更多的是算法。 –