我想,每个人一开始遇到这个问题,都会觉得挺简单的。但真正实施的时候,可能就会觉得还是有点坑的。毕竟对于C/C++这样成熟而使用广泛的语言而言,对于这个简单的问题竟然没有一个简洁有力甚至一行代码的解决方案,依然是让人觉得挺震惊的。
在 C/C++ 中,由于整数读取通常是会忽略空格、制表符、换行符等等的,所以当一行整数为不定数目的读取时,事情就变得有点棘手了。
由于对换行符的忽略,你无法判断此时行是否结束。
在C++中,我们通常可以直接把 cin 读取的返回作为条件判断以此来判断输入是否成功,不成功则不再继续 cin 从而退出循环,来完成对不定数目数据的读入。
一开始可能会这样想:while (cin >> a[n++]);
然后正如上述对换行符的忽略,换行之后 cin 并没有 fail (可参考 cin.fail() 方法)。
然后可能会有如下想法:
1 int temp; 2 while (true) 3 { 4 cin >> temp; 5 if (temp == ' ') break; 6 a[n++] = temp; 7 }
但依然不行。因为数据中很可能有与 ' ' ASCII 码相同的整数值,如果此时就 break 这样读入的数据不完整了。
然后我开始查找和提问,具体可参考下述链接的问题和讨论:
http://segmentfault.com/q/1010000002782266
事实上,c++ 强大的支持是完全可以用已有的功能解决的,实在不行大不了总是可以读入字符串再解析的嘛~
具体可以由上述链接中的答案,参考 sstream 和 sscanf。
并且,c++标准库本身就重载了istream& operator>> (istream& (*pf)(istream&));,让用户自行处理一些特殊的input需求。
然而对于一个初入C++坑的骚年而言,这些我依然觉得不熟悉不简明。
再继续检索了一些网上的内容之后,还是用一个类C的方式,解决了这个问题。
用到字符串,同时解析数字部分直接交给sscanf函数解决。既可以理解又保持简洁,让问题不至于过于深究了。
方案如下:
1 #include <string> 2 #include <iostream> 3 using namespace std; 4 5 char buffer[1024]; 6 char* p = buffer; 7 8 gets(buffer); 9 while (*p != 0) 10 { 11 // 过滤空格与缩进 12 while (*p == ' ' || *p == ' ') p++; 13 14 // 读整数 15 if (sscanf(p, "%d", &a[n++]) == 0) break; 16 17 // 偏移指针到非数字部分 18 p++; 19 while (*p >= '0' && *p <= '9') p++; 20 }
其中 a 是存储整数的数组,n是其下标,最终也是整个数组的长度。