{"id":3330,"date":"2018-10-20T00:01:35","date_gmt":"2018-10-20T07:01:35","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=3330"},"modified":"2018-10-27T10:25:57","modified_gmt":"2018-10-27T17:25:57","slug":"working-with-text-files-longer-than-a-single-line","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=3330","title":{"rendered":"Working with Text Files Longer than a Single Line"},"content":{"rendered":"<p>Unless your program also created the file it&#8217;s reading, you have no guarantee how must text lurks inside. It could be a single character or the entire works of Shakespeare. Dealing with an unknown quantity of text it a file-reading challenge.<br \/>\n<!--more--><br \/>\nTo write an unknown quantity of text is really no big deal: You keep using file-output functions, such as <em>fprintf()<\/em> or <em>fputs()<\/em> until you&#8217;ve sent away as much text as desired. Close the file. You&#8217;re done.<\/p>\n<p>For reading an unknown quantity of text, start with a text file. For the sample code in this Lesson, I&#8217;ve used the <a href=\"https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2018\/10\/declaration.txt\">declaration.txt<\/a> file, which you can obtain by clicking the link.<\/p>\n<p>To start, the file is opened in <code>\"r\"<\/code>, read mode.<\/p>\n<p>I recommend reading the file by chunks of text. The <em>fgets()<\/em> function is up the task. It requires a <em>char<\/em> buffer to store text. See <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=3321\">last week&#8217;s Lesson<\/a> for an example, though that example reads only one line from the file.<\/p>\n<p>The <em>fgets()<\/em> function is called repeatedly until the <code>EOF<\/code> condition is returned. This flag is set by the operating system when the last byte from a file has been read. To detect this condition, use the <em>feof()<\/em> function. When <em>feof()<\/em> returns a non-zero value, the <code>EOF<\/code> has been encountered.<\/p>\n<p>The last step is to close the file.<\/p>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n\r\nint main()\r\n{\r\n    const char filename[] = \"declaration.txt\";\r\n    const int bufsize = 64;\r\n    char buffer[bufsize];\r\n    FILE *f;\r\n\r\n    <span class=\"comments\">\/* open the file for reading *\/<\/span>\r\n    f = fopen(filename,\"r\");\r\n    if( f == NULL )\r\n    {\r\n        fprintf(stderr,\"Error opening %s\\n\",filename);\r\n        return(1);\r\n    }\r\n\r\n    <span class=\"comments\">\/* read all the text *\/<\/span>\r\n    while( !feof(f) )\r\n    {\r\n        fgets(buffer,bufsize,f);\r\n        printf(\"%s\",buffer);\r\n    }\r\n\r\n    <span class=\"comments\">\/* close the file *\/<\/span>\r\n    fclose(f);\r\n\r\n    return(0);\r\n}<\/pre>\n<p>A <em>while<\/em> loop at Line 19 checks for the <em>feof()<\/em> condition on file handle <code>f<\/code>. The ! (not) is used because <em>feof()<\/em> returns zero until the actual end-of-file is encountered. So the loop spins, reading one line or 64 characters of text from the file and printing that buffer. When the <code>EOF<\/code> is found, the loop stops and the file is closed.<\/p>\n<p>The file outputs the entire contents of the <code>declaration.txt<\/code> file. You could make the code more efficient by increasing the buffer size. For example, if the operating system reads files in 2K chunks, you could change the buffer size of 2048, but on modern computers the difference wouldn&#8217;t be that noticeable.<\/p>\n<p>Files can also be read one byte a time, which allows for tighter code:<\/p>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n\r\nint main()\r\n{\r\n    const char filename[] = \"declaration.txt\";\r\n    FILE *f;\r\n    int ch;\r\n\r\n    <span class=\"comments\">\/* open the file for reading *\/<\/span>\r\n    f = fopen(filename,\"r\");\r\n    if( f == NULL )\r\n    {\r\n        fprintf(stderr,\"Error opening %s\\n\",filename);\r\n        return(1);\r\n    }\r\n\r\n    <span class=\"comments\">\/* read all the text *\/<\/span>\r\n    while(1)\r\n    {\r\n        ch = fgetc(f);\r\n        if( ch == EOF)\r\n            break;\r\n        putchar(ch);\r\n    }\r\n\r\n    <span class=\"comments\">\/* close the file *\/<\/span>\r\n    fclose(f);\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The <em>while<\/em> loop at Line 19 is endless. At Line 20, <em>fgetc()<\/em> fetches a single character from the open file <code>f<\/code> and stores it in variable <code>ch<\/code>. At Line 21, variable <code>ch<\/code> is tested for the <code>EOF<\/code> flag, which breaks the loop. Otherwise, the character is output at Line 23.<\/p>\n<p>The approach of reading a file one character at a time is best for immediate output. Otherwise, when you must examine the file&#8217;s text, using <em>fgets()<\/em> to store text in a buffer is a better choice.<\/p>\n<p>For <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=3337\">next week&#8217;s Lesson<\/a>, I cover writing values to a file.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The key to reading an unknown quantity of text from a file is knowing when to stop. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=3330\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-3330","post","type-post","status-publish","format-standard","hentry","category-main"],"_links":{"self":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3330","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3330"}],"version-history":[{"count":4,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3330\/revisions"}],"predecessor-version":[{"id":3352,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3330\/revisions\/3352"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3330"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3330"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3330"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}