#include <stdio.h>
#include <ctype.h> //isprint
//compile with: gcc -Wall -Wextra cc-c.c -o cc-c
//run with: printf 'tab\there, bell\a, esc\033[0m\n' | ./cc-c
// head -c 200 /dev/urandom | ./cc-c # raw binary
// ./cc-c < cc-c.c # ordinary text
//K&R2 exercise 7-2: print arbitrary input "in a sensible way".
//Graphic characters (isprint) go through as-is; anything else except
//newline is shown as a C-style octal escape, \ooo -- octal is the Unix
//custom (od, \033 in C strings, cat -v's cousin). Lines longer than
//MAXCOL columns are broken, and an escape is never split across a break.
#define MAXCOL 80 //maximum output columns per line
#define OCTLEN 4 //width of one escape: backslash + 3 octal digits
int inc(int pos, int n);
int main(void)
{
int c;
int pos = 0; //columns used on the current line
while ((c = getchar()) != EOF)
if (c == '\n') { //a real line end: keep it, reset
putchar('\n');
pos = 0;
} else if (isprint(c)) {
pos = inc(pos, 1);
putchar(c);
} else {
//getchar returns an unsigned char value (0..255) as an int,
//so it never needs more than 3 octal digits (255 = \377).
//%03o pads with zeros: 7 -> "007", so every escape is 4 wide
pos = inc(pos, OCTLEN);
printf("\\%03o", c);
}
return 0;
}
//inc: room for n more columns? If not, break the line first.
//Returns the new column position.
int inc(int pos, int n)
{
if (pos + n > MAXCOL) {
putchar('\n');
return n;
}
return pos + n;
}
win@DESKTOP-MEIH88T:~/webdev-projects$ gcc -Wall -Wextra cc-c.c -o cc-c
win@DESKTOP-MEIH88T:~/webdev-projects$ printf 'tab\there, bell\a, esc\033[0m\n' | ./cc-c
tab\011here, bell\007, esc\033[0m