Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>At least at first glance, this seems to have a couple of problems. First:</p> <pre><code>while ((line = strtok(buf, "\n\r"))) { </code></pre> <p>To use <code>strtok</code> you normally pass the buffer on the <em>first</em> all, then make subsequent calls passing "NULL" for the first parameter until <code>strtok</code> returns a NULL (indicating that it's reached the end of the buffer). [Edit: upon further examination, it's apparent this isn't really a bug -- as pointed out by @Casablanca, he sets <code>buf</code> to NULL in the loop so the second and subsequent iterations actually <em>do</em> pass NULL for the first parameter -- so the current code is a bit hard to understand and (at least arguably) somewhat fragile, but not actually wrong.]</p> <p>Second, when you allocate your space, it looks like you're not allocating space for the terminating NUL:</p> <pre><code>res[i] = (char*)malloc(sizeof(char) * strlen(line)); </code></pre> <p>At least at first glance, it looks like this should be:</p> <pre><code>res[i] = malloc(strlen(line)+1); </code></pre> <p>[As an aside, <code>sizeof(char)==1</code> and casting the return from <code>malloc</code> can mask the bug of failing to <code>#include &lt;stdlib.h&gt;</code> to get a proper prototype in scope.]</p> <p>Some of your other code isn't exactly wrong, but strikes me as less readable than ideal. For example:</p> <pre><code>j = 0; while ((res[i][j] = tolower(line[j]))) { j++; } </code></pre> <p>This appears to be a rather obfuscated way of writing:</p> <pre><code>for (j=0; line[j] != '\0'; j++) res[i][j] = tolower((unsigned char)line[j]); </code></pre> <p>Also note that when you call <code>tolower</code>, you generally need/want to cast the parameter to <code>unsigned char</code> (passing a negative value gives undefined behavior, and quite a few characters with accents, umlauts, etc., will normally show up as negative in the typical case that <code>char</code> is signed).</p> <p>You also seem to have a memory leak -- <code>read_dict</code> calls <code>readfile</code>, which allocates a buffer (with <code>calloc</code> -- why not <code>malloc</code>?) and returns a pointer to that memory in a structure. <code>read_dict</code> receives the structure, but unless I've missed something, the struct goes out of scope without your ever freeing the memory it pointed to.</p> <p>Rather than try to find and fix the problem you've seen, my immediate reaction would be to start over. It seems to me that you've made the problem considerably more complex than it really is. If I were doing it, I'd probably start with a function to allocate space and read a line into the space, something on this order:</p> <pre><code>// Warning: Untested code. #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;string.h&gt; char *readline(FILE *file) { char *buffer = NULL; size_t current_size = 1; char *temp; const int block_size = 256; do { if (NULL == (temp = realloc(buffer, current_size+block_size))) break; buffer = temp; buffer[current_size-1] = '\0'; if (fgets(buffer+current_size-1, block_size, file)==NULL) return strlen(buffer) &gt; 0 ? buffer : NULL; current_size += block_size-1; } while (strchr(buffer, '\n') == NULL); strtok(buffer, "\n"); if (NULL != (temp = realloc(buffer, strlen(buffer)+1))) buffer =temp; return buffer; } </code></pre> <p>Once that's working, reading all the lines in the file and converting them to upper-case comes out something like:</p> <pre><code>// Warning: more untested code. while (res[i] = readline(file)) { size_t j; for (j=0; res[i][j]; j++) res[i][j] = toupper((unsigned char)res[i][j]); ++i; } </code></pre>
 

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