目前,我只接受程序中用户的数字输入。我做了很多研究,但是给出的所有示例代码仍然可以接受输入,比如10abc
。
这是一个英尺对米转换器。
include <iostream>
using namespace std;
bool isNumber(string feet){
for (int i = 0; i < feet.length(); i++){
if (isdigit(feet[i]) == false){
return false;
}
return true;
}
}
int main(){
string feet;
beginning:
cout << "Enter the feet: ";
cin >> feet;
if (isNumber(feet))
cout << "The meter is: " << (double)stod(feet) * 0.3048 << endl;
else {
cout << "Invalid input. Please try again" << endl;
goto beginning;
}
return 0;
}
这段代码接近完美,但它不接受小数点(无语面),因为小数点会破坏“等位数”函数。
那么,是否有任何方法只接受纯数字,也包括小数点?
发布于 2021-07-27 20:41:21
那么,是否有任何方法只接受纯数字,也包括小数点?
函数std::strspn
将返回仅包含在另一个字符串中的字符的字符串的长度。因此,如果希望同时允许小数位数和小数点,可以使用以下方法进行输入验证:
bool isNumber( string feet )
{
return strspn( feet.c_str(), "0123456789." ) == feet.length();
}
但是,正如注释部分已经指出的那样,转换函数std::stod
本身提供了可用于输入验证的信息。如果为该函数提供第二个参数,它将向提供的变量写入匹配的字符数。
函数std::stod
在转换值之前会自动使用所有前导空格字符(例如空格和制表符)。如果还希望也允许尾随空格字符,但不允许使用其他类型的字符,则可能需要使用以下代码:
std::size pos;
double d;
//attempt the conversion
d = stod( feet, &pos );
//make sure that at least one character was converted
if ( pos == 0 )
throw "Input was invalid!";
//make sure that all remaining characters are whitespace
while ( feet[pos] != '\0' )
{
if ( !isspace( (unsigned char)feet[pos] ) )
throw "Input was invalid!";
pos++;
}
如果您根本不想允许任何空格,包括前导空格,那么在将字符串内容传递给std::stod
之前,您必须自己验证字符串内容。
您可能想知道为什么我要将char
转换为unsigned char
。请参阅this question了解为什么需要这样做的原因。出于同样的原因,代码中的以下一行是错误的:
if (isdigit(feet[i]) == false){
应改为:
if (isdigit((unsigned char)feet[i]) == false){
此外,代码中的下列问题似乎值得一提:
线
cin >> feet;
将读取一个单词的输入。因此,如果用户输入例如2318 sijslnej
,那么这一行代码将只将2318
写到feet
中。我怀疑这是你想要的。您可能需要使用feet.getline
,因为它将读取整行,而不是只读第一个单词。
我强烈建议你戒掉写这个的习惯:
if ( isdigit(...) == false )
尽管这一行总是有效的,但它仍然是一个非常坏的习惯,因为这个习惯也会导致您写以下内容:
if ( isdigit(...) == true )
这一行相当于
if ( isdigit(...) == 1 )
这是错误的。函数std::isdigit
返回int
类型的值,而不是bool
类型,并且返回值不一定是0
或1
。它可以返回任何非零值来表示一个数字,例如20
。在这种情况下,上面提到的if
条件表达式将等价于20 == 1
,后者将计算为false。这不是你想要的。
因此,而不是
if ( isdigit(...) == false )
你应该写
if ( !isdigit(...) )
而不是
if ( isdigit(...) == true )
你应该写:
if ( isdigit(...) )
发布于 2021-07-27 12:08:50
template <typename T>
T readFromLine(std::istream& in)
{
std::string line;
while (std::getline(in, line)) { // read whole line until it is possible
std::istringstream line_stream { line }; // initialize string stream to parse line read
T x;
// try read `x` then discard white spaces then check if end of lien was reached
if (line_stream >> x >> std::ws && line_stream.eof()) {
// stop since reading was successful and line do not contain anything extra
return x;
}
// continue if reading `x` was unsuccessful or when line contains something extra
}
// while loop ended since end of file was reached or error on input stream
throw std::invalid_argument { "stream to short" };
}
https://stackoverflow.com/questions/68544396
复制相似问题