/** * This is a solution to the numcat problem. * It does not: * - indent the numbers the right way; * - report all the errors the right way. */ #include <string.h> #include <unistd.h> #include <fcntl.h> #include <sys/types.h> #include <stdlib.h> #define BUFFSIZE 4096 char buff[BUFFSIZE]; int number = 2; /** * A simple function to reverse some part of a string */ void reverse(char *start, char *end) { char x; while (start < end) { x = *start; *start = *end; *end = x; start++; end--; } } /** * A simple function to print a number in a string. * It also adds a tab before the string and a space after it. */ char *itostr(int n, char *result) { int i = 1; result[0] = '\t'; while (n) { result[i++] = n%10 + '0'; n/=10; } reverse(&result[1], &result[i-1]); result[i] = ' '; result[i+1] = 0; return result; } /** * A function to process the buffer after each read. * It splits it in new lines and writes the number and * the line. */ void output(char *buf, int start, int end) { int i; char x[10]; for (i=start;i<end;i++) { if (buf[i]=='\n') { write(1, &buf[start], i+1-start); itostr(number++, x); write(1, x, strlen(x)); start = i + 1; } } write(1, buf + start, end - start); } int main(int argc, char **argv) { if (argc < 2) { write(2, "Usage: numcat filename\n", 11); exit(EXIT_FAILURE); } int fd = open(argv[1], O_RDONLY); if (fd == -1) { write(2,"hmm..\n",6); exit(EXIT_FAILURE); } ssize_t read_bytes; write(1, "\t1 ",3); while (1) { read_bytes = read(fd, buff, BUFFSIZE); if (read_bytes == -1) { write(2, "Error!\n", 7); exit(EXIT_FAILURE); } if (read_bytes == 0) { write(1, "\n", 1); exit(EXIT_SUCCESS); } output(buff, 0, read_bytes); } return 0; }