Символ к международному преобразованию в C

К вашему сведению - у нас есть демонстрационный пример, который использует Design Automation для обновления старых файлов:

https://github.com/Autodesk-Forge/design.automation-nodejs-revit. file.upgrader

Средство просмотра и производная модели не поддерживает старые файлы rvt. Это также будет полезно для просмотра.

35
задан Binary Worrier 23 April 2009 в 15:34
поделиться

7 ответов

Да, это безопасное преобразование. С требует, чтобы это работало. Эта гарантия содержится в параграфе 2 параграфа 5.2.1 самого последнего стандарта ISO C, последняя версия которого N1570 :

И базовый, и базовый наборы символов исполнения должны иметь следующие Участники:
[...]
10 десятичных цифр
0 1 2 3 4 5 6 7 8 9
[...]
В исходных и исполнительных базовых наборах символов значение каждого символа после 0 в приведенном выше списке десятичных цифр должно быть на единицу больше, чем значение предыдущего.

И ASCII, и EBCDIC, и наборы символов, полученные из них, удовлетворяют этому требованию, поэтому стандарт C смог навязать его. Обратите внимание, что буквы не являются смежными с iN EBCDIC, и C их не требует.

Нет библиотечной функции для этого для одного символа , вам потребуется сначала построим строку:

int digit_to_int(char d)
{
 char str[2];

 str[0] = d;
 str[1] = '\0';
 return (int) strtol(str, NULL, 10);
}

Вы также можете использовать функцию atoi () , чтобы выполнить преобразование, если у вас есть строка, но strtol () лучше и безопаснее.

Тем не менее, как отметили комментаторы, вызывать функцию для этого преобразования крайне сложно; Ваш первоначальный подход к вычитанию «0» является правильным способом сделать это. Я просто хотел показать, как рекомендуется стандартный подход преобразования числа в виде строки в «истину»

27
ответ дан 27 November 2019 в 07:17
поделиться

Попробуйте:

char c = '5' - '0';
9
ответ дан 27 November 2019 в 07:17
поделиться
int i = c - '0';

Вы должны знать, что это не выполняет никакой проверки персонажа - например, если символ был «а», вы получите 91 - 48 = 49. Особенно, если вы Имея дело с пользовательским или сетевым вводом, вы, вероятно, должны выполнить проверку, чтобы избежать плохого поведения в вашей программе. Просто проверьте диапазон:

if ('0' <= c &&  c <= '9') {
    i = c - '0';
} else {
    /* handle error */
}

Обратите внимание, что если вы хотите, чтобы ваше преобразование обрабатывало шестнадцатеричные цифры, вы могли проверить диапазон и выполнить соответствующий расчет.

if ('0' <= c && c <= '9') {
    i = c - '0';
} else if ('a' <= c && c <= 'f') {
    i = 10 + c - 'a';
} else if ('A' <= c && c <= 'F') {
    i = 10 + c - 'A';
} else {
    /* handle error */
}

Это преобразует один шестнадцатеричный символ, независимо от прописных или строчных букв, в целое число.

5
ответ дан 27 November 2019 в 07:17
поделиться

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

5
ответ дан 27 November 2019 в 07:17
поделиться

Поскольку вы конвертируете только один символ, функция atoi () является избыточной. atoi () полезна, если вы конвертируете строковые представления чисел. Другие посты привели примеры этого. Если я правильно прочитал ваш пост, вы конвертируете только один числовой символ. Таким образом, вы собираетесь преобразовать только символ в диапазоне от 0 до 9. В случае преобразования только одного числового символа, ваше предложение вычесть «0» даст вам желаемый результат. Это работает потому, что значения ASCII являются последовательными (как вы сказали). Таким образом, вычитая значение ASCII 0 (значение ASCII 48 - значения см. В ASCII Table ) из числового символа, получим значение числа. Итак, ваш пример c = c - '0', где c = '5', на самом деле происходит 53 (значение ASCII 5) - 48 (значение ASCII 0) = 5.

Когда я впервые опубликовал этот ответ, я не принял во внимание ваш комментарий о том, что между разные наборы символов. Я еще немного огляделся вокруг, и кажется, что ваш ответ все еще в основном правильный. Проблема в том, что вы используете символ, который является 8-битным типом данных. Который не будет работать со всеми типами символов. Прочитайте эту статью Джоэла Спольски о Unicode для более подробной информации о Unicode. В этой статье он говорит, что он использует wchar_t для символов. Это хорошо сработало для него, и он публикует свой веб-сайт на 29 языках. Итак, вам нужно изменить свой символ на wchar_t. Кроме этого, он говорит, что символы со значением 127 и ниже в основном одинаковы. Это будет включать символы, которые представляют числа. Это означает, что предложенная вами базовая математика должна работать на то, чего вы пытались достичь.

2
ответ дан 27 November 2019 в 07:17
поделиться

Да. Это безопасно, если вы используете стандартные символы ascii, как в этом примере.

1
ответ дан 27 November 2019 в 07:17
поделиться

Обычно, если нет гарантии, что ваш вход находится в диапазоне '0' .. '9', вам необходимо выполнить проверку следующим образом:

if (c >= '0' && c <= '9') {
    int v = c - '0';
    // safely use v
}

Альтернативой является используйте таблицу поиска. Вы получаете простую проверку диапазона и преобразование с меньшим (и, возможно, более быстрым) кодом:

// one-time setup of an array of 256 integers;
// all slots set to -1 except for ones corresponding
// to the numeric characters
static const int CHAR_TO_NUMBER[] = {
    -1, -1, -1, ...,
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // '0'..'9'
    -1, -1, -1, ...
};

// Now, all you need is:

int v = CHAR_TO_NUMBER[c];

if (v != -1) {
    // safely use v
}

PS Я знаю , что это перебор . Я просто хотел представить его как альтернативное решение, которое может быть не сразу очевидным.

0
ответ дан 27 November 2019 в 07:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: