这是对Robᵩ 答案的改进,因为这是正确的答案(我很失望它没有被接受。)
您需要做的是更改ctype 查看的数组以确定分隔符是什么。
在最简单的情况下,您可以创建自己的:
const ctype<char>::mask foo[ctype<char>::table_size] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ctype_base::space};
在我的机器上,'\n' 是 10。我已将该数组元素设置为分隔符值:ctype_base::space。用foo 初始化的ctype 只会在'\n' 上定界,而不是' ' 或'\t'。
现在这是一个问题,因为传入ctype 的数组不仅定义了分隔符,还定义了流式传输所需的字母、数字、符号和其他一些垃圾。 (Ben Voigt 的回答涉及到这一点。)所以我们真正想做的是修改mask,而不是从头开始创建一个。
可以这样实现:
const auto temp = ctype<char>::classic_table();
vector<ctype<char>::mask> bar(temp, temp + ctype<char>::table_size);
bar[' '] ^= ctype_base::space;
bar['\t'] &= ~(ctype_base::space | ctype_base::cntrl);
bar[':'] |= ctype_base::space;
使用bar 初始化的ctype 将分隔'\n' 和':',但不会分隔' ' 或'\t'。
您开始设置cin 或任何其他istream,以使用您的自定义ctype,如下所示:
cin.imbue(locale(cin.getloc(), new ctype<char>(data(bar))));
您也可以在ctypes 之间切换,行为会在中途改变:
cin.imbue(locale(cin.getloc(), new ctype<char>(foo)));
如果您需要返回默认行为,只需执行以下操作:
cin.imbue(locale(cin.getloc(), new ctype<char>));
Live example