c++ 的流输入,分为“格式化输入” 和“非格式化输入”。格式化输入的表现之一,会自动以空格为作为输入停止的标志,并跳过空格;格式化输入的表现之二,则是自动检查类型。这两点正合你的需求。
你现在的思路,似乎是按非格式化输入(然后由你来尝试实现格式化)的方法,所以事情被你搞复杂了。
方法一:低头接受空格分隔版
在c++输入流之前低头,使用 空格 作为 输入的分隔符:
int a[3] {};
std::cout << "请输入3个整数,每个数之间使用英文空格区分:";
std::cin >> a[0] >> a[1] >> a[2];
std::cout << a[0] << ',' << a[1] << ',' << a[2] << std::endl;输入: 1 2 3
输出: 1,2,3
方法二:低头接受临时变量版
以上例子,要求用户输入三个整数时,必须以“英文空格”分隔(最后一个当然可以使用换行来结束)。此时用户输入是 “1 2 3”。很容易,用户有时可能会希望以 英文的 ',' 作为分隔,即,希望输入 “1,2,3”,于是c++的一个坑来了,你想相对“完美”地,保持“格式化输入”的模式来定制这个分割符,若按“面向对象”的思维来思考,应该是:
//伪代码:cin.set_separator(',');
cin >> a[0] >> a[1] >> a[2];
可惜,这不行啊……为了实现这样一个目标,在C++中,竟然得熟悉以下知识:什么叫“迭代器”,
什么又是流的“迭代器”,包括流迭代器如何表达end();
如何使用输出或输入流 作为入参来 std::copy()函数,
最难的是还需要学习如何使用模板定义一个定制的 分隔符
简单的模板知识还不够,还得知道"非类型的模板参数……"
……
打住。这是 C++的流在已经过度设计的情况下,仍然无法满足一个看似非常简单的需求……
所以,还是土一点吧,自己来吃掉这个分割符:
int v[3] = {};
char c; //注意,是char类型 std::cin >> v[0] >> c >> v[1] >> c >> v[2];
题主说“std::cin>>a[0]>>ch>>a[1]>>ch>>a[2]”不行??嗯,会不会是你的 ch 的类型不是char?我亲测,我上面的代码肯定行:
方法三:正常装逼版 -C++流定制惯用法
对一个C++程序员说,写出上面代码很容易让自己非常难受,心情低落,吃不下饭,睡不好觉。因为它搞了一基本没用变量c,并且表意也不太明确。如果只是想解决后者,大可以将临时变量c的名字改为“comma”,也就是逗号的意思……但……临时变量……其实也不关临时变量的问题,其实就是这样做非常不C++……至于为什么“非常不C++”以及“很C++”到底是什么样子,没法在这里说。
此时可以考虑使用C++流(包括输出和输入)的一个惯用法。你定义一个函数,用这个函数来控制流的行为。这类函数称为“流的控制函数/io manipulators”。注:由于在实际项目很少需要真的在终端(控制台)里接受输入,所以我在想我下面要写的“控制函数”,或许C++标准库已经存在了,但反正要给题主演示如何实现,所以我也不去查了,自己写一个。
这回我给出完整代码,可以直接编译运行:
#include
using namespace std;
istream& separator(istream& is)
{
return is.ignore();
}
int main()
{
int v[3] = {};
std::cin >> v[0] >> separator >> v[1] >> separator >> v[2];
std::cout << v[0] << ',' << v[1] << ',' << v[2] << std::endl;
}输入: 1,2,3
输出: 1,2,3
可以看出“separator()”函数的实际实现,根本无视分隔符是什么(但必须严格遵守是一个英文字符,即char类型),直接将它忽略掉,即:调用输入流的 ignore() 方法,直接将下一个字符跳过。注:如果你希望严格检查用户是不是使用 ',' 字符来分隔,那你需要调用 is.peek(),得到流中的下一个字符,如果它不是你想要的,就设置流的badbit。
另:如果你对这种做法还不太熟悉,那请从 std::endl 开始学习。
方法四:过度装逼版
我不想演示了,因为我觉得这种完全只是用来装逼,不仅无助,简直就是拉低代码可读性,东西还是不要教会大家的好。虽然有些人(好像包括C++之父)真的非常强调C++的输入就得那么写……但我不觉得。
方法五:本色出演,绝不装逼之:scanf() 又不是不能用
以上方法可能都不是你想要的,你就是要scanf这种的,那就继续用。因为它在C++里也是标准,你只需:
#include