如果用户输入两个或多个由空格分隔的字符串C++如何防止缓冲区溢出?

How to prevent C++ buffer overflow if the user enters two or more strings separated by white spaces?

本文关键字:C++ 字符串 分隔 空格 溢出 缓冲区 何防止 输入 用户 两个 如果      更新时间:2023-10-16

我是一名学生,目前正在研究C++课程。 我正在制作一个程序,该程序应该要求用户输入一个不大于 99.99 的浮点数作为加油站的燃料价格。 我创建了将用户输入保存到 char 数组的代码,并创建了限制,以便用户输入的点不能超过 2 个点,例如 (2..2(。 最大字符数为 5 个,包括一个点。 现在,一切正常,除了用户在按回车键之前输入两组字符串。 我有一个问题,因为第二个字符串与循环中的其他 cin 语句搞砸了。 该代码还将获取最终的字符数组输入,然后将其隐藏到浮点变量中,以便可以轻松计算进一步的计算。 我正在开发Windows系统和Visual Studio 2017 C++。
我尝试检测 if/else 语句中的单个空格,但似乎空格没有被检测为单个字符数组成员,就像这个 ex。 否则如果 (str[count] == ' '( ,而不是要求重新输入没有空格的正确输入。 getline(( 函数无法在 char 数组上运行,所以我无法以这种方式丢弃在空格之后和之后输入的字符。 我尝试将 char 数组更改为字符串,但是如果用户输入两个或多个由空格分隔的字符串,我的程序会继续读取它以再次读取 cin。

int main()
{
int count = 0;
int lenFlag = 0, mainFlag = 0;
float result = 0;
int len;
char str[6] = "00000";
//string str ="00000";
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(2);
//This part will ask the user to set the price of fuel 
//for the gas pump program.   The programming project segment 
//is from a book by Walter Savitch "Absolute C++".

while (mainFlag == 0)
{
cout << "Please enter the fuel price in dollars $";
cin >> str;
len = strlen(str);
cout << "strlen is = " << len << endl;
while (len <= 5 && mainFlag == 0)
{
count = 0, lenFlag = 0;
while (count < len && lenFlag == 0)
{
if (count == 0 && (str[count] < 48 || str[count] > 57))
{                                                    
cout << "The first input member must be a number."
"You must use a number between 0-9.n"
"Try again: ";
cin >> str;
len = strlen(str);
lenFlag = 1;
}
else if (count > 0 && (str[count] < 48 || str[count] > 57)   
&&  str[count] != '.')
{
cout << "You must enter number between 0-9, or a decimal delimiter.n"
"Try again, : ";
cin >> str;
len = strlen(str);
lenFlag = 1;
}
else if (count > 0 && (str[0] == '.' && str[1] == '.') || (str[0] == '.' && str[2] == '.') ||
(str[0] == '.' && str[3] == '.') || (str[0] == '.' && str[4] == '.') ||
(str[1] == '.' && str[2] == '.') || (str[1] == '.' && str[3] == '.') ||
(str[1] == '.' && str[4] == '.') || (str[2] == '.' && str[3] == '.') ||
(str[2] == '.' && str[4] == '.') || (str[3] == '.' && str[4] == '.'))
{
cout << "You have entered more than 1 decimal delimiter, try again: ";
cin >> str;
len = strlen(str);
lenFlag = 1;
}
else if (count > 1 && str[0] > 48 && str[0] < 58 && str[1]>47 
&& str[1] < 58 && str[2]>47 && str[2] < 58)
{
cout << "Maximum number is 99.99, try again:n";
cin >> str;
len = strlen(str);
lenFlag = 1;
}
else if (str[count] == ' ')
{
cout << "Typing whitspace is not an option!!" << endl;
cout << "Try again!!" << endl;
cin >> str;
len = strlen(str);
lenFlag = 1;
}
else if (count == len - 1 && lenFlag == 0)
{
//cout << "Main flag switches to 1!!" << endl;
mainFlag = 1;
}
count++;
}
} //while(lenCopy <= 5) loop end 
if (len > 5)
{
cout << "Either non-numbers were entered, or a negative 
number, or an incorrect " << endl;
cout << "number size. Enter a maximum size of 5 
including a .dot for decimal number" << endl;
cout << "Maximum number is 99.99." << endl;
mainFlag = 0;
}
}//mainflag loop ends
int dotpos = 0;
for (int n = 0; n < len; n++)                            
{                                       
if (str[n] == '.')                                  
{
//dotpos = n + 1;
dotpos = len - n - 1;
cout << "dotpos = " << dotpos << endl;
}
else
{
result = result * 10 + (str[n] - '0');                       
//Line above is a  float and character mix as a math equation.
cout << "result " << n << " = " << result << endl;
}
}
if (dotpos > 0)                                         
result = result / (power(10, dotpos));              
cout << "You have set the cost at $" << result << " per gallon." << endl;
system("pause");
return 0;
}

偶尔围绕str变量的堆栈已损坏,当我大量尝试弄乱用户输入只是为了检查程序是否可以崩溃时,就会发生这种情况。 这就是为什么我需要知道如何清除空格后的输入。 我通过将 char 数组更改为字符串来解决堆栈损坏问题,但仍然没有潜在用户可能会在程序中丢弃的多余字符。

如果必须使用字符数组,我强烈建议限制从控制台读取的字符数。

std::istream::getline(( 非常适合于此:

const unsigned int LIMIT = 10;
char number_as_text[LIMIT];
std::cout << "Enter a floating point number, less than 10 characters: ";
std::cin.getline(number_as_text, LIMIT);

然后,可以使用strtod等函数将字符串转换为浮点变量。

我找到了解决字符串缓冲区溢出问题的好方法。 它使用 辛>>斯;后跟 getline(( 函数。 两者需要结合使用,并且 比读取将只是第一个字符串,空格之后的所有内容都将被丢弃。

cout << "Do you want to set cost in gallons or liters? "
"nPress G for gallons or L for liters: ";
cin >> ws;
getline(cin, chooseSetCost);
while (chooseSetCost != "G" && chooseSetCost != "g" && chooseSetCost != "L" && chooseSetCost != "l")
{
cout << "Incorrect input. Try again: "; 
cin >> ws;
getline(cin, chooseSetCost);
cout << "choose cost is = " << chooseSetCost << endl;
}