如何通过字段从istringstream读取和验证

时间:2013-03-11 17:30:05

标签: c++ parsing istream

我正在尝试检查输入有效性。我得到一个文件,其中有两列,第一列是字符串,第二列是整数。分隔符是任意数量的空格。问题是,我无法弄清楚如何正确检查第二项是否真的是一个int。请考虑以下代码:

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

通过调用lineStream.good()我可以检测输入,例如“abcd g”,但是当我输入类似“abcd 12a”的内容时,它被解析为“abcd”和12.与“abcd 12.2”等相同。

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

感谢提示

2 个答案:

答案 0 :(得分: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
  }
}

基本上,有两个检查:

    如果
  1. line_stream >> name >> num无法提取stringint,则会失败。
  2. 在这些提取之后,如果它们到达流的末尾,则将设置eof位。因此,如果流中仍有内容,则line_stream.eof()将失败。
  3. 显然,这是一个非常脆弱的方法,只适用于特定情况,并且需要适应线条格式的任何变化。

答案 1 :(得分: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;
}