我正在编写一个C程序,要求用户输入一个单词或句子,通过单词/句子,用'aoa'或'AoA'替换'a'或'A'的所有实例,然后输出结果 . 但是,如果我尝试输入更长的句子,我就会遇到问题 . 例如,如果我输入“为什么程序不会运行”,程序会输出奇怪的字母而不是预期的结果 . 这是我的代码:
#include <iostream>
#include <string>
using namespace std;
int main(int argc, const char * argv[])
{
string mening, temp; //The mening string is the word/sentence the user will input.
int play = 1, add;
while (play == 1) {
cout<<"Type in the sentence: ";
getline(cin, mening); //The input is saved in the string variable mening.
unsigned long y = mening.size(); //Grabs the amount of characters in input; this number is saved in the unsigned long variable y.
add = 0; //Makes sure the int variable add is reset to 0 if the loop restarts.
for (int k = 0, n = 1;n<=y;k++, n++) {
if (mening[k] == 'a' || mening[k] == 'A') {
k++;
for (int i = k, m = 1;m<=y - n;i++, m++) {
temp[i] = mening[i];
} //The characters after the one that has been checked are stored in temp array indexes, if the character that has been checked is an a or A.
for (int i = k, m = 1, j = k + 2;m<=y - n;i++, m++, j++) {
mening[j] = temp[i];
} //The characters after the one that has been checked move two steps to the right, to allow the two extra letters.
mening[k] = 'o';
mening[k + 1] = mening[k - 1];
k++;
add = add + 2; //The int variable add is increased by 2 during each aoa/AoA to avoid strange characters being outputted at the very end.
}
else { }
}
for (int k = 0;k<=y + add - 1;k++) {
cout<<mening[k];
}
cout<<endl<<"Do you want to do it again? (yes/no): ";
getline(cin, mening);
cin.clear();
cout << flush;
cout.flush();
cout.clear();
if (mening == "Yes" || mening == "yes" || mening == "YES") {
}
else {
play = 2;
}
}
cout<<endl<<"The program will now close.";
return 0;
}
可能导致问题的原因是什么?
4 回答
一个直接的问题是你从
[1,n]
索引,而C(std::string
,std::vector
,但也是C样式数组)使用[0,n)
. 这意味着'll access beyond the end of the string. And you'将字符存储到带有temp[x]
的temp
中,尽管temp
的大小始终为0.这两种都是未定义的行为,这可能会产生任何影响(包括崩溃程序) .在开发代码时应该使用标准库的调试模式 . 在Visual Studios中,我认为这是默认值;使用g,您需要将
-D_GLIBCXX_CONCEPT_CHECKS -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC
添加到命令行 .处理此问题的最简单方法是复制到新字符串中,随时进行更改:
如果你确实想要进行替换,那就太棘手了 . 当您插入的文本多于开头时,迭代器将失效 . 所以你需要这样的东西:
就个人而言,我赞成复制到一个新的字符串 .
我建议你应该使用标准函数
std::string::insert
来插入字符'oA'
或'oa'
. 它将使您的代码更易于处理和调试 .或者你可以这样做:
更有条理,具有处理返回字符串的转换的函数 .
你也可以尝试这个功能,两个都工作,一个似乎有点漂亮 .
实际上有一个尾随字符'\ n'来自最后一个cin >>,所以getline取这个'\ n'字符并被终止;在getline之前忽略缓冲区的内容......
cin.ignore();
getling(cin,string_name)