C++简单字符串替换,非复杂代码,但产生疯狂错误
首先,感谢您的一切帮助!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
*/
请帮我这么为难!
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_all从Boost String Algorithms Library
+1替代'',更容易:) – 2010-06-29 08:43:09
谢谢!惊人!谢谢! – CodingIsAwesome 2010-06-29 09:47:51
一个完整的功能替换字符串:
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
大将风范:这是更好地定义靠近使用点的变量,并在定义的地方初始化它们。你的'static'变量都不应该是这样的(除非可能'被寻求'应该是一个常量)具有构造函数的类将由构造函数初始化,不需要“清除”替换字符串(并且存在最少的代码,错误的可能性就越小)。在提问时,尽量减少代码到相关部分 - 最好是提供额外的代码,而不是错过重要部分,所以如果有疑问,请留下它,但删除注释掉的部分。 – 2010-06-29 08:15:36