C++如何不使用字符串读入一行不定数目的整数?

Maples7
  • 37

本来以为 while (cin >> a[n++]);可以直接读入一行结束,但是发现根本无法退出循环,用VS调试到行尾就看不到内容了,而此时循环没有退出也没有报错。大概是把换行符当整数读入了所以cin并没有fail?

然后尝试了:

    int temp;
    while (true)
    {
        cin >> temp;
        if (temp == '\n') break;
        a[n++] = temp;
    }

样例可以过,但是依然不能AC(OJ上的一道题),我想大概是可能有跟 \nASCII值相同的整数。

当然,可以用字符串先整行读入再解析,但是难道 C++ 中没有更好更简洁的方法吗?因为问题本身并不难。

回复
阅读 9.4k
3 个回答
✓ 已被采纳

自己处理空格还是蛮麻烦的。一般用sstream就好,真要想自己做,也是可以。

#include <iostream>

using namespace std;

//return true if \n, or return false
bool escape_white_space(istream &is)
{
  char dummy;
  while(true)
  {
    is >> dummy;
    if (dummy == '\n')
    {
      return true;
    }
    else if (!isspace(dummy))
    {
      is.putback(dummy);
      return false;
    }
  }
}
int main()
{
 int a[10];
 cin >> std::noskipws;

 int n = 0;
 while(true)
 {
   if(escape_white_space(cin))
     break;
   cin >> a[n++];
 }

  for (int i = 0; i < n; i++)
  {
    cout << a[i];
  }
  return 0;

}

再延伸一步,可以自己写一个manipulator。

//will absorb white character but if linebreak, then set error
istream &ws_on_lb_error(istream &is)
{
  char dummy;
  while(true)
  {
    is >> dummy;
    if (dummy == '\n')
    {
      is.setstate(ios_base::failbit);
      return is;
    }
    else if (!isspace(dummy))
    {
      is.putback(dummy);
      return is;
    }
  }
}

怎么用呢?和标准的manipulator一样用!

 int a[10];
 cin >> std::noskipws;

 int n = 0;
 //假设开头没有任何white space
 while(cin >> a[n++] >> ws_on_lb_error)
 {
 }

cin >> xyz返回false的唯一原因是failbit或者badbit被设置了。所以你自己写可以自己根据\n设置failbit。

用cin读int会直接跳过空格回车,没办法区分是否换行。
一个办法是把整行读出来然后再用sscanf或者sstream,这样也不算很麻烦。直接读大概是没办法了。

自问自答:
参考了一些资料,最后用我觉得力求简洁的类C的方法解决了读入数据的问题,如下:

#include <string>
#include <iostream>
using namespace std;

char buffer[1024]; 
char* p = buffer;

gets(buffer);
while (*p != 0)
{
    // 过滤空格与缩进
    while (*p == ' ' || *p == '\t') p++;

    // 读整数
    if (sscanf(p, "%d", &a[n++]) == 0) break;

    // 偏移指针到非数字部分
    p++;
    while (*p >= '0' && *p <= '9') p++;
}
宣传栏