2013-03-11 25 views
3

我试图检查输入有效性。给我一个文件,其中有两列,第一个是字符串,第二个是ints。分隔符是任意数量的空格。问题是,我无法弄清楚如何正确检查第二个项目是否是int。通过调用lineStream.good()我可以检测输入如“ABCD G”,但是当我在放像“ABCD 12A”,它被解析为“ABCD”和12同样的,“如何从字符串中读取和验证istringstream

string line; // parameter with a string to be parsed 
string name; 
int num; 
istringstream lineStream(line); 
lineStream >> name; 
lineStream >> num; 

:考虑下面的代码abcd 12.2“等

在Java中,我可以使用String.split()来数组,然后解析每个整个元素,而不是忽略任何字符,但我不知道什么是正确的方法。

感谢提示

+0

可以影响C++假设你的分裂相同的“分裂”的策略是基于空格转换为字符串,然后再验证个别实体,但最终的问题是一个亮点。看来你问的是如何验证被提取的*元素,事实上,它是完整和简洁的,也许如何通过流属性收集这些信息。好问题。我会对不同的方法感兴趣。 – WhozCraig 2013-03-11 17:42:09

+0

我想知道是否有一种方法可以简单地做到这一点,即使用流。人们可能会为创建一个char *数组而烦恼,然后对它们进行标记并检查有效性,这是真的。 – 2013-03-11 17:46:31

回答

1

你可以简单地检查是否达到行std::stringstream结束你提取int后。如果int提取失败,则根本没有整数。如果成功了,但流中仍然有内容,那么这条线就太多了。我想解决这个问题,像这样:

std::string line, name; 
int num; 
while (std::getline(file, line)) { 
    std::stringstream line_stream(line); 
    if (line_stream >> name >> num && 
     line_stream.eof()) { 
    // Line was of the correct format 
    } 
} 

基本上有两项检查:如果它不能提取无论是stringint

  1. line_stream >> name >> num将失败。
  2. 这些提取后,eof位将设置,如果他们到达流的末尾。因此,如果流中仍有内容,line_stream.eof()将会失败。

很明显,这是一个非常脆弱的方法,只适用于特定的情况,并且需要适应几乎任何行格式的改变。

+0

@JerryCoffin这是一个[常见的误解](http://stackoverflow.com/q/14615671/150634)(几乎和思考'!eof()'是一个很好的while条件一样常见)。提取到达结束时会设置“eof” - 在阅读之前使用它不是一个好条件。 – 2013-03-11 17:48:00

+0

如果第二个字段后面有空格,这将不起作用,是吗? – 2013-03-11 17:48:04

+0

@MartinMelka确实不会。它只会特别允许''。你想在最后允许空格吗? – 2013-03-11 17:48:27

0

您可以读取两个字符串,然后检查第二个字符串是否是一个数字。事情是这样的:

std::string line; // parameter with a string to be parsed 
std::string name; 
std::string strNum; 
int num; 
std::istringstream lineStream(line); 
lineStream >> name; 
lineStream >> strNum; 

if (isNumber(strNum)) 
{ 
    num = atoi(strNum.c_str()); 
} 

// 

bool isNumber(const std::string& strNum) 
{ 
    bool lIsNumber = true; 
    std::string::const_iterator it = strNum.begin(); 
    while (it != strNum.end()) 
    { 
     if (!std::isdigit(*it)) 
     { 
     lIsNumber = false; 
     break; 
     } 
     ++it; 
    } 
    return lIsNumber; 
} 
+0

我想这应该工作。它不会考虑其余部分,但可以轻松完成。为什么我没有想到这一点? :o – 2013-03-11 17:55:44