Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I recommend a more portable (hopefully) way of file size determination since <code>fseek(binaryStream, offset, SEEK_END)</code> is not guaranteed to work. See the code below.</p> <p>I believe that files should be at least minimally buffered at the kernel level (e.g. buffering at least one block per file by default), so seeks should not incur significant amount of extra I/O and should only advance the file position internally. If the default buffering is not satisfactory, you may try to use <code>setvbuf()</code> to speed up the I/O.</p> <pre><code>#include &lt;limits.h&gt; #include &lt;string.h&gt; #include &lt;stdio.h&gt; /* File must be open with 'b' in the mode parameter to fopen() */ long fsize(FILE* binaryStream) { long ofs, ofs2; int result; if (fseek(binaryStream, 0, SEEK_SET) != 0 || fgetc(binaryStream) == EOF) return 0; ofs = 1; while ((result = fseek(binaryStream, ofs, SEEK_SET)) == 0 &amp;&amp; (result = (fgetc(binaryStream) == EOF)) == 0 &amp;&amp; ofs &lt;= LONG_MAX / 4 + 1) ofs *= 2; /* If the last seek failed, back up to the last successfully seekable offset */ if (result != 0) ofs /= 2; for (ofs2 = ofs / 2; ofs2 != 0; ofs2 /= 2) if (fseek(binaryStream, ofs + ofs2, SEEK_SET) == 0 &amp;&amp; fgetc(binaryStream) != EOF) ofs += ofs2; /* Return -1 for files longer than LONG_MAX */ if (ofs == LONG_MAX) return -1; return ofs + 1; } /* File must be open with 'b' in the mode parameter to fopen() */ /* Set file position to size of file before reading last line of file */ char* fgetsr(char* buf, int n, FILE* binaryStream) { long fpos; int cpos; int first = 1; if (n &lt;= 1 || (fpos = ftell(binaryStream)) == -1 || fpos == 0) return NULL; cpos = n - 1; buf[cpos] = '\0'; for (;;) { int c; if (fseek(binaryStream, --fpos, SEEK_SET) != 0 || (c = fgetc(binaryStream)) == EOF) return NULL; if (c == '\n' &amp;&amp; first == 0) /* accept at most one '\n' */ break; first = 0; if (c != '\r') /* ignore DOS/Windows '\r' */ { unsigned char ch = c; if (cpos == 0) { memmove(buf + 1, buf, n - 2); ++cpos; } memcpy(buf + --cpos, &amp;ch, 1); } if (fpos == 0) { fseek(binaryStream, 0, SEEK_SET); break; } } memmove(buf, buf + cpos, n - cpos); return buf; } int main(int argc, char* argv[]) { FILE* f; long sz; if (argc &lt; 2) { printf("filename parameter required\n"); return -1; } if ((f = fopen(argv[1], "rb")) == NULL) { printf("failed to open file \'%s\'\n", argv[1]); return -1; } sz = fsize(f); // printf("file size: %ld\n", sz); if (sz &gt; 0) { char buf[256]; fseek(f, sz, SEEK_SET); while (fgetsr(buf, sizeof(buf), f) != NULL) printf("%s", buf); } fclose(f); return 0; } </code></pre> <p>I've only tested this on windows with 2 different compilers.</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