Exercise 7-2. Write a program that will print arbitrary input in a sensible way. As a minimum, it should print non-graphic characters in octal or hexadecimal according to local custom, and break long text lines.
#include <stdio.h> // for getchar(), putchar(), printf(), EOF
#include <ctype.h> // for isgraph(), isspace(), ispunct()
enum {OCTAL, HEX};
int main(int argc, char *argv[])
{
int c, count;
int print = OCTAL; // default
while (--argc > 0 && (*++argv)[0] == '-') // optional arguments
{
while (c = *++argv[0]) // -x, -xx, -x -x, etc.
{
switch(c)
{
case 'x' :
print = HEX;
break;
default:
printf("Illegal option: '%c'\n", c);
printf("Usage : ./print -x\n");
printf("-x - print non-graph chars in hex (default octal)\n");
return 1; // end program, signalling error
}
}
}
if (argc) // if (argc > 0)
{
printf("Usage : ./print -x\n");
printf("-x - print non-graph chars in hex (default octal)\n");
return 1; // end program, signalling error
}
count = 0; // initialize
while ((c = getchar()) != EOF)
{
count++;
if(!isgraph(c))
{
if (!isblank(c) && c != '\n')
{
count++;
if(print == OCTAL)
{
printf("%o", c);
if (c >= 64) {count++;} // 3 octal digits
}
else // if(print == HEX)
{printf("%x", c);}
}
else if (isblank(c)) // ' ' or '\t'
{putchar(c);}
if (c == '\n')
{
putchar(c); // putchar('\n');
count = 0; // reset for each new line
}
else if (isspace(c) && count >= 70)
{
putchar('\n');
count = 0; // reset for each new line
}
}
else // graphic char
{
putchar(c);
if ((ispunct(c) && count >= 70) || count >= 75)
{
putchar('\n');
count = 0; // reset for each new line
}
}
}
return 0;
}
/*
gcc print.c -o print
./print c
Usage : ./print -x
-x - print non-graph chars in hex (default octal)
./print -c
Illegal option: 'c'
Usage : ./print -x
-x - print non-graph chars in hex (default octal)
./print // Input from keyboard
mÄÕä©<µ19»è // from the binary file
m303204303225303244302251<30221030226519302215302273303250 // octal
// Ctrl^D in Linux, Ctrl^Z+Enter in Windows (EOF)
./print -x // Input from keyboard
mÄÕä©<µ19»è // from the binary file
mc384c395c3a4c2a9<c288c2b519c28dc2bbc3a8 // hex
// Ctrl^D in Linux, Ctrl^Z+Enter in Windows (EOF)
./print < print.c > copy1.c // Input source file
./print -x < print.c > copy2.c
./print < print > copy1.txt // Input binary file
./print -x < print > copy2.txt
rm copy* // clean
*/