SiteBanner

This installment's code draws together a number of elements we've explored so far.  They include:
 

  • File input / output
  • Global variables
  • User input from the terminal window
  • Enumeration values
  • Functions returning a value
  • The use of '#define'
  • Loop structures and "if  --  else" logic testing
  • Commenting to give clarity to program function

 

The program code would need reconsideration to solve the situation where, if the text data file has not yet been created, and the user does not provide any input except for '<Enter>', the text data file is STILL created with NO content.

 

(right-click to download)

/* pgm23 source */

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <sys/stat.h>            // for 'stat()' function to discover size of file

#define NOTESFILE    "./notes.txt"
#define NL                   '\n'
#define SLENGTH       128

char G_instr[SLENGTH];

enum statevals {ISERROR = -1, ISGOOD, DATAEMPTY = -1, DATAFOUND, ENDLESSLOOP};

int get_line_from_term(void);
int get_size_of_file(void);

int main(void) {
     int datastate;
     FILE *fileptr;

     /* 'a+' = APPEND to file, and allow reading also. File not exists? Create. FIle exists? Append. */
     /* 'w+' = WRITE to file, and allow reading also. File not exists? Create. File exists? Replace */
     fileptr = fopen(NOTESFILE, "a+");
     if (fileptr == NULL) {
          printf("\n"); perror("Abort - opening file for append: "); printf("\n");
          return(ISERROR);
          }

     while (ENDLESSLOOP)  {
          printf("\nEnter medium-length string, then <Enter>\n");
          printf("(<Enter> alone quits entry):  ");
          datastate = get_line_from_term();

          if (datastate == DATAFOUND) {
               printf("\nYou entered: %s\n", G_instr);

               strcat(G_instr, "\n");
               if (fputs(G_instr, fileptr) == EOF) {
                    perror("Abort - appending data to file: ");
                    fclose(fileptr); // we need to close what we opened
                    return(ISERROR);
                    }
               }
          else
                break; // out of ENDLESSLOOP because of just '<Enter>' alone
          }

     printf("\n");
     rewind(fileptr);
     while (fgets(G_instr, SLENGTH - 1, fileptr) != NULL)
          printf("%s", G_instr);

     fclose(fileptr);

     printf("\nFile size is currently: %d bytes.\n\n", get_size_of_file());
     return(ISGOOD);
     }

/* BUG ALERT If user happens to enter more than SLENGTH */
/* number of characters, the contents of 'G_instr' is arbitrary */
int get_line_from_term(void) {
     int ch;
     int y;

     y = 0;
     while (ENDLESSLOOP) {
          if ((ch = getc(stdin)) == NL)
               break;

          if (isprint(ch) != 0)
                G_instr[y++] = (char) ch;

          if (y == SLENGTH - 1) // - 1 reserves one space for terminating '\0' null
               y = 0;
          }

     /* since we're building a string from characters, we have */
     /* to always take care to null-terminate any input */
     G_instr[y] = '\0';

     if (strlen(G_instr) != 0)
          return(DATAFOUND);
     else
          return(DATAEMPTY);
     }

int get_size_of_file(void) {
     struct stat fileStat;

     stat(NOTESFILE, &fileStat);
     return(fileStat.st_size);
     }