递归cin.getline()不想要求输入

时间:2017-03-24 09:50:15

标签: c++ parsing recursion

以下是代码:

void Reader::read(short& in) {
    char* str = new char[6];
    char* strbeg = str;
    cin.getline(str, 6);

    in = 0;
    int value = 0;
    short sign = 1;

    if (*str == '+' || *str == '-') {
        if (*str == '-' ) sign = -1;
        str++;
    }

    while (isdigit(*str)) {
        value *= 10;
        value += (int) (*str - '0');
        str++;
        if (value > 32767) {
            cout.write("Error, value can't fit short. Try again.\n", 41);
            delete[] strbeg;
            read(in);
            return;
        }
    }

    if (sign == -1) { value *= -1; }

    in = (short) value;

    delete[] strbeg;

    return;
}

如果我键入999999999,它会调用自己,但在第四行,它不会再要求输入。调试器无法提供太多信息,因为它是更具特定语言的问题。先感谢您。祝你今天愉快! 是的,目标是将输入解析为短。我知道从最小负面输掉1,wip:)

=== edit ===

我试过转到......不,同样的事情。所以它不是关于可见变量或地址,我想。

=== edit ===

我无法使用运算符>>因为这项任务是禁止的。

1 个答案:

答案 0 :(得分:0)

999999999将导致溢出,因此为cin设置了failbit。然后你的程序到达读(in),然后是cin.getline()。在这里,由于失败,cin不会再问任何输入。

如果你试图弄清楚为什么在我的代码中确实要求更多输入,你可以自己找出所有这些。

我给你写了一个例子。

#include <iostream>
#include <climits>

using namespace std;

int main() {
  char str[6];

  short x = 0;
  bool flag = false;
  while (flag == false) {
    cin.getline(str, 6);
    flag = cin.good();
    if (flag) { // if read successfully
      char *p = str;
      if (*p=='-') // special case for the first character
        ++p;

      while (*p && *p>='0' && *p<='9')
        ++p;
      if (*p) // there is a non digit non '\0' character
        flag = false;
    }

    if (flag == false) {
      cout << "An error occurred, try try again." << endl;
      if (!cin.eof()) {
        cin.unget(); // put back the possibly read '\n'
        cin.ignore(INT_MAX, '\n');
      }
      cin.clear();
    } else {
      // str is now ready for parsing
      // TODO: do your parsing work here

      // for exemple x = atoi(str); 
    }
  }

  std::cout << x << std::endl;

  return 0;
}

正如我们所讨论的,你不需要新的。

在解析之前检查读取的字符串是否干净。如果你混合检查和解析,事情会很复杂。

你不需要递归。

通过istream::getline从流中读取字符似乎是我们在这里唯一的选择。当发生错误时,这个函数实际上并没有告诉我们多少,我们必须分别处理溢出和其他问题。