Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I would, obviously, just use IOStreams. Reading a homogeneous array or arrays from a CSV file without having to bother with any quoting is fairly trivial:</p> <pre><code>#include &lt;iostream&gt; #include &lt;sstream&gt; #include &lt;string&gt; #include &lt;vector&gt; std::istream&amp; comma(std::istream&amp; in) { if ((in &gt;&gt; std::ws).peek() != std::char_traits&lt;char&gt;::to_int_type(',')) { in.setstate(std::ios_base::failbit); } return in.ignore(); } int main() { std::vector&lt;std::vector&lt;double&gt;&gt; values; std::istringstream in; for (std::string line; std::getline(std::cin, line); ) { in.clear(); in.str(line); std::vector&lt;double&gt; tmp; for (double value; in &gt;&gt; value; in &gt;&gt; comma) { tmp.push_back(value); } values.push_back(tmp); } for (auto const&amp; vec: values) { for (auto val: vec) { std::cout &lt;&lt; val &lt;&lt; ", "; } std::cout &lt;&lt; "\n"; } } </code></pre> <p>Given the simple structure of the file, the logic can actually be simplified: Instead of reading the values individually, each line can be viewed as a sequence of values if the separators are read automatically. Since a comma won't be read automatically, the commas are replaced by spaced before creating the string stream for the internal lines. The corresponding code becomes</p> <pre><code>#include &lt;algorithm&gt; #include &lt;fstream&gt; #include &lt;iostream&gt; #include &lt;iterator&gt; #include &lt;sstream&gt; #include &lt;string&gt; #include &lt;vector&gt; int main() { std::vector&lt;std::vector&lt;double&gt; &gt; values; std::ifstream fin("textread.csv"); for (std::string line; std::getline(fin, line); ) { std::replace(line.begin(), line.end(), ',', ' '); std::istringstream in(line); values.push_back( std::vector&lt;double&gt;(std::istream_iterator&lt;double&gt;(in), std::istream_iterator&lt;double&gt;())); } for (std::vector&lt;std::vector&lt;double&gt; &gt;::const_iterator it(values.begin()), end(values.end()); it != end; ++it) { std::copy(it-&gt;begin(), it-&gt;end(), std::ostream_iterator&lt;double&gt;(std::cout, ", ")); std::cout &lt;&lt; "\n"; } } </code></pre> <p>Here is what happens:</p> <ol> <li>The destination <code>values</code> is defined as a vector of vectors of <code>double</code>. There isn't anything guaranteeing that the different rows are the same size but this is trivial to check once the file is read.</li> <li>An <code>std::ifstream</code> is defined and initialized with the file. It may be worth checking the file after construction to see if it could be opened for reading (<code>if (!fin) { std::cout &lt;&lt; "failed to open...\n";</code>).</li> <li>The file is processed one line at a time. The lines are simply read using <code>std::getline()</code> to read them into a <code>std::string</code>. When <code>std::getline()</code> fails it couldn't read another line and the conversion ends.</li> <li>Once the <code>line</code> is read, all commas are replaced by spaces.</li> <li>From the thus modified <code>line</code> a string stream for reading the line is constructed. The original code reused a <code>std::istringstream</code> which was declared outside the loop to save the cost of constructing the stream all the time. Since the stream goes bad when the lines is completed, it first needed to be <code>in.clear()</code>ed before its content was set with <code>in.str(line)</code>.</li> <li>The individual values are iterated using an <code>std::istream_iterator&lt;double&gt;</code> which just read a value from the stream it is constructed with. The iterator given <code>in</code> is the start of the sequence and the default constructed iterator is the end of the sequence.</li> <li>The sequence of values produced by the iterators is used to immediately construct a temporary <code>std::vector&lt;double&gt;</code> representing a row.</li> <li>The temporary vector is pushed to the end of the target array.</li> </ol> <p>Everything after that is simply printing the content of the produced matrix using C++11 features (range-based for and variables with <code>auto</code>matically deduced type).</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