C Newbie, функция управления ASCII - PullRequest
2 голосов
/ 11 января 2011

Я написал программу, которая хорошо работает на C, которая преобразует нечитаемый ASCII в их символьные значения.Буду признателен, если мастер C?показал бы мне лучший способ сделать это, что я сделал в настоящее время, в основном этот раздел:

if (isascii(ch)) {
    switch (ch) {
        case 0:
            printControl("NUL");
            break;
        case 1:
            printControl("SOH");
            break;

        .. etc (32 in total)

        case default:
            putchar(ch);
            break;
    }
}

Это нормально, чтобы сделать такой большой переключатель?Или я должен использовать какой-то другой метод (вход из таблицы ASCII?)

Ответы [ 4 ]

3 голосов
/ 11 января 2011

Если вы всегда выполняете одну и ту же операцию (например, putchar), вы можете просто статически инициализировать массив, который сопоставляется тому, что должен отображаться каждый символ. Затем вы можете получить доступ к правильному значению сопоставления, аккуратно обращаясь к массиву по смещению входящего символа.

Например, (в псевдокоде - прошло много времени с тех пор, как я написал на C), вы должны определить:

const char* [] map = {"NUL", "SOH, ...};

, а затем индексируйте это с помощью чего-то вроде:

const char* val = map[((int)ch)];

чтобы получить ваше значение.

Вы не сможете использовать это, если ваши значения "from" не являются последовательными; в этом случае вам потребуется несколько условных блоков. Но если вы можете использовать последовательность, вы должны.

1 голос
/ 11 января 2011

Слишком много лет назад, когда я проводил свое время на языках ассемблера для 8-битных микросхем, я написал бы что-то вроде

printf("%3.3s", 
       ("NULSOHSTXETXEOTENQACKBELBS HT LF VT FF CR SO SI "
        "DLEDC1DC2DC3DC4NAKSYNETBCANEM SUBESCFS GS RS US ")[3*ch]);

, но не потому, что это особенно лучше.И умножение на три раздражает, потому что 8-битные микро не умножаются, так что это потребовало бы как сдвига, так и добавления, а также запасного регистра.

Намного более C-подобный результат будетиспользовать таблицу с четырьмя байтами на элемент управления, включая байты NUL.Это позволяет указывать каждую запись как строковую константу, но экономит дополнительное хранилище для 32 указателей.

const char *charname(int ch) {
    if (ch >= 0 && ch <= 0x20)
        return ("NUL\0"  "SOH\0"  "STX\0"  "ETX\0"  /* 00..03 */
                "EOT\0"  "ENQ\0"  "ACK\0"  "BEL\0"  /* 04..07 */
                "BS\0\0" "HT\0\0" "LF\0\0" "VT\0\0" /* 08..0B */
                "FF\0\0" "CR\0\0" "SO\0\0" "SI\0\0" /* 0C..0F */
                "DLE\0"  "DC1\0"  "DC2\0"  "DC3\0"  /* 10..13 */
                "DC4\0"  "NAK\0"  "SYN\0"  "ETB\0"  /* 14..17 */
                "CAN\0"  "EM\0\0" "SUB\0"  "ESC\0"  /* 18..1B */
                "FS\0\0" "GS\0\0" "RS\0\0" "US\0\0" /* 1C..1F */
                "SP\0\0") + (ch<<2);                /* 20 */
    if (ch == 0x7f)
        return "DEL";
    if (ch == EOF)
        return "EOF";
    return NULL;
}

Я попытался отформатировать основную таблицу, чтобы ее организация была понятной.Функция возвращает NULL для символов, которые называют себя или не являются 7-битными ASCII.В противном случае он возвращает указатель на ASCII-строку, оканчивающуюся NUL, содержащую условное сокращение этого управляющего символа, или «EOF» для не-символа EOF, возвращаемого стандартными процедурами ввода-вывода C в конце файла.* Обратите внимание на усилия, приложенные для заполнения каждого слота имени персонажа ровно четырьмя байтами.Это тот случай, когда создание этой таблицы с использованием языка сценариев или отдельной программы было бы хорошей идеей.В этом случае простой ответ - построить таблицу из 129 записей (или 257 записей), содержащую имена всех 7-битных символов ASCII (или 8-битных расширений в вашей предпочтительной кодовой странице) с дополнительным слотом для * 1012.*.

См. Источники функций, объявленных в <ctype.h>, для примера обработки дополнительного пространства для EOF.

0 голосов
/ 11 января 2011

Я бы сказал, создайте таблицу с vals (0-32) и соответствующей им управляющей строкой ("NUL", "SOH"). (В этом случае для таблицы требуется только массив)

Затем вы можете просто проверить, находится ли он в диапазоне индекса в таблице, чтобы получить строку для передачи вашей функции printControl ().

0 голосов
/ 11 января 2011

Вы можете сделать переключение таким большим, но им становится немного сложно управлять.

Я хотел бы подойти к этому так: построить массив с char c; char* ctrl; для каждого элемента. Тогда вы можете просто перебрать массив. Это немного облегчит ведение данных.

Обратите внимание, что если вы используете каждый символ в определенном диапазоне (например, символы от 0 до 32), тогда вашему массиву потребуется только имя, и нет необходимости хранить значение символа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...