#include FILE *f; main(int argc, char ** argv) { int c, c1, c2; unsigned int r; char buf[8]; if (argc > 2) { fprintf(stderr, "Usage: %s [ file ]\n", argv[0]); return; } if (argc == 2) { f = fopen(argv[1],"r"); if (f == NULL) { fprintf(stderr, "Can't open %s\n", argv[1]); return; } } else { f = stdin; } while ((c = getc(f)) != EOF) { if (c < 0x80) putchar(c); else if ((c & 0xe0) == 0xc0) { /* two-char rune */ c1 = c; r = (c & 0x1f) << 6; if ((c = getc(f)) == EOF) { fprintf(stderr, "EOF in rune\n"); putchar(c1); break; } if ((c & 0xc0) != 0x80) { fprintf(stderr, "Bad rune %x, %x\n", r, c); putchar(c1); putchar(c); continue; } r = r | (c & 0x3f); if (r < 0x100) putchar(r); else { fprintf(stderr, "Rune too big %x\n", r); putchar(c1); putchar(c); } } else if ((c & 0xf0) == 0xe0) { /* three-char rune */ r = (c & 0xf) << 12; c1 = c; if ((c = getc(f)) == EOF) { fprintf(stderr, "EOF in rune\n"); putchar(c1); break; } if ((c & 0xc0) != 0x80) { fprintf(stderr, "Bad rune %x, %x\n", r, c); putchar(c1); putchar(c); continue; } c2 = c; r = r | ((c & 0x3f) << 6); if ((c = getc(f)) == EOF) { fprintf(stderr, "EOF in rune\n"); putchar(c1); putchar(c2); break; } if ((c & 0xc0) != 0x80) { fprintf(stderr, "Bad rune %x, %x\n", r, c); putchar(c1); putchar(c2); putchar(c); continue; } r = r | (c & 0x3f); if (r < 0x100) putchar(r); else { fprintf(stderr, "Rune too big %x\n", r); putchar(c1); putchar(c2); putchar(c); } } else { fprintf(stderr, "Bad rune %x, %x\n", r, c); putchar(c); } } fflush(f); return; }