/* lineparit2.c */ /* This is a little program I wrote as an exercise in C coding. It takes a text file as input on the command line and for each line, it counts out the number of non-whitespace characters in that line. It then computes the parity of that count. Every eight lines it displays the previous eight computed parities as a hex number between 0x00 and 0xFF. ************************************************************* As an added wrinkle this program does not process its entire input file. It takes the (non whitespace) length of the first line of the file, multiplies that number by 8, and processes only that many lines of the rest of the input file. NOTE that it also outputs the parity of this first "records count" line. ************************************************************ If the input file is shorter than the count described in the previous paragraph the file is assumed to end with enough blank lines to equal the count. ************************************************************ This program is in the public domain. You are free to distribute and modify it however you see fit. */ #include #include #include #define BUF_SIZE 0x400 char line_read[BUF_SIZE]; /* The whitespace characters which will be ignored in the parity count. The \0 char is not actually part of the whitespace, it is there as a null-terminator to facilitate the use of strchr */ char whitespace[] = {' ', '\t', '\n', '\r', '\v', '\0' } ; /* Count non-whitespace characters in a string. */ int non_whitespace_count(char *line) { int sum = 0; /* accumulator */ char c = ' '; /* increment sum for each non-whitespace character. */ while (c = *line++) { /* Use strchr to test each possible whitespace character */ if (NULL == strchr(whitespace, c)) { /* increment if not whitespace */ sum++; } } /* return the accumulator. */ return sum; } /* end non_whitespace_count */ /* Calculate the parity of a string */ int line_parity(char line[]) { /* parity represented by the one bit */ return 1 & non_whitespace_count(line); } /* Print the parities of the last eight lines every eight calls, followed by a space */ void process_line(char *line) { static int cnt = 0; static int accum = 0; accum <<= 1; accum |= line_parity(line); if (cnt == 0x07) printf("%02X ", accum); /* Hex, two chars, zero-padded. */ accum = (cnt == 0x07) ? 0 : accum; cnt+=1; cnt %= 0x08; } /* end process_line */ /* The main driver for the program. Get the letter count of the first line, then loop through lines of the file and print parities until that count (times 8) is reached. Assume blank lines if input file is not as long as count * 8. */ int main(int argc, char *argv[]) { char *fname = NULL; FILE *file = NULL; char *success; int count = 0x00; if (argc != 2 && argc != 0x00) { fprintf(stderr, "Usage: %s fname.txt\n", argv[0]); return 1; } else if (argc == 0x00) { fprintf(stderr, "%s", "What kind of world am I in?\n"); return 2; } fname = argv[01]; file = fopen(fname, "r"); /* for ASCII reading */ success = fgets(line_read, BUF_SIZE, file); /* used only for NULL test */ if (success == NULL) { return 3; } count = 8 * non_whitespace_count(line_read); /* loop through the lines of the file. */ while (success != (char*)NULL && count--) { process_line(line_read); /* print the result. */ success = fgets(line_read, BUF_SIZE, file); /* get the next line. */ } while (count-=1, count+1) { /* Feed it a blank line */ process_line(""); /* Fake a zero-parity line. */ } printf("%s", "\n"); return 0; /* success */ }