更改cin的分隔符(c ++)
我已经redirect“cin”从文件stream中读取cin.rdbug(inF.rdbug())
当我使用提取操作符时,它读取直到它达到一个空格字符。
是否有可能使用另一个分隔符? 我经历了cplusplus.com的API,但没有find任何东西。
可以使用std::ios_base::imbue
来更改cin
或任何其他std::istream
的字间分隔符以添加自定义ctype
facet
。
如果您正在以/ etc / passwd的样式读取文件,则以下程序将分别读取每一个:
-delimited字。
#include <locale> #include <iostream> struct colon_is_space : std::ctype<char> { colon_is_space() : std::ctype<char>(get_table()) {} static mask const* get_table() { static mask rc[table_size]; rc[':'] = std::ctype_base::space; rc['\n'] = std::ctype_base::space; return &rc[0]; } }; int main() { using std::string; using std::cin; using std::locale; cin.imbue(locale(cin.getloc(), new colon_is_space)); string word; while(cin >> word) { std::cout << word << "\n"; } }
对于string,可以使用std::getline
重载使用不同的分隔符来读取。
对于数字提取,分隔符并不是真正的“空白”,但是数字中的任何字符都是无效的。
这是对罗布的回答的一个改进,因为这是正确的(我感到失望的是,它没有被接受)。
你需要做的是改变ctype
看的数组来决定一个分隔符是什么。
在最简单的情况下,你可以创build自己的:
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
的数组定义的不仅仅是分隔符,还定义了stream传输所需的leters,数字,符号和其他一些垃圾。 ( 本Voigt的答案涉及到这一点)所以我们真正想要做的是修改一个mask
,而不是从头开始创build一个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>(bar.data())));
您也可以在ctype
之间切换,行为将在中途更改:
cin.imbue(locale(cin.getloc(), new ctype<char>(foo)));
如果您需要回到默认行为,请执行以下操作:
cin.imbue(locale(cin.getloc(), new ctype<char>));
[ 现场示例 ]