c++ cin整数以,(逗号)分割读取

2023-11-11

1 某些场景整数流不是空格分割,如用逗号分割

例如,下面的输入,要求每行是一个数组,一共两行测试输入

1,2,3,4
5,6,7,8

下面的代码就可以很好的解决问题。

	vector<int> w;
	int temp;
	while (cin >> temp){
	    w.push_back(temp);
	    if (cin.get() == '\n') break;
	}

2 先谈谈cin

cin会根据数据的类型以及分隔符自动对数据进行输入。

  1. 数据的类型:两个常见的类型,如字符串string、数(int、short、float、double)
  2. 分隔符--delimiter:isblack()空格TAB两个
  3. cin允许分隔符多次出现,比如两数中间可以有多个空格、TAB相连

因此常见的数据输入是空格作为分隔符。

  1. cin会自动忽略分隔符回车换行‘\n’

自动忽略:不是足够智能发现它就不读取,而且读取后丢弃了!!!,可用通过cin.unsetf(ios::skipws)让cin都读取不丢弃

3 理解上面的代码

到这里就很清晰了,代码通过cin.get()从缓存中读取一个字节,这样就扩充了cin只能用空格TAB两个作为分隔符。这很精巧。发现是’\n’就知道一行结束了
案例

1/6*4556-123					/**<OK */
1/6*4556-			123			/**<OK,cin会自动忽略空格 */
192.168..1						/**<ERROR-上面的代码只能忽略一个空格,连续两个,,会触发cin.fail的错误	*/

下面是一个IP地址的读取,很容易达到目标
在这里插入图片描述

5 多行读取

上面的代码只能读取一行,有些不足,因为到底输入多少行是未知的,利用cin.good实现多行读取

int number;
while (cin.good()) {
	vector<int> ip_mask;
	while (cin >> number) {
		ip_mask.push_back(number);
		if (cin.get() == '\n')
			break;
	}
	if (!cin.good())
		break;
	/**<do something */
}

注意:循环次数是行数+1,会多一次循环,是为了触发读取失败。
流状态有 3 个标志位:eofbit,badbit 和 failbit。

  1. 当 cin 操作到达文件末尾时,eofbit 置 1。
  2. 当流被破坏时,badbit 置 1。例如:试图读取不可访问的文件、写入写保护的磁盘、写入的设备剩余空间不足等。
  3. cin 操作未能读取到预期的字符时 failbit 会置 1。例如:要输入到一个整型变量中,输入的却是字符时 failbit 置 1。I/O 失败时 failbit 也可能置 1。
  4. 如果 3 个状态位都为 0 表示一切顺利。good

5 BUG

考虑如下输入

1,2,3,4,
5,6,7,8

在4的后面添加一个逗号,这是就不能达到预期目标,实际上是一个数组,因为读完4后,cin.get()把逗号读走,cin接着读取’\n’当然自动忽略,也就连在一起了

6 字符串的流分割

如果是字符串,就不能简单的处理了,需要配合istringstream

xxx,xxx,xxx

下面是经典的处理方式,istringstream配合getline的字符切割方式。

	vector<int> w;
	vector<int> v;
	string wstr;
	string vstr;
	cin >> wstr;
	cin >> vstr;
	
	istringstream iss(wstr);
	string word;
	while (getline(iss, word, ',')) {
	    w.push_back(stoi(word));
	}
	iss.clear();
	iss.str(vstr);
	while (getline(iss, word, ',')) {
	    v.push_back(stoi(word));
	}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c++ cin整数以,(逗号)分割读取 的相关文章