本来以为 while (cin >> a[n++]);
可以直接读入一行结束,但是发现根本无法退出循环,用VS调试到行尾就看不到内容了,而此时循环没有退出也没有报错。大概是把换行符当整数读入了所以cin并没有fail?
然后尝试了:
int temp;
while (true)
{
cin >> temp;
if (temp == '\n') break;
a[n++] = temp;
}
样例可以过,但是依然不能AC(OJ上的一道题),我想大概是可能有跟 \n
ASCII值相同的整数。
当然,可以用字符串先整行读入再解析,但是难道 C++ 中没有更好更简洁的方法吗?因为问题本身并不难。
用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++;
}
自己处理空格还是蛮麻烦的。一般用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。