Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Although it isn't a priori obvious there is a relatively simple way to change what a stream considers to be whitespace. The way to do it is to <code>imbue()</code> the stream with a <code>std::locale</code> object whose <code>std::ctype&lt;char&gt;</code> facet is replaced to consider the desired characters as whitespace. <code>imbue()</code>, <code>locale</code>, <code>ctype</code> - huh?!? OK, well, these aren't necessarily the things you use day to day so here is a quick example which set's up <code>std::cin</code> to use comma and newline characters as spaced:</p> <pre><code>#include &lt;locale&gt; template &lt;char S0, char S1&gt; struct commactype_base { commactype_base(): table_() { this-&gt;table_[static_cast&lt;unsigned char&gt;(S0)] = std::ctype_base::space; this-&gt;table_[static_cast&lt;unsigned char&gt;(S1)] = std::ctype_base::space; } std::ctype&lt;char&gt;::mask table_[std::ctype&lt;char&gt;::table_size]; }; template &lt;char S0, char S1 = S0&gt; struct ctype: commactype_base&lt;S0, S1&gt;, std::ctype&lt;char&gt; { ctype(): std::ctype&lt;char&gt;(this-&gt;table_, false) {} }; </code></pre> <p>Actually, this particular implementation of <code>std::ctype&lt;char&gt;</code> can actually be used to use one or two arbitrary <code>char</code>s as spaces (a proper C++2011 version would probably allow an arbitrary number of arguments; also, the don't really have to be template argumentss). Anyway, with this in place, just drop the following line at the beginning of your <code>main()</code> function and you are all set:</p> <pre><code>std::cin.imbue(std::locale(std::locale(), new ::ctype&lt;',', '\n'&gt;)); </code></pre> <p>Note that this really only considers <code>,</code> and <code>\n</code> as space characters. This also means that no other characters are skipped as whitespace. ... and, of course, a sequence of multiple comma characters is considered to be just one separator rather than possibly creating a bunch of empty strings. Also note that the above <code>std::ctype&lt;char&gt;</code> facet removes all other character classification. If you want to parse other objects than just strings you might want to retain the other character classification and only change that for spaces. Here is a way this could be done:</p> <pre><code>template &lt;char S0, char S1&gt; struct commactype_base { commactype_base(): table_() { std::transform(std::ctype&lt;char&gt;::classic_table(), std::ctype&lt;char&gt;::classic_table() + std::ctype&lt;char&gt;::table_size, this-&gt;table_, [](std::ctype_base::mask m) -&gt; std::ctype_base::mask { return m &amp; ~(std::ctype_base::space); }); this-&gt;table_[static_cast&lt;unsigned char&gt;(S0)] |= std::ctype_base::space; this-&gt;table_[static_cast&lt;unsigned char&gt;(S1)] |= std::ctype_base::space; } std::ctype&lt;char&gt;::mask table_[std::ctype&lt;char&gt;::table_size]; }; </code></pre> <p>Sadly, this crashes with the version of gcc I have on my system (apparently the <code>std::ctype&lt;char&gt;::classic_table()</code> yields a null pointer. Compiling this with a current version of clang doesn't work because clang doesn't support lambda. With the two caveats the above code should be correct, though...</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload