Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The <code>c_str</code> method will return a pointer to <code>const</code> data. One approach is to replace:</p> <pre><code>customers[idx].setAcctNum(atoi(strtok((char *)tmpString.c_str()," "))); customers[idx].setAcctFN(strtok(NULL," ")); customers[idx].setAcctLN(strtok(NULL," ")); </code></pre> <p>with:</p> <pre><code>char *s = strdup (tmpString.c_str()); // check if s is NULL customers[idx].setAcctNum(atoi(strtok(s," "))); customers[idx].setAcctFN(strtok(NULL," ")); customers[idx].setAcctLN(strtok(NULL," ")); free (s); </code></pre> <p>This gives you a duplicate <em>writeable</em> string that you can run <code>strtok</code> on.</p> <p>I'm not usually a <em>big</em> fan of using old-style C stuff in C++ code but I'm also pragmatic in getting code running. There may well be a more "C++" way of doing things.</p> <p>And, if your implementation doesn't have a <code>strdup</code> (I don't think it's part of the standard):</p> <pre><code>char *strdup (const char *s) { char *d = (char *)(malloc (strlen (s) + 1)); if (d == NULL) return NULL; strcpy (d,s); return d; } </code></pre> <p><em>Update:</em></p> <p>Anthony, based on the updates to your question, if you're getting an error still then it's probably because the string is not what you expect. Come to think of it, you should <em>not</em> get <code>EXC_BAD_ACCESS</code> from writing to the result of a <code>c_str</code> since the memory is technically not read-only. <code>EXC_BAD_ACCESS</code> should only occur if you try to write to read-only memory (or outside your address space). As one commenter has pointed out, <code>c_str</code> <em>may</em> return a pointer to read-only memory for certain simple cases but that's unlikely to be the case here if your file has complex lines.</p> <p>In either case, the copying to a mutable string will fix it.</p> <p>What I think may be happening is that one of your <code>strtok</code>s is returning NULL. This would be the case if you're processing a line with less than three fields (e.g., "hello there" where the third <code>strtok</code> will return NULL).</p> <p>Print out the string in your code before the <code>strtok</code> calls:</p> <pre><code>std::cerr &lt;&lt; "[" &lt;&lt; s &lt;&lt; "]" &lt;&lt; std::endl; </code></pre> <p>(and ensure you free the string after the <code>strtok</code> calls lest you end up with a memory leak).</p> <p>If that turns out to be the problem, the solution depends on what you need. You could ignore those lines totally by checking and copying the individual string out before calling <code>set...()</code> - in other words, only call them if all three strings were non-null.</p> <p>You could check the string before hand to count the number of separators, ensuring that there were at least two.</p> <p>I'm sure there are other possibilities but I can't really help until:</p> <ol> <li>We know that the problem is as suspected; and</li> <li>You tell us what you want to happen.</li> </ol> <p>Hope that helps.</p>
 

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