small simplification.
This commit is contained in:
parent
0b01807f10
commit
aec062db2e
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
## Comparison with wc.
|
## Comparison with wc.
|
||||||
|
|
||||||
The GNU utils version ([github](https://github.com/coreutils/coreutils/tree/master/src/wc), [savannah](http://git.savannah.gnu.org/gitweb/?p=coreutils.git;a=blob;f=src/wc.c;hb=HEAD)) is a bit over 1K lines of C. It does many things and checks many possible failure modes.
|
The GNU utils version ([github](https://github.com/coreutils/coreutils/tree/master/src/wc.c), [savannah](http://git.savannah.gnu.org/gitweb/?p=coreutils.git;a=blob;f=src/wc.c;hb=HEAD)) is a bit over 1K lines of C. It does many things and checks many possible failure modes.
|
||||||
|
|
||||||
The busybox version ([git.busybox.net](https://git.busybox.net/busybox/tree/coreutils/wc.c)) of wc is much shorter, at 257 lines, while striving to be [POSIX-compliant](https://pubs.opengroup.org/onlinepubs/9699919799/), meaning it has flags.
|
The busybox version ([git.busybox.net](https://git.busybox.net/busybox/tree/coreutils/wc.c)) of wc is much shorter, at 257 lines, while striving to be [POSIX-compliant](https://pubs.opengroup.org/onlinepubs/9699919799/), meaning it has flags.
|
||||||
|
|
||||||
|
@ -35,4 +35,4 @@ The plan9port version of wc ([github](https://github.com/9fans/plan9port/blob/ma
|
||||||
- If it doesn't have arguments, read from stdin.
|
- If it doesn't have arguments, read from stdin.
|
||||||
- [ ] Open files, read characters.
|
- [ ] Open files, read characters.
|
||||||
- [ ] Write version that counts lines
|
- [ ] Write version that counts lines
|
||||||
- [ ]
|
- [ ] Document reading from user-inputed stdin (end with Ctrl+D)
|
||||||
|
|
31
ww.c
31
ww.c
|
@ -1,50 +1,47 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
int process_fn(int fn)
|
int wc(FILE* fp)
|
||||||
{
|
{
|
||||||
char c[1];
|
char c[1];
|
||||||
int seen_word = 0;
|
int seen_word = 0, seen_sep_after_word = 0, num_words = 0;
|
||||||
int seen_sep_after_word = 0;
|
int fn = fileno(fp);
|
||||||
int num_words = 0;
|
|
||||||
while (read(fn, c, sizeof(c)) > 0) {
|
while (read(fn, c, sizeof(c)) > 0) {
|
||||||
if (*c != '\n' && *c != ' ' && *c != '\t') {
|
if (*c == '\n' || *c == ' ' || *c == '\t') {
|
||||||
seen_word = 1;
|
if (seen_word) {
|
||||||
} else if (seen_word) {
|
|
||||||
seen_sep_after_word = 1;
|
seen_sep_after_word = 1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// see a separator, but haven't seen a word: do nothing
|
seen_word = 1;
|
||||||
|
}
|
||||||
// exercise: what happens if you only track seen_sep,
|
// exercise: what happens if you only track seen_sep,
|
||||||
// instead of seen_sep_after_word?
|
// instead of seen_sep_after_word?
|
||||||
// test with: $ echo " x x" | ./wc
|
// test with: $ echo " hello world" | ./wc
|
||||||
}
|
|
||||||
if (seen_word && seen_sep_after_word) {
|
if (seen_word && seen_sep_after_word) {
|
||||||
num_words++;
|
num_words++;
|
||||||
seen_sep_after_word = seen_word = 0;
|
seen_sep_after_word = seen_word = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (seen_word) {
|
num_words+=seen_word;
|
||||||
num_words++;
|
|
||||||
}
|
|
||||||
printf("%i\n", num_words);
|
printf("%i\n", num_words);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
if (!isatty(STDIN_FILENO)) {
|
if (argc == 1) {
|
||||||
return process_fn(STDIN_FILENO);
|
return wc(stdin);
|
||||||
} else if (argc > 1) {
|
} else if (argc > 1) {
|
||||||
FILE* fp = fopen(argv[1], "r");
|
FILE* fp = fopen(argv[1], "r");
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
perror("Could not open file");
|
perror("Could not open file");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
fclose(fp);
|
return wc(fp) && fclose(fp);
|
||||||
return process_fn(fileno(fp));
|
|
||||||
} else {
|
} else {
|
||||||
printf("Usage: ww file.txt\n");
|
printf("Usage: ww file.txt\n");
|
||||||
printf(" or: cat file.txt | ww\n");
|
printf(" or: cat file.txt | ww\n");
|
||||||
|
printf(" or: ww # read from user-inputted stdin\n");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user