这是使用浮点值进行输入验证的正确方法吗?
在花费了大量时间研究输入验证之后,我结合了一些想法并提出了这个:
检查字符串是否为有效双精度
的函数...
bool isDouble(double& destination, string& source)
{ // 64 bit
bool goodValue = false;
if (!source.empty()) {
errno = 0;
char *garbage = nullptr;
destination = strtod(source.c_str(), &garbage);
if (*garbage == '\0' && errno != ERANGE)
goodValue = true;
}
return goodValue;
}
>用于检查字符串是否为有效 32 位整数
...
bool isLong(long& destination, string& source)
{ // 32 bit (base 10)
const short BASE = 10;
bool goodValue = false;
if (!source.empty()) {
errno = 0;
char* garbage = nullptr;
destination = strtol(source.c_str(), &garbage, BASE);
if (*garbage == '\0' && errno != ERANGE)
goodValue = true;
}
return goodValue;
}
示例实现的函数
using namespace std;
int main() {
string buffer;
double value;
cout << "Enter a value: ";
getline(cin, buffer, '\n');
if (isDouble(value, buffer))
cout << "Value: " << value << endl;
else
cout << "ERROR: Invalid input\n";
return 0;
}
如果我忽略了这种方法的任何内容,任何人都可以发表评论吗?
After spending a good amount of time researching input validation, I combined a few ideas and came up with this:
Function to check a string for a valid double
...
bool isDouble(double& destination, string& source)
{ // 64 bit
bool goodValue = false;
if (!source.empty()) {
errno = 0;
char *garbage = nullptr;
destination = strtod(source.c_str(), &garbage);
if (*garbage == '\0' && errno != ERANGE)
goodValue = true;
}
return goodValue;
}
Function to check a string for a valid 32 bit integer
...
bool isLong(long& destination, string& source)
{ // 32 bit (base 10)
const short BASE = 10;
bool goodValue = false;
if (!source.empty()) {
errno = 0;
char* garbage = nullptr;
destination = strtol(source.c_str(), &garbage, BASE);
if (*garbage == '\0' && errno != ERANGE)
goodValue = true;
}
return goodValue;
}
Sample Implementation
using namespace std;
int main() {
string buffer;
double value;
cout << "Enter a value: ";
getline(cin, buffer, '\n');
if (isDouble(value, buffer))
cout << "Value: " << value << endl;
else
cout << "ERROR: Invalid input\n";
return 0;
}
Can anyone comment on if I am overlooking anything with this approach?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我不确定“正确”的方法,但这肯定不是我会做的。首先,也许是最明显的,这段代码:
在几个地方重复(至少我认为另一个实例是相同的,并且可能应该是相同的)。
其次,您似乎不允许使用诸如
1e23
或-1.2
之类的数字,这些数字通常被接受为浮点数。顺便说一句,我想我会使用 strtod 来尝试转换输入。您可以使用其第二个参数来检测转换是否到达输入字符串的末尾(如果没有,您将知道至少部分输入未被接受)。然后(显然)您会想要检查返回的值是否在所需的范围内。
I'm not sure about "the" correct way, but it's certainly not how I'd do it. First and probably most obvious, this chunk of code:
is duplicated in a couple of places (at least I think the other instance is identical, and probably should be anyway).
Second, you don't appear to allow numbers like
1e23
or-1.2
, which are usually accepted as floating point.Offhand, I think I'd use
strtod
to attempt to convert the input. You can use its second parameter to detect whether a conversion reached the end of the input string (if not, you'll know at least part of the input wasn't accepted). You'll then (apparently) want to check that the returned value was in the desired range.也许
strtod()
函数可以是在这里提供帮助,因为它告诉您已转换了多少:作为
buf
的源,您可以使用std::string token 标记您的输入; std::cin>> token;
或类似的东西并使用token.c_str()
。Perhaps the
strtod()
function can be of help here, as it tells you how much has been converted:As the source for
buf
you could tokenize your input withstd::string token; std::cin >> token;
or something like that and usetoken.c_str()
.如果这是您想要的练习,这是可以理解的。但除此之外,您可以使用 istringstream 来避免重新发明轮子:
If it's an exercise you want, that's understandable. But otherwise, you can use
istringstream
to avoid reinventing the wheel: