====== Утилита ascii - выдача таблицы символов ======
Много лет назад, изучая язык Си, я написал простейшую программу,
показывающую таблицу кодировки символов:
#include
int main ()
{
int i, j, c;
for (i=' '; i<256; i+=8) {
for (j=0; j<8; ++j) {
c = i + j;
printf (" %03o %c ", c, c);
}
printf ("\r\n");
}
return 0;
}
В нынешнее время жизнь усложнилась. Все переходят на Unicode,
стиль параметров GNU и т.п. Пришлось утилиту несколько доработать.
Вот что получилось:
#include
#include
#include
#include
#include
/* Table of options. */
struct option longopts[] = {
/* option has arg integer code */
{ "help", 0, 0, 'h' },
{ "version", 0, 0, 'V' },
{ "octal", 0, 0, 'o' },
{ "hex", 0, 0, 'x' },
{ "decimal", 0, 0, 'd' },
{ 0, 0, 0, 0 },
};
void usage ()
{
fprintf (stderr, "ascii utility, version 2.0, Copyright (GPL) Serge Vakulenko\n");
fprintf (stderr, "\n");
fprintf (stderr, "Usage:\n");
fprintf (stderr, " ascii [options] [encoding]\n");
fprintf (stderr, "Options:\n");
fprintf (stderr, " -d, --decimal show decimal character codes (default)\n");
fprintf (stderr, " -o, --octal show octal character codes\n");
fprintf (stderr, " -x, --hex show hexadecimal character codes\n");
fprintf (stderr, "\n");
fprintf (stderr, "For list of available encodings, run `iconv -l'\n");
exit (1);
}
int main (int argc, char **argv)
{
int i, j, n, base;
char *encoding, *local, *p, *outp, buf [32];
unsigned char c;
size_t out_bytes_left, in_bytes_left;
iconv_t cv;
base = 10;
for (;;) {
i = getopt_long (argc, argv, "hVdox", longopts, 0);
if (i < 0)
break;
switch (i) {
case 'h': /* help */
usage ();
break;
case 'V': /* version */
printf ("Version: 2.0\n");
return 0;
case 'd': /* decimal */
base = 10;
break;
case 'o': /* octal */
base = 8;
break;
case 'x': /* hex */
base = 16;
break;
}
}
if (optind < argc-1 || optind > argc)
usage ();
if (optind == argc-1)
encoding = argv[optind];
else
encoding = "ascii";
/* Get local encoding. */
local = getenv ("LANG");
if (! local)
#ifdef __CYGWIN__
local = "cp1251";
#else
local = "utf-8";
#endif
/* Strip optional modifier. */
p = strchr (local, '@');
if (p)
*p = 0;
/* Get codeset. */
p = strchr (local, '.');
if (p)
local = p+1;
cv = iconv_open (local, encoding);
if (cv < 0) {
perror ("iconv_open");
exit (1);
}
/* Print table of characters. */
for (i=' '; i<256; i+=8) {
for (j=0; j<8; ++j) {
c = i + j;
/* Convert a symbol to local encoding. */
p = (char*) &c;
in_bytes_left = 1;
outp = buf;
out_bytes_left = sizeof (buf);
n = iconv (cv, &p, &in_bytes_left,
&outp, &out_bytes_left);
if (n != 0) {
if (c == ' ') {
fprintf (stderr, "%s: unknown encoding\n",
encoding);
exit (1);
}
if (j == 0) {
/* Invalid first symbol.
* Ignore this line. */
break;
}
buf[0] = '?';
n = 1;
} else
n = sizeof (buf) - out_bytes_left;
switch (base) {
default:
case 10: printf ( " %3d", c); break;
case 8: printf ( " %03o", c); break;
case 16: printf ("0x%02x", c); break;
}
printf (" %.*s ", n, buf);
}
if (j != 0)
printf ("\r\n");
}
iconv_close (cv);
return 0;
}
Можно запросить любую таблицу кодировке из имеющихся в операционной
системе, по умолчанию выдается ASCII. Данные формируются в локальной
кодировке, зависящей от переменной окружения LANG. Есть возможность
выдавать коды в десятичной, восьмеричной или шестнадцатеричной системе.
Итого 136 строк против 15-ти --- цена универсальности. Скачать файл с исходными
текстами можно отсюда: {{ascii.c}}.
Ну и стандартная отмазка GPL, без этого нынче никак:
//Данная программа является свободным программным обеспечением
и вы можете распространять ее в соответствии с условиями
[[http://www.infolex.narod.ru/gpl_gnu/gplrus.html |
Стандартной Общественной Лицензии GNU]].//