c++ - C++ 数字输入验证
问题描述
我习惯了 Python,现在正在学习 C++,这对我来说有点复杂。如何修改输入以使其符合代码顶部注释中的描述?我试图包含 if (input[0]!='.' &&...) 但它只返回 0。我希望它作为数字的一部分包含在内。与输入的第一个字符之后的字符相同。
我也不知道如何用逗号分隔超过三位数的数字(显然是从数字的末尾开始)(所以 1000000 应该返回为 1,000,000)。
/*
* The first character can be a number, +, -, or a decimal point
* All other characters can be numeric, a comma or a decimal point
* Any commas must be in their proper location (ie, separating hundreds from thousands, from millions, etc)
* No commas after the decimal point
* Only one decimal point in the number
*
*/
#include <iostream>
#include <cmath>
#include <climits>
#include <string>
int ReadInt(std::string prompt);
int ReadInt(std::string prompt)
{
std::string input;
std::string convert;
bool isValid=true;
do {
isValid=true;
std::cout << prompt;
std::cin >> input;
if (input[0]!='.' && input[0]!='+' && input[0]!='-' && isdigit(input[0]) == 0) {
std::cout << "Error! Input was not an integer.\n";
isValid=false;
}
else {
convert=input.substr(0,1);
}
long len=input.length();
for (long index=1; index < len && isValid==true; index++) {
if (input[index]==',') {
;
}
else if (isdigit(input[index]) == 0){
std::cout << "Error! Input was not an integer.\n";
isValid=false;
}
else if (input[index] == '.') {
;
}
else {
convert += input.substr(index,1);
}
}
} while (isValid==false);
int returnValue=atoi(convert.c_str());
return returnValue;
}
int main()
{
int x=ReadInt("Enter a value: ");
std::cout << "Value entered was " << x << std::endl;
return 0;
}
解决方案
编写解析代码很棘手。解析时,很容易把控制流弄得一团糟。我建议将 I/O 与验证代码分开:创建一个单独的函数bool IsVaildInt(const std::string& s)
来返回是否s
是有效输入,并在调用函数之外执行提示。
它有助于系统地思考每个字符构成有效输入的内容。如果您熟悉正则表达式,就像 cigien 建议的那样,即使您最终手动编写解析代码而不是使用正则表达式库,这也可能是组织您的方法的好方法。
以下是您发布的要求:
* The first character can be a number, +, -, or a decimal point
* All other characters can be numeric, a comma or a decimal point
* Any commas must be in their proper location (ie, separating hundreds
from thousands, from millions, etc)
* No commas after the decimal point
* Only one decimal point in the number
这是很多逻辑,但它是可行的。听起来您正在将其作为掌握 C++ 基础知识的练习,因此我不会发布任何代码。相反,这是我将如何处理此问题的大纲:
测试第一个字符是否为 0-9、+、- 或小数点。如果不是,则返回无效。
搜索字符串是否有小数点。如果是,请记住它的位置。
循环遍历剩余的字符,从最后一个字符开始反向。
与循环索引分开,制作一个计数器,说明当前数字位置是什么(... -1 表示十分位,0 表示个位,1 表示十位,2 表示百位,...)。如果字符串有小数点,则使用它与字符串长度来确定最后一个字符的数字位置。
如果字符是逗号,请检查它是否位于与当前数字位置相比的有效位置。如果不是,则返回无效。
否则,如果字符是小数点,则它必须是前面标识的那个。如果不是,那就意味着有多个小数点,所以返回无效。
否则,字符必须是数字 0-9,并且数字位置计数器应该递增。如果字符不是数字,则返回无效。
最后,如果循环一直执行而没有遇到错误,则返回该字符串是有效的。
推荐阅读
- java - Spring Cloud Gateway:发布大文件时出现“连接已在响应之前关闭,同时发送请求正文”错误
- javascript - 使用 .reduce() 使用先前数组中的所有相似键值创建一个新数组
- rust - 如何通过对象安全方法中的动态调度传递闭包?
- ibm-cloud - 无法查看 API Connect Cloud Foundry 页面
- python - python中map和filter的区别
- mysql - 在另一个选择中选择案例
- android - Unity中Android的纵横比
- reactjs - 如何使用 useReducer 钩子测试组件?
- php - 为 Paypal 付款添加折扣
- javascript - 如何验证浏览器是否支持后台同步?