3

入力の有効性を確認しようとしています。最初の列は文字列、2 番目の列は int です。セパレータは任意の数のスペースです。問題は、2 番目の項目が本当に 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()、配列を使用して、文字を無視せずに各要素全体を解析できますが、ここで正しいアプローチが何であるかはわかりません。

ヒントをありがとう

4

2 に答える 2

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
  }
}

基本的に、次の 2 つのチェックがあります。

  1. line_stream >> name >> numstringまたはのいずれかを抽出できない場合は失敗しますint
  2. これらの抽出の後eof、ストリームの最後に達した場合、ビットが設定されます。そのline_stream.eof()ため、ストリームにまだコンテンツが残っている場合は失敗します。

明らかに、これは特定の状況でのみ機能する非常に壊れやすい方法であり、行形式のほとんどすべての変更に適応する必要があります。

于 2013-03-11T17:43:17.137 に答える
0

2 つの文字列を読み取り、2 番目の文字列が実際に数値かどうかを確認できます。このようなもの:

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;
}
于 2013-03-11T17:51:14.817 に答える