更改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>));
[ 现场示例 ]