Skip to content

Instantly share code, notes, and snippets.

@amigo421
Created January 24, 2020 12:48
Show Gist options
  • Save amigo421/c0845247790c5512abef51116bb7537a to your computer and use it in GitHub Desktop.
Save amigo421/c0845247790c5512abef51116bb7537a to your computer and use it in GitHub Desktop.
custom separators, two ways
// getting existing table for ctype<char> specialization
const auto temp = ctype<char>::classic_table();
// create a copy of the table in vector container
vector<ctype<char>::mask> bar(temp, temp + ctype<char>::table_size);
// add/remove stream separators using bitwise arithmetic.
// use char-based indices because ascii codes here are equal to indices
bar[' '] ^= ctype_base::space;
bar['\t'] &= ~(ctype_base::space | ctype_base::cntrl);
bar[':'] |= ctype_base::space;
// A ctype initialized with bar would delimit on '\n' and ':' but not ' ' or '\t'.
// ....
// usage of the mask above.
// any istream here but we use cin as sample only.
// do not forget to get raw memory area from vector by .data()
cin.imbue(locale(cin.getloc(), new ctype<char>(bar.data())));
// to reset locale to default use this:
cin.imbue(locale(cin.getloc(), new ctype<char>));
//====================================================================
// second way to customize delimiter symbols
//====================================================================
struct csv_whitespace : std::ctype<wchar_t>
{
bool do_is(mask m, char_type c) const
{
if ((m & space) && c == L' ') {
return false; // space will NOT be classified as whitespace
}
if ((m & space) && c == L',') {
return true; // comma will be classified as whitespace
}
return ctype::do_is(m, c); // leave the rest to the parent class
}
};
// .....
cin.imbue(std::locale(cin.getloc(), new csv_whitespace));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment