Compare commits
2 Commits
926eab1a9b
...
d5026e5b76
Author | SHA1 | Date | |
---|---|---|---|
d5026e5b76 | |||
c3ac29d887 |
|
@ -1,6 +1,6 @@
|
|||
# wc: count words in <50 lines of C
|
||||
|
||||
The Unix utility wc counts words. You can make simple, non-POSIX compatible version of it that solely counts words in [158 words and 44 lines of C](https://git.nunosempere.com/personal/wc/src/branch/master/src/wc.c). Or you can be like GNU and take 3615 words and 1034 lines to do something more complex.
|
||||
The Unix utility wc counts words. You can make simple, non-POSIX compatible version of it that solely counts words in [159 words and 42 lines of C](https://git.nunosempere.com/personal/wc/src/branch/master/src/wc.c). Or you can be like GNU and take 3615 words and 1034 lines to do something more complex.
|
||||
|
||||
## Desiderata
|
||||
|
||||
|
@ -23,7 +23,7 @@ The [plan9](https://9p.io/sources/plan9/sys/src/cmd/wc.c) version implements som
|
|||
|
||||
The plan9port version of wc ([github](https://github.com/9fans/plan9port/blob/master/src/cmd/wc.c)) also implements some sort of table method, in 352 lines. It reads from stdin if the number of args is 0, and uses the Linux `read` function to read character by character.
|
||||
|
||||
The [OpenBSD](https://github.com/openbsd/src/blob/master/usr.bin/wc/wc.c) version is just *nice*. It reads from stdin by default, and uses a bit of buffering using read to speed things up. It defaults to using fstat when counting characters. It is generally pleasantly understandable, nice to read.
|
||||
The [OpenBSD](https://github.com/openbsd/src/blob/master/usr.bin/wc/wc.c) version is just *nice*. It reads from stdin by default, and uses a bit of buffering using read to speed things up. It defaults to using fstat when counting characters. It is generally pleasantly understandable, nice to read. I'm actually surprised at how pleasant it is to read.
|
||||
|
||||
The [FreeBSD version](https://cgit.freebsd.org/src/tree/usr.bin/wc/wc.c) sits at 367 lines. It has enough new things that I can't parse all that it's doing: in lines 137-143, what is capabilities mode? what is casper?, but otherwise it decides whether to read from stdin by the number of arguments, in line 157. It uses a combination of fstat and read, depending on the type of file.
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ int chc(FILE* fp)
|
|||
register int c;
|
||||
int num_chars = 0;
|
||||
while ((c = getc(fp)) != EOF) {
|
||||
num_chars ++;
|
||||
num_chars++;
|
||||
}
|
||||
printf("%i\n", num_chars);
|
||||
return 0;
|
||||
|
@ -22,7 +22,7 @@ int main(int argc, char** argv)
|
|||
perror("Could not open file");
|
||||
return 1;
|
||||
}
|
||||
return chc(fp) && fclose(fp);
|
||||
return chc(fp) && fclose(fp);
|
||||
} else {
|
||||
printf("Usage: chc file.txt\n");
|
||||
printf(" or: cat file.txt | chc\n");
|
||||
|
|
|
@ -6,11 +6,11 @@ int lc(FILE* fp)
|
|||
int num_lines = 0;
|
||||
register int c;
|
||||
while ((c = getc(fp)) != EOF) {
|
||||
if (c == '\n' ) {
|
||||
num_lines ++;
|
||||
if (c == '\n') {
|
||||
num_lines++;
|
||||
}
|
||||
}
|
||||
// num_lines += (c != '\n'); // < judgment call, adds a line if the last line isn't followed by a newline.
|
||||
// num_lines += (c != '\n'); // < judgment call, adds a line if the last line isn't followed by a newline.
|
||||
printf("%i\n", num_lines);
|
||||
return 0;
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ int main(int argc, char** argv)
|
|||
perror("Could not open file");
|
||||
return 1;
|
||||
}
|
||||
return lc(fp) && fclose(fp);
|
||||
return lc(fp) && fclose(fp);
|
||||
} else {
|
||||
printf("Usage: lc file.txt\n");
|
||||
printf(" or: cat file.txt | lc\n");
|
||||
|
|
20
src/wc.c
20
src/wc.c
|
@ -8,14 +8,12 @@ int wc(FILE* fp)
|
|||
while ((c = getc(fp)) != EOF) {
|
||||
if (c != ' ' && c != '\n' && c != '\t') {
|
||||
word = 1;
|
||||
} else {
|
||||
if (word) {
|
||||
num_words++;
|
||||
word = 0;
|
||||
}
|
||||
} else if (word) {
|
||||
num_words++;
|
||||
word = 0;
|
||||
}
|
||||
}
|
||||
num_words+=word;
|
||||
num_words += word;
|
||||
printf("%i\n", num_words);
|
||||
return 0;
|
||||
}
|
||||
|
@ -30,11 +28,11 @@ int main(int argc, char** argv)
|
|||
perror("Could not open file");
|
||||
return 1;
|
||||
}
|
||||
int wc_status = wc(fp);
|
||||
int fclose_status = fclose(fp);
|
||||
return (wc_status == 0) && (fclose_status ==0);
|
||||
// can't do return wc_status == 0 && fclose_status == 0;
|
||||
// because then if wc returns with -1, fclose is not called.
|
||||
int wc_status = wc(fp);
|
||||
int fclose_status = fclose(fp);
|
||||
return (wc_status == 0) && (fclose_status == 0);
|
||||
// can't do return wc_status == 0 && fclose_status == 0;
|
||||
// because then if wc returns with -1, fclose is not called.
|
||||
} else {
|
||||
printf("Usage: wc file.txt\n");
|
||||
printf(" or: cat file.txt | wc\n");
|
||||
|
|
Loading…
Reference in New Issue
Block a user