A
:data_input
[input code here];
if ([validation test]) {
std::cout << "Invalid data. ";
goto data_input;
}
乙
do {
[input code here];
while ([validation test] && std::cout << "Invalid data. ");
C
do {
[input code here];
}
while ([validation test] && (std::cout << "Invalid data. ") || 1);
您会选择哪种方法跳回代码的输入段?为什么?
答案 0 :(得分:1)
我使用scanf(在C中)的一个技巧如下:
while (scanf("%d", &myInt)!=1) {
printf("Invalid Data!\n");
}
这基本上结合了数据输入和验证步骤:scanf尝试读取int,并返回它成功读取的内容的数量。如果它不是1,则出现问题,显示错误消息,并再次运行scanf。
因此,如果您能以某种方式将输入和验证步骤合并到一个语句中。所以,你可以尝试:
int data; // or whatever
while (!validate(data = getData())) {
[error code]
}
(我不是C ++的专家,所以虽然我知道这是可能的,但我不确定它是否一定是好的风格.C ++众神,如果这不是惯用的,告诉我,我会编辑)
如果无法做到这一点,我会选择这样的事情:
[input data]
while ([validation test fails]) {
std::cout << "Invalid data."
[input data again]
}
我不喜欢A,因为goto:)
我不喜欢B或C,因为我认为这是滥用和&amp;&amp;和|| - 利用短路是好的,但这些运算符的输入应该是返回有意义的值的表达式,而不是语句。
答案 1 :(得分:0)
在混合中抛出另一个:
bool validateData([data])
{
bool valid;
[validation logic, sets valid true or false]
if(!valid)
{
std::cout << "Invalid data.";
return false;
}
return true;
}
然后
do
{
[input data]
} while(!validateData([data]));
然后a)它是可读的b)validateData可以是任意的并且是可维护的。
答案 2 :(得分:0)
如果您正在使用C ++流并希望对数据执行某些操作,那么我将这样做:
std::istream& operator<<(std::istream& i, Data& d)
{
if (!(i >> d.member) || !(i >> d.othermember))
d.markInvalid(); // the istream is automatically marked invalid
return i;
}
// In another function:
Data myData;
while (std::cout << "Please enter the data: " &&
std::cin >> myData) // Or another stream, of course)
{
if (!data.isValid())
{
std::cout << "Invalid data.\n";
continue;
}
// Operate on data
}
这为您提供了一个优势,即意外的EOF不会有循环运行且没有任何东西。如果您希望继续输入错误,只需将第二个&&
更改为||
并进行循环检查myData.isValid()
,并在出现故障时显示错误消息continue;
。
或者,如果您只是编写一个函数来读取和返回数据(在我看来并不那么优雅),您可以使用
Data GetData(std::ostream& o, std::istream& i) {
Data myData;
while (o << "Please enter the data: " &&
i >> myData.member &&
i >> myData.otherMember &&
!myData.isValid())
{
o << "Invalid data! Please try again.\n";
}
if (!i)
{
myData.markInvalid(); // Make sure the caller knows the data is not good.
// Alternatively, throw an exception.
}
return myData;
}
// In another function:
Data myData = GetData(std::cout, std::cin);
if (myData.isValid())
{
// Operate on data
}
在任何一种情况下,您可能无法完全创建对象,并且需要某种方式来报告它。您需要检查输入的数据是否格式错误(然后您可能希望忽略无效输入以便获取新输入),或者流是否死亡(在这种情况下您可能需要拯救)。 C ++ FAQ提供了有关此事here的一些信息,包括使用整数类型执行此类操作的函数示例。