我很难找到执行通常需要使用标头(除了iostream
和iomanip
)或大于基本的C ++知识的任务的方法。 如何仅使用逻辑运算符,基本算术(+, - ,*,/,%),if语句和while循环来检查用户输入的数据类型?
显然输入变量首先具有声明的数据类型,但是这个问题覆盖了用户输入错误数据类型的可能性。
我尝试了几种方法,包括if (!(cin >> var1))
技巧,但没有任何方法可以正常工作。这有可能吗?
int main() {
int var1, var2;
cin >> var1;
cin >> var2;
cout << var1 << " - " << var2 << " = " << (var1-var2);
return 0;
}
可以在这里输入asdf
和5.25
,那么如何使用我之前说明的方法检查输入是否不是预期的整数?
我理解这个问题在很多方面都很模糊,主要是因为限制非常具体,列出我允许使用的所有内容都会很痛苦。我想评论中提到的部分问题是如何首先区分数据类型。
答案 0 :(得分:1)
您可以使用简单的操作来执行此操作,尽管可能有点困难,例如,可以使用以下函数来检查输入是否为十进制数。您可以扩展该想法并检查浮点数之间是否存在句点。
如果您需要进一步的帮助,请添加评论。
bool isNumber(char *inp){
int i = 0;
if (inp[0] == '+' || inp[0] == '-') i = 1;
int sign = (inp[0] == '-' ? -1 : 1);
for (; inp[i]; i++){
if (!(inp[i] >= '0' && inp[i] <= '9'))
return false;
}
return true;
}
答案 1 :(得分:0)
阅读后的一般检查完成如下:
stream >> variable;
if (not stream.good()) {
// not successful
}
这可以在任何std::ios
上完成。它适用于在空白处停止的标准类型(任何数字类型,char
,string
等)。如果无法读取variable
,good
将返回false。您可以为自己的类(包括control over good
's return value)自定义它:
istream & operator>>(istream & stream, YourClass & c)
{
// Read the data from stream into c
return stream;
}
针对您的具体问题:假设您阅读了字符42
。没有办法区分阅读它
- int
- double
因为两者都很好。您必须更精确地指定输入格式。
答案 2 :(得分:0)
标准库并不神奇 - 您只需要解析从用户读取的数据,类似于标准库所做的。
首先阅读用户的输入:
std::string s;
cin >> s;
(如果您想阅读整行,可以使用getline
)
然后你可以继续解析它;我们将尝试区分整数(*[+-]?[0-9]+ *
),实数(*[+-][0-9](\.[0-9]*)?([Ee][+-]?[0-9]+)? *
),字符串(*"[^"]" *
)和其他任何东西(“坏”)。
enum TokenType {
Integer,
Real,
String,
Bad
};
基本构建块是“吃掉”连续数字的例程;这将有助于我们了解[0-9]*
和[0-9]+
部分。
void eatdigits(const char *&rp) {
while(*rp>='0' && *rp<='0') rp++;
}
此外,跳过空格的例程可以很方便:
void skipws(const char *&rp) {
while(*rp==' ') rp++;
// feel free to skip also tabs and whatever
}
然后我们可以解决真正的问题
TokenType categorize(const char *rp) {
首先,我们想跳过空白
skipws(rp);
然后,我们将尝试匹配最简单的东西:字符串
if(*rp=='"') {
// Skip the string content
while(*rp && *rp!='"') rp++;
// If the string stopped with anything different than " we
// have a parse error
if(!*rp) return Bad;
// Otherwise, skip the trailing whitespace
skipws(rp);
// And check if we got at the end
return *rp?Bad:String;
}
然后,在数字上,注意实数和整数定义以相同的方式开始;我们有一个共同的分支:
// If there's a + or -, it's fine, skip it
if(*rp=='+' || *rp=='-') rp++;
const char *before=rp;
// Skip the digits
eatdigits(rp);
// If we didn't manage to find any digit, it's not a valid number
if(rp==start) return Bad;
// If it ends here or after whitespace, it's an integer
if(!*rp) return Integer;
before = rp;
skipws(rp);
if(before!=rp) return *rp?Bad:Integer;
如果我们注意到仍有东西,我们会解决实际数字:
// Maybe something after the decimal dot?
if(*rp=='.') {
rp++;
eatdigits(rp);
}
// Exponent
if(*rp=='E' || *rp=='e') {
rp++;
if(*rp=='+' || *rp=='-') rp++;
before=rp;
eatdigits(rp);
if(before==rp) return Bad;
}
skipws(rp);
return *rp?Bad:Real;
}
阅读输入后,您可以轻松调用此例程。
(请注意,这里的字符串只是为了好玩,cin
没有对双引号分隔字符串进行任何特殊处理。)