/* byte-counter-better.c Jeff Ondich, 9 Jan 2026 Illustrates (barely) the use of command-line arguments and file input by opening the specified file, reading one byte at a time from the file, and reporting the total number of bytes. */ #include void print_usage_statement(const char *program_name); int main(int argc, char *argv[]) { // Parse the command line if (argc != 2) { print_usage_statement(argv[0]); return 1; } const char *input_file_name = argv[1]; // Open the file FILE *input_file = fopen(input_file_name, "r"); if (input_file == NULL) { fprintf(stderr, "Can't open %s for reading\n", input_file_name); return 1; } // Loop through the file one char/byte at a time, counting as we go. int count = 0; char ch = fgetc(input_file); while (ch != EOF) { count++; ch = fgetc(input_file); } // fgetc will return EOF in either of two conditions: the normal // situation where we've finished reading through the file, or the // exceptional situation where there's been some sort of system error // during our attempt to read a byte. To figure out which // situation we're in, we can use either the ferror function or the // feof function. ferror will return true if a system error occurred. // // Error-checking is usually a huge pain in the neck, but it's super-duper // important to do thoroughly. Errors really do occur, and we need to // decide how we want our software to behave when they do. if (ferror(input_file)) { fprintf(stderr, "Error reading %s\n", input_file_name); fclose(input_file); return -1; } // Print the results printf("Number of bytes in %s: %d\n", input_file_name, count); // Clean up after ourselves. fclose(input_file); return 0; } void print_usage_statement(const char *program_name) { fprintf(stderr, "Usage: %s inputfile\n", program_name); fprintf(stderr, " prints to standard output the number of bytes\n"); fprintf(stderr, " (as a decimal integer) in the specified file\n"); }