较长的获取线 CIN 输入的问题
Problems with longer getline cin inputs
我正在编写一个C++程序,该程序要求用户输入单词或句子,遍历单词/句子,将"a"或"A"的所有实例替换为"aoa"或"AoA",然后输出结果。但是,如果我尝试输入更长的句子,我会遇到问题。例如,如果我键入"为什么程序不会运行",程序将输出奇怪的字母而不是预期的结果。这是我的代码:
#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;
}
可能导致问题的原因是什么?
一个直接的问题是你从[1,n]
索引,而C++(std::string
,std::vector
,还有C风格数组)使用[0,n)
. 这意味着您将访问超出字符串的结尾。 您将字符存储到temp
与 temp[x]
,尽管 temp
的大小始终为 0。 双其中未定义的行为,可能会产生任何影响(包括使程序崩溃)。
您应该在以下情况下使用标准库的调试模式开发代码。 在Visual Studios中,我认为这是违约;使用 G++,您需要向命令添加-D_GLIBCXX_CONCEPT_CHECKS
-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC
线。
处理此问题的最简单方法是复制到新字符串中,随时进行更改:
std::string results;
for ( auto current = mening.cbegin(); current != mening.cend(); ++ current ) {
switch ( *current ) {
case 'a':
results += "aoa";
break;
case 'A':
results += "AoA";
break;
default:
results += *current;
break;
}
}
如果您确实想就地进行更换,它会变得棘手。当您插入的文本比开始时多时,迭代器失效。 所以你需要这样的东西:
static std::string const Ao( "Ao" );
static std::string const ao( "ao" );
for ( auto current = mening.begin(); current != mening.end(); ++ current ) {
switch ( *current ) {
case 'a':
current = mening.insert( current, ao.begin(), ao.end() ) + 2;
break;
case 'A':
current = mening.insert( current, Ao.begin(), Ao.end() ) + 2;
break;
}
}
就个人而言,我倾向于复制到新字符串中。
我建议你应该使用标准函数std::string::insert
插入字符'oA'
或'oa'
。它将使您的代码更易于处理和调试。
或者你可以简单地这样做:
#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 n = 0; n<y; n++ ) {
cout << mening[n];
if (mening[n] == 'a' || mening[n] == 'A')
cout << "o" << mening[n];
}
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;
}
#include <iostream>
#include <string>
std::string ReplaceA(std::string s) {
std::string temp = "";
for (unsigned int k = 0; k < s.size(); k++) {
if (s[k] == 'a' || s[k] == 'A') {
temp = temp + s[k];
temp = temp + "o";
temp = temp + s[k];
}
else {
temp = temp + s[k];
}
}
return temp;
}
int main(int argc, const char * argv[])
{
std::string mening; //The mening string is the word/sentence the user will input.
int play = 1;
while (play == 1) {
std::cout<<"Type in the sentence: ";
getline(std::cin, mening); //The input is saved in the string variable mening.
std::cout << ReplaceA(mening) << std::endl;
std::cout << "Do you want to do it again? (yes/no): ";
std::cin >> mening;
if( std::cin.fail() || ( mening != "yes" && mening != "no" ) ) {
std::cout << "Bad InputnDo you want to do it again? (yes/no): ";
std::cin.clear();
std::cin.ignore('256','n');
std::cin >> mening;
}else{
if(mening == "no") break;
}
std::cin.clear();
std::cin.ignore('256','n');
}
std::cout << "The program will now close.";
return 0;
}
更有条理,具有处理返回字符串的转换的函数。
你也可以试试这个功能,两个都可以工作,一个似乎更漂亮一点。
std::string ReplaceA(std::string s) {
std::string temp = "";
for(std::string::iterator k = s.begin(); k != s.end(); k++) {
switch(*k) {
case 'a': temp += "aoa"; break;
case 'A': temp += "AoA"; break;
default: temp += *k; break;
}
}
return temp;
}
cin>> 中还剩下一个尾随字符 '',所以 getline 采用这个 '' 字符并被终止; 忽略getline之前缓冲区的内容...
cin.ignore();
葛岭(辛,string_name)
- cpp二进制搜索问题,计算给定数组中输入元素的出现次数
- 编写时C++中的输入重定向问题
- 输入std::数组时出现问题
- 我试图制作一个程序,要求用户输入问题和答案,但程序循环不正确
- 打印时有二叉树问题.用户输入不打印任何内容
- 用户输入字符串的文件附加问题..C++
- 函数以相反的顺序输出输入问题,并改进算法以解释相等的数字
- 每当调试C (Xcode 10.1)时,输入问题
- iostream输入问题
- 井字输入问题
- 多个玩家的键盘输入问题
- 字符输入问题
- 使用 getline() 的字符串输入问题
- 如何在我的C++测验中输入问题
- GLFW操纵杆输入问题
- 在Bison中为$$输入问题
- c++内存/输入问题
- C++ 拆分输入问题
- c++文件输入问题
- 基本c++输入问题