开发者

C++ simple string replace, non complicated code, but producing crazy error

First, thank for you all your help!

The error I am getting is:

Unhandled exception at 0x7c812afb (kernel32.dll) in Readerboard.exe: Microsoft C++ exception: std::out_of_range at memory location 0x0012f8a8..

I have found the problem to be with this line:

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

It is located in this procedure:

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

The whole cpp file is displayed below:

#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
*/

Please help I am so stumped!


str.replace(str.find(sought), sought.size(), replacement); is wrong when str.find() doesn't find what it's looking for. str.find() will return str::npos, which will not be a valid location in the string. Hence, the call to replace fails with the index out of range exception you're seeing.

Change that to:

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;

and let us know if that helps you.

EDIT: You might also want to consider using boost::algorithm::replace_all from the Boost String Algorithms Library


A complete function for replacing strings:

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

If you need performance, here is an optimized function that modifies the input string, it does not create a copy of the string:

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

Tests:

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;

Output:

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜