Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Very simply, you could read the file as I have described below.</p> <pre><code>void List::importData(const char *filePath) { // open the file. std::ifstream file(filePath); // storage for the values read from the stream. std::string symbol; int shares; // here we read the symbol from the file stream, with "file &gt;&gt; symbol". the // return value of that expression is the stream 'file', so we can chain // that to reading the share count with "file &gt;&gt; symbol &gt;&gt; shares". notice // that we use this in a conditional - this is because the stream will // evaluate to 'true' if there is more data to read, or 'false' otherwise. while ((file &gt;&gt; symbol &gt;&gt; shares)) { // create the new node addToBack(symbol, shares); } } </code></pre> <p>A few potential improvements to your <code>List</code>/<code>Node</code> arrangement. What i've given below ignores the problems of <strong>copy assignment</strong> and <strong>copy construction</strong>. As it stands, it'll blow up if you do either of these things - its left as an exercise to fix. But ultimately, i'd recommend using an <code>std::list&lt;StockItem&gt;</code>, where <code>StockItem</code> contains just the <code>symbol</code> and <code>share_count</code>.</p> <pre><code>#include &lt;fstream&gt; #include &lt;memory&gt; // the node class used in the list. note that I have not declared the list // to be a friend of the node. its needed as the data members are public. if // you dont want the data to be public (e.g. you want to enforce certain // operations) make them private, and provide accessor functions. in this case // StockNode is a struct, making the data members public by default. struct StockNode { std::string mSymbol; int mShares; StockNode *mNext; // custom constructor, which populates the symbol and shares. StockNode(const std::string&amp; symbol, int shares) : mSymbol(symbol), mShares(shares), mNext(0) { } }; class StockList { // we store the head AND the tail of the list. storing the tail allows for // fast appends. StockNode *mHead; StockNode *mTail; public: // we override the default constructor to initialize the head/tail pointers // to 0 (null). StockList() : mHead(0), mTail(0) { } // destructor - since we are using raw pointers, we need to manage the // freeing of the StockNodes ourselfs (again, if we used a // std::list&lt;StockNode&gt; we could have avoided this. ~StockList() { clear(); } void clear() { StockNode *node = mHead; // while we havent reached the end of the list. while (node) { // find the next element StockNode *temp = node-&gt;mNext; // free the memory for the current element. delete node; // set node to the next element in the list. node = temp; } // reset the pointers mHead = 0; mTail = 0; } // appends a node to the list. i have called it push_back in line with the // standard library implementation std::list (which you would normally use // here, but it looks like this is homework). notice that the parameter // is not a pointer, but a std::auto_ptr. look up the documentation for it // to see exactly how it works. its not *required* here, but i use it so // the interface documents that we are taking ownership of the node. void push_back(std::auto_ptr&lt;StockNode&gt; stockNode) { // notice below the calls to "release", this stops the std::auto_ptr // managing the memory - so it doesn't free the memory when we still // need it. if (mTail) { // the tail is set, write the new value. mTail-&gt;mNext = stockNode.release(); mTail = mTail-&gt;mNext; } else { // no tail set means this is the first element, set the head and // the tail. mHead = stockNode.release(); mTail = mHead; } } // ... implement other methods for looking up StockNodes, etc... void exportData(const std::string&amp; filePath) const { std::ofstream file(filePath.c_str()); for (StockNode *node = mHead; node; node = node-&gt;mNext) { // note that i have used '\n' instead of std::endl. this is // because std::endl prints the '\n' and flushes the stream // as we are writing to file, i figure it'll be a little quicker // if it doesnt flush to disk after every line. file &lt;&lt; node-&gt;mSymbol &lt;&lt; " " &lt;&lt; node-&gt;mNext &lt;&lt; '\n'; } } void importData(const std::string&amp; filePath) { std::ifstream file(filePath.c_str()); std::string symbol; int shares; while ((file &gt;&gt; symbol &gt;&gt; shares)) { push_back(std::auto_ptr&lt;StockNode&gt;(new StockNode(symbol, shares))); } } }; </code></pre>
    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. This table or related slice is empty.
    1. This table or related slice is empty.
    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