检查输入的类型是不是正确
Posted
技术标签:
【中文标题】检查输入的类型是不是正确【英文标题】:Check if input is of correct type检查输入的类型是否正确 【发布时间】:2015-05-20 15:46:15 【问题描述】:我有一个模板类,它可以采用各种类型:int、double 等。我想检查用户是否输入了正确的类型。如果对象是用 int 实例化的,用户应该输入一个 int,如果它是用 double 他应该输入一个 double 等等。无论输入来自文件还是键盘,我都希望能够做到这一点。我有 2 个问题。
-
我应该检查“>>”运算符重载的定义吗?
如何进行检查?我是否要创建一个模板函数来检查任何类型的类型?
我想要这样的东西:
template <class Ttype>
class foo
Ttype a,b,c;
friend istream &operator>> <>( istream &input, foo<Ttype> &X );
//methods
;
template <class Ttype> istream &operator>>( istream &input, foo<Ttype> &X )
//check if X.a,X.b,X.c are of Ttype
input>>X.a>>X.b>>X.c;
int main()
foo<int> a;
cin>>a;
foo<double> b;
cin>>b;
return 0;
【问题讨论】:
X.a
必须是 Ttype
,因为您声明它是。如果你真的想检查,你可以static_assert(std::is_same<Ttype, decltype(X.a)>::value, "not the same");
但这永远不会触发。
你可以使用 boost::spirit,参见 here 和 here
【参考方案1】:
在阅读之前您无法检查输入。我唯一能想到的是将输入读入一个字符串(这将始终适用于文本文件或标准输入)并尝试将其转换为您期望的类型。在转换时,您可以查找异常。
【讨论】:
我如何检查类型是否匹配?我在 Ttype 上使用 typeinfo 吗? 只要使用转换方法,检查是否出现异常。您可以针对多种类型专门化您的模板函数,并在每种类型中调用正确的转换方法(如atoi
/atof
或一些 STL 等价物,如果有的话)。
这些函数都不会抛出异常。
是的。对于 C++11,您可以使用 std::stoi
等等。否则,如果 boost 是一个选项,boost::lexical_cast
可能会有用。【参考方案2】:
您似乎只想尝试从istream
读取,如果读取失败则失败。在这种情况下,您可以在提取操作后使用 istream
的隐式 bool-likeness。
template <class T>
class Foo
T a,b,c;
friend std::istream& operator>>(std::istream& input, Foo& X )
if (!(input >> X.a >> X.b >> X.c)) // examine the istream
std::cerr << "extraction failed\n";
return input;
【讨论】:
我很欣赏这个解决方案。但是还有两个想法。我不太确定,但这不会给最后一次读取操作(EOF)带来麻烦吗?原因 EOF 也会设置故障位,但这不是真正的错误。我在这里可能错了。也许额外的检查有助于确定它是否是 EOF。比如明确检查fail()
,如果这是真的,还要检查它是否不是eof()
。第二个想法。这会失败吗? int
如果输入类似于5.0
?
eof
直到您尝试读取 流的末尾时才会设置。如果您输入了类似1 2.0 3
的内容,它将按预期失败,如果您输入了1 2 3.5
,它会成功但将.5
留在流中。如果你想解决这个问题,那么你将不得不将输入作为字符串来使用。如何从那里移动并不是最清楚的。您可以为每个字符串创建一个字符串流,并检查是否消耗了整个流。以上是关于检查输入的类型是不是正确的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 PHP 和正则表达式检查输入值是不是正确? [复制]