Char для преобразования int в C
Если я хочу преобразовать одно числовое число char
в это числовое значение, например, если:
char c = '5';
и я хочу, чтобы c
удерживал 5
вместо '5'
, он на 100% переносится так, как это?
c = c - '0';
Я слышал, что все наборы символов сохраняют числа в последовательном порядке, поэтому я так предполагаю, но я хотел бы знать, есть ли организованная библиотечная функция для этого преобразования и как это делается традиционно. Я настоящий новичок:)
Ответы
Ответ 1
Да, это безопасное преобразование. C требует, чтобы он работал. Эта гарантия содержится в разделе 5.2.1 параграфа 2 последнего стандарта ISO C, последний проект которого N1570:
Оба базовых набора символов основного и основного исполнений должны иметь следующее Участники:
[...]
10 десятичных цифр
0 1 2 3 4 5 6 7 8 9
[...]
Как в базовых наборах символов источника, так и для исполнения значение каждого символа после 0 в приведенном выше списке десятичных цифр должно быть больше, чем значение предыдущего.
И ASCII, и EBCDIC, и наборы символов, полученные из них, удовлетворяют этому требованию, поэтому стандарт C смог навязать его. Обратите внимание, что буквы не смежны iN EBCDIC, а C не требует их.
Нет никакой функции библиотеки, чтобы сделать это для одного char
, вам нужно сначала создать строку:
int digit_to_int(char d)
{
char str[2];
str[0] = d;
str[1] = '\0';
return (int) strtol(str, NULL, 10);
}
Вы также можете использовать функцию atoi()
для преобразования, как только у вас есть строка, но strtol()
лучше и безопаснее.
Как уже отмечали комментаторы, экстремальным излишеством является вызов функции для этого преобразования; ваш первоначальный подход к вычитанию "0" - это правильный способ сделать это. Я просто хотел показать, как здесь будет использоваться рекомендованный стандартный подход к преобразованию числа в виде строки в "истинный" номер.
Ответ 2
Попробуйте следующее:
char c = '5' - '0';
Ответ 3
Вы можете использовать atoi
, который является частью стандартной библиотеки.
Ответ 4
int i = c - '0';
Вы должны знать, что это не выполняет никакой проверки против символа - например, если символ был "a", тогда вы получите 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
Поскольку вы только конвертируете один символ, функция atoi() переполнена. atoi() полезен, если вы преобразовываете строковые представления чисел. На других примерах приведены примеры этого. Если я правильно прочитал ваше сообщение, вы преобразовываете только один цифровой символ. Таким образом, вы собираетесь преобразовать символ, который находится в диапазоне от 0 до 9. В случае преобразования только одного числового символа ваше предложение вычесть "0" даст вам результат, который вы хотите. Причина этого заключается в том, что значения ASCII являются последовательными (как вы сказали). Таким образом, вычитая значение ASCII 0 (значение ASCII 48 - см. ASCII Table для значений) от числового символа будет выдавать значение числа, Итак, ваш пример c = c - '0', где c = '5', то, что действительно происходит, 53 (значение ASCII 5) - 48 (значение ASCII 0) = 5.
Когда я впервые опубликовал этот ответ, я не принял во внимание ваш комментарий о том, что он на 100% переносится между разными наборами символов. Я немного поглядел вокруг, и кажется, что ваш ответ по-прежнему в основном правилен. Проблема в том, что вы используете char, который является 8-битным типом данных. Это не будет работать со всеми типами символов. Прочтите эту статью Joel Spolsky в Юникоде для получения более подробной информации о Unicode. В этой статье он говорит, что использует символы wchar_t для символов. Это хорошо сработало для него, и он публикует свой веб-сайт на 29 языках. Итак, вам нужно будет изменить ваш char на wchar_t. Помимо этого, он говорит, что персонаж под значением 127 и ниже в основном тот же. Это будет включать символы, которые представляют числа. Это означает, что основная математика, которую вы предложили, должна работать на то, чего вы пытались достичь.
Ответ 6
Да. Это безопасно, если вы используете стандартные символы ascii, например, вы находитесь в этом примере.
Ответ 7
Обычно, если нет гарантии, что ваш вход находится в диапазоне "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
}
P.S. Я знаю, что это перебор. Я просто хотел представить его в качестве альтернативного решения, которое может не сразу проявиться.
Ответ 8
Как предлагали другие, но завернуты в функцию:
int char_to_digit(char c) {
return c - '0';
}
Теперь просто используйте функцию. Если, по линии, вы решили использовать другой метод, вам просто нужно изменить реализацию (производительность, различия между наборами символов и т.д.), Вам не нужно будет изменять вызывающих абонентов.
В этой версии предполагается, что c содержит char, который представляет цифру. Вы можете проверить это до вызова функции, используя функцию ctype.h isdigit.
Ответ 9
Так как коды ASCII для '0', '1', '2'.... помещаются от 48 до 57, они по существу непрерывны. Теперь для арифметических операций требуется преобразование типа данных char в int datatype.Hence, что вы в основном делаете:
53-48 и, следовательно, он сохраняет значение 5, с помощью которого вы можете выполнять любые целые операции. Обратите внимание, что при преобразовании из int в char компилятор не дает ошибки, а просто выполняет операцию по модулю 256, чтобы поместить значение в допустимый диапазон
Ответ 10
Вы можете просто использовать функцию atol()
:
#include <stdio.h>
#include <stdlib.h>
int main()
{
const char *c = "5";
int d = atol(c);
printf("%d\n", d);
}