К вашему сведению - у нас есть демонстрационный пример, который использует Design Automation для обновления старых файлов:
https://github.com/Autodesk-Forge/design.automation-nodejs-revit. file.upgrader
Средство просмотра и производная модели не поддерживает старые файлы rvt. Это также будет полезно для просмотра.
Да, это безопасное преобразование. С требует, чтобы это работало. Эта гарантия содержится в параграфе 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» является правильным способом сделать это. Я просто хотел показать, как рекомендуется стандартный подход преобразования числа в виде строки в «истину»
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 */
}
Это преобразует один шестнадцатеричный символ, независимо от прописных или строчных букв, в целое число.
Вы можете использовать atoi
, который является частью стандартной библиотеки.
Поскольку вы конвертируете только один символ, функция 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 и ниже в основном одинаковы. Это будет включать символы, которые представляют числа. Это означает, что предложенная вами базовая математика должна работать на то, чего вы пытались достичь.
Да. Это безопасно, если вы используете стандартные символы ascii, как в этом примере.
Обычно, если нет гарантии, что ваш вход находится в диапазоне '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 Я знаю , что это перебор . Я просто хотел представить его как альтернативное решение, которое может быть не сразу очевидным.