2010-06-29 16 views
2

首先,感謝您的一切幫助!C++簡單字符串替換,非複雜代碼,但產生瘋狂錯誤

我得到的錯誤是:

未處理的異常0x7c812afb (KERNEL32.DLL)在Readerboard.exe: 微軟C++異常: 的std :: out_of_range內存位置 0x0012f8a8 ..

我發現是這一行的問題:

str.replace(str.find(sought), sought.size(), replacement); 

它坐落在此過程中:

void DisplayMessages() { 

ifstream myReadFile; 
string str; 
static string myMessages[10]; 
static int i; // of course my famous i 
static int MyPosition; 
string sought; 
string replacement; 

myReadFile.open("C:\\Documents and Settings\\agerho000\\Desktop\\cms_export_test\\outages.htm",ios::in); 
i = 0; //the start of my array 
sought = "</td>"; // value that I want to replace with nothing 
replacement.clear(); 

if(!myReadFile) // is there any error? 
{ 
    cout << "Error opening the file! Aborting…\n"; 
    exit(1); 
} 

if (myReadFile.is_open()) 
{ 
    cout << endl; 
    while (!myReadFile.eof()) 
    { 
    getline(myReadFile, str); 

    if (str == "<tr>") 
    {  
     myReadFile.seekg(4,ios::cur); 
     getline(myReadFile, str); 
     str.replace(str.find(sought), sought.size(), replacement); 

     cout << str; 

     myMessages[i]=str; 
     i++; 
    } 

    } 

} 

i=0; 
while (i < 10) 
{ 
    cout << i << ") " << myMessages[i] << endl; 
    i++; 
     if (myMessages[i]=="") 
     { 
      break; 
     } 
} 

myReadFile.close(); 

mainMenu(); 
} 

整個CPP文件顯示如下:

#include <iostream> 
#include <string> 
#include <fstream> 

using namespace std; 

void mainMenu(); 
void DisplayMessages(); 
void AddMessage(); 
void DeleteMessage(); 
void EditMessage(); 
void RunTests(); 
void CheckFile(); 
void CreateHtmlFile(string myMessages[10]); 
/* 
#define MIN  1 
#define MAX  100 

#define TRUE 1 
#define FALSE 0 
*/ 

int main() { 
    cout << endl; 
    cout << endl; 
    cout << "Hello Andrew.\n"; 
    cout << "First you need some sort of menu.\n"; 

    mainMenu(); 

    return 0; 
} 


void mainMenu() { 

    int Command; 

    cout << endl; 
    cout << endl; 
    cout << endl; 
    cout << "What would you like to do?\n"; 
// cout << "1) Check that tests work!\n"; 
// cout << "2) Check that the file exists\n"; 
    cout << "3) Display Messages\n"; 
// cout << "4) Edit a message\n"; 
// cout << "5) Add a message\n"; 
// cout << "6) Delete a message\n"; 
    cout << "7) Exit\n"; 
    cout << "Enter a number: "; 
    cin >> Command; 

    if (Command == 3) 
    { 
     DisplayMessages(); 
    } 

    if (Command == 7) 
    { 
     cout << "Exiting..."; 
     exit(EXIT_SUCCESS); 
    } 

    if (Command == 6) 
    { 
     DisplayMessages(); 
    } 
} 


void DisplayMessages() { 

ifstream myReadFile; 
string str; 
static string myMessages[10]; 
static int i; // of course my famous i 
static int MyPosition; 
string sought; 
string replacement; 

myReadFile.open("C:\\Documents and Settings\\agerho000\\Desktop\\cms_export_test\\outages.htm",ios::in); 
i = 0; //the start of my array 
sought = "</td>"; // value that I want to replace with nothing 
replacement.clear(); 

if(!myReadFile) // is there any error? 
{ 
    cout << "Error opening the file! Aborting…\n"; 
    exit(1); 
} 

if (myReadFile.is_open()) 
{ 
    cout << endl; 
    while (!myReadFile.eof()) 
    { 
    getline(myReadFile, str); 

    if (str == "<tr>") 
    {  
     myReadFile.seekg(4,ios::cur); 
     getline(myReadFile, str); 
     str.replace(str.find(sought), sought.size(), replacement); 

     cout << str; 

     myMessages[i]=str; 
     i++; 
    } 

    } 

} 

i=0; 
while (i < 10) 
{ 
    cout << i << ") " << myMessages[i] << endl; 
    i++; 
     if (myMessages[i]=="") 
     { 
      break; 
     } 
} 

myReadFile.close(); 

mainMenu(); 
} 

void AddMessage() { 
} 
/* 
void DeleteMessage() { 
ifstream myReadFile; 
string str; 
static string myMessages[10]; 
static int i; // of course my famous i 
static int MyPosition; 
string sought; 
string replacement; 
static int Command; 

myReadFile.open("C:\\Documents and Settings\\agerho000\\Desktop\\cms_export_test\\outages.htm",ios::in); 
i = 0; //the start of my array 
sought = "</b></td>"; // value that I want to replace with nothing 
replacement.clear(); 

if(!myReadFile) // is there any error? 
{ 
    cout << "Error opening the file! Aborting…\n"; 
    exit(1); 
} 

if (myReadFile.is_open()) 
{ 
    cout << endl; 

    while (!myReadFile.eof()) 
    { 
     getline(myReadFile, str); 

     if (str == "<tr>") 
     {  
      myReadFile.seekg(7,ios::cur); 
      getline(myReadFile, str); 
      str.replace(str.find(sought), sought.size(), replacement); 

      myMessages[i]=str; 
      i++; 
     } 

    } 

} 

i=0; 
while (i < 10) 
{ 
    cout << i << ") " << myMessages[i] << endl; 
    i++; 
     if (myMessages[i]=="") 
     { 
      break; 
     } 
} 
myReadFile.close(); 

cout << "Enter the number of the message you would like to delete?\n"; 
cout << "Or enter 11 to go back to the main menu.\n"; 
cin >> Command; 

while (Command >= 12) 
{ 
    cout << "Invalid number, try again!\n"; 
    cout << endl; 
    cout << "Enter the number of the message you would like to delete?\n"; 
    cout << "Or enter 11 to go back to the main menu.\n"; 
    cin >> Command; 
} 

if (Command == 11) 
{ 
    mainMenu(); 
} 

myMessages[Command].clear(); 
//clear the string 
//now rebuild the htm file with the new array 
CreateHtmlFile(myMessages); 
} 

void EditMessage() { 
} 

void RunTests() { 
} 

void CheckFile() { 
} 

void CreateHtmlFile(string myMessages[]) 
{ 
} 

        //File.seekg(-5); moves the inside pointer 5 characters back 
        //File.seekg(40); moves the inside pointer 40 characters forward 
        //tellg() Returns an int type, that shows the current position of the inside-pointer for reading 
        //tellp() same as above but for writing 
        //seekp() just like seekg() but for writing 
*/ 

請幫我這麼爲難!

+0

大將風範:這是更好地定義靠近使用點的變量,並在定義的地方初始化它們。你的'static'變量都不應該是這樣的(除非可能'被尋求'應該是一個常量)具有構造函數的類將由構造函數初始化,不需要「清除」替換字符串(並且存在最少的代碼,錯誤的可能性就越小)。在提問時,儘量減少代碼到相關部分 - 最好是提供額外的代碼,而不是錯過重要部分,所以如果有疑問,請留下它,但刪除註釋掉的部分。 – 2010-06-29 08:15:36

回答

15

str.replace(str.find(sought), sought.size(), replacement);str.find()找不到要查找的內容時是錯誤的。 str.find()將返回str::npos,這不會是字符串中的有效位置。因此,調用替換失敗,索引超出範圍異常,你看到。

修改成:

std::size_t foundIndex = str.find(sought); 
if (foundIndex != str.npos) 
    str.replace(foundIndex, sought.size(), replacement); 
else 
    std::cout << "Oops.. didn't find " << sought << std::endl; 

,並讓我們知道,如果可以幫助您。

編輯:您可能還需要考慮使用boost::algorithm::replace_allBoost String Algorithms Library

+0

+1替代'',更容易:) – 2010-06-29 08:43:09

+0

謝謝!驚人!謝謝! – CodingIsAwesome 2010-06-29 09:47:51

0

一個完整的功能替換字符串:

std::string ReplaceString(std::string subject, const std::string& search, 
          const std::string& replace) { 
    size_t pos = 0; 
    while ((pos = subject.find(search, pos)) != std::string::npos) { 
     subject.replace(pos, search.length(), replace); 
     pos += replace.length(); 
    } 
    return subject; 
} 

如果您需要的性能,這裏是一個優化的函數,修改輸入字符串,它不創建字符串的副本:

void ReplaceStringInPlace(std::string& subject, const std::string& search, 
          const std::string& replace) { 
    size_t pos = 0; 
    while ((pos = subject.find(search, pos)) != std::string::npos) { 
     subject.replace(pos, search.length(), replace); 
     pos += replace.length(); 
    } 
} 

測試:

std::string input = "abc abc def"; 
std::cout << "Input string: " << input << std::endl; 

std::cout << "ReplaceString() return value: " 
      << ReplaceString(input, "bc", "!!") << std::endl; 
std::cout << "ReplaceString() input string not modified: " 
      << input << std::endl; 

ReplaceStringInPlace(input, "bc", "??"); 
std::cout << "ReplaceStringInPlace() input string modified: " 
      << input << std::endl; 

輸出:

Input string: abc abc def 
ReplaceString() return value: a!! a!! def 
ReplaceString() input string not modified: abc abc def 
ReplaceStringInPlace() input string modified: a?? a?? def