#include #include #include #include #include /* cmd arguments l - lines c - bytes w - words */ unsigned int l_flag; unsigned int c_flag; unsigned int w_flag; unsigned int words; unsigned int bytes; unsigned int lines; /* Total */ unsigned int twords; unsigned int tbytes; unsigned int tlines; void count(const int fd) { char buf[4096]; ssize_t n = 0; int in_word = 1; while ((n = read(fd, buf, sizeof(buf))) > 0) { bytes += n; for (ssize_t i = 0; i < n; i++) { if (buf[i] == '\n') lines++; if (buf[i] == ' ' || buf[i] - '\t' < 5) { if (!in_word) { in_word = 1; words++; } } else in_word = 0; } } tbytes += bytes; twords += words; tlines += lines; } void print_count(const char *path, unsigned int plines, unsigned int pwords, unsigned int pbytes) { if (l_flag) printf("%u ", plines); if (w_flag) printf("%u ", pwords); if (c_flag) printf("%u", pbytes); printf(" %s\n", path); } int main(int argc, char **argv) { int opt; while ((opt = getopt(argc, argv, "lcw")) != -1) { switch (opt) { case 'l': l_flag = 1; break; case 'c': c_flag = 1; break; case 'w': w_flag = 1; break; default: printf("wc [file1 file2...]\n\t[-l Lines] [-c Bytes] [-w Words]\n"); return 0; } } argv += optind; argc -= optind; if (!w_flag && !l_flag && !c_flag) { w_flag = 1; l_flag = 1; c_flag = 1; } if (argc == 0 || argv[0][0] == '-') { count(STDIN_FILENO); print_count("", lines, words, bytes); return 0; } for (int i = 0; i < argc; i++) { int fd = open(argv[i], O_RDONLY); if (fd < 0) { fprintf(stderr, "wc: %s\n", strerror(errno)); return 1; } count(fd); if (i == argc - 1) print_count("total", tlines, twords, tbytes); else print_count(argv[i], lines, words, bytes); close(fd); words = bytes = lines = 0; } return 0; }