I am writing a cat command clone in C and I'm getting weird behavior when I change the order of my option flags.
The -s option flag squeezes double-spaced lines.
The -n option flag numbers every line starting at 1.
I've checked the difference of running my program in the following ways:
$ diff <(./myCat -s spaces.txt) <(cat -s spaces.txt)
no difference
$ diff <(./myCat -n spaces.txt) <(cat -n spaces.txt)
no difference
$ diff <(./myCat -ns spaces.txt) <(cat -ns spaces.txt)
no difference
running ./myCat -sn spaces.txt, however, only squeezes the text and does not number the lines.
Can anyone explain this behavior? I thought the order of option flags did not matter in this case.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char **argv) {
FILE *fp;
const int bufferSize = 4096;
char buffer[bufferSize];
int currentFile = 0;
for (int i = 1; i < argc; i++) {
if (argv[i][0] != '-') {
currentFile = i;
break;
}
}
int bflag = 0, eflag = 0, nflag = 0, sflag = 0;
int opt;
while ((opt = getopt(argc, argv, "bens:?")) != -1) {
switch(opt) {
case 'b':
bflag++;
break;
case 'e':
eflag++;
break;
case 'n':
nflag++;
break;
case 's':
sflag++;
break;
case ':':
printf("option needs a value\n");
exit(1);
case '?':
printf("usage: cat [-bens] [file ...]\n");
exit(1);
}
}
while (currentFile < argc) {
if (currentFile) {
fp = fopen(argv[currentFile], "rb");
if (fp == NULL) {
fprintf(stderr, "%s: %s: No such file or directory",
argv[0], argv[currentFile]);
exit(1);
}
}
int lineNumber = 1;
int lastLineBlank = 0;
while (fgets(buffer, bufferSize, (fp == NULL ? stdin : fp))) {
int length = strlen(buffer);
buffer[length - 1] = '\0';
if (sflag) {
length = strlen(buffer);
int currentLineBlank = (length <= 1) ? 1 : 0;
if (lastLineBlank && currentLineBlank) {
continue;
}
lastLineBlank = currentLineBlank;
}
if (bflag) {
length = strlen(buffer);
if (length >= 1) {
char *tmp = strdup(buffer);
buffer[0] = '\0';
sprintf(buffer, "%*d\t", 6, lineNumber++);
strcat(buffer, tmp);
}
} else
if (nflag) {
char *tmp = strdup(buffer);
buffer[0] = '\0';
sprintf(buffer, "%*d\t", 6, lineNumber++);
strcat(buffer, tmp);
}
if (eflag) {
length = strlen(buffer);
buffer[length] = '$';
buffer[length + 1] = '\0';
}
fprintf(stdout, "%s\n", buffer);
}
fclose(fp);
currentFile++;
}
return 0;
}