Конвертировать char в int в C и C ++ - PullRequest
313 голосов
/ 17 февраля 2011

Как мне преобразовать char в int в C и C ++?

Ответы [ 11 ]

441 голосов
/ 17 февраля 2011

Зависит от того, что вы хотите сделать:

чтобы прочитать значение как код ascii, вы можете написать

char a = 'a';
int ia = (int)a; 
/* note that the int cast is not necessary -- int ia = a would suffice */

для преобразования символа '0' -> 0, '1' -> 1 и т. Д., Вы можете написать

char a = '4';
int ia = a - '0';
/* check here if ia is bounded by 0 and 9 */
74 голосов
/ 09 июня 2015

Ну, в коде ASCII числа (цифры) начинаются с 48 .Все, что вам нужно сделать, это:

int x = (int)character - 48;
58 голосов
/ 17 февраля 2011

C и C ++ всегда продвигают типы как минимум до int.Кроме того, символьные литералы имеют тип int в C и char в C ++.

Вы можете преобразовать тип char, просто присвоив int.

char c = 'a'; // narrowing on C
int a = c;
29 голосов
/ 17 февраля 2011

char - это всего лишь 1-байтовое целое число. В типе char нет ничего волшебного! Точно так же, как вы можете назначить short для int или int для long, вы можете назначить char для int.

Да, имя типа данных примитива бывает "char", что означает, что он должен содержать только символы. Но на самом деле «char» - это просто плохое имя, которое может сбить с толку всех, кто пытается выучить язык. Лучшее название для него - int8_t, и вы можете использовать его вместо этого, если ваш компилятор следует новейшему стандарту C.

Хотя, конечно, следует использовать тип char при обработке строки, поскольку индекс классической таблицы ASCII умещается в 1 байт. Вы могли бы , однако, также обрабатывать строки с обычными целочисленными значениями, хотя в реальном мире нет практической причины, по которой вы бы хотели это делать. Например, следующий код будет отлично работать:

  int str[] = {'h', 'e', 'l', 'l', 'o', '\0' };

  for(i=0; i<6; i++)
  {
    printf("%c", str[i]);
  }

Вы должны понимать, что символы и строки - это просто числа, как и все остальное в компьютере. Когда вы пишете «а» в исходном коде, он предварительно обрабатывается до числа 97, которое является целочисленной константой.

Так что, если вы напишите выражение типа

char ch = '5';
ch = ch - '0';

это на самом деле эквивалентно

char ch = (int)53;
ch = ch - (int)48;

, который проходит через целочисленные продвижения на языке C

ch = (int)ch - (int)48;

и затем усекается до символа для соответствия типу результата

ch = (char)( (int)ch - (int)48 );

Между строк происходит много тонких вещей, подобных этому, где char неявно рассматривается как int.

16 голосов
/ 17 февраля 2011

(Этот ответ касается стороны C ++, но проблема расширения знака существует и в C).

Обработка всех трех типов char (signed, unsigned и char) более сложна, чем кажется на первый взгляд. Значения в диапазоне от 0 до SCHAR_MAX (что 127 для 8-битного char) просты:

char c = somevalue;
signed char sc = c;
unsigned char uc = c;
int n = c;

Но когда somevalue находится за пределами этого диапазона, только пропуск unsigned char дает вам согласованные результаты для "одинаковых" значений char во всех трех типах:

char c = somevalue;
signed char sc = c;
unsigned char uc = c;
// Might not be true: int(c) == int(sc) and int(c) == int(uc).
int nc = (unsigned char)c;
int nsc = (unsigned char)sc;
int nuc = (unsigned char)uc;
// Always true: nc == nsc and nc == nuc.

Это важно при использовании функций из ctype.h , таких как isupper или toupper, из-за расширения знака:

char c = negative_char;  // Assuming CHAR_MIN < 0.
int n = c;
bool b = isupper(n);  // Undefined behavior.

Обратите внимание, что преобразование через int неявное; у этого же UB:

char c = negative_char;
bool b = isupper(c);

Чтобы исправить это, пройдите через unsigned char, что легко сделать, обернув ctype.h функциями через safe_ctype :

template<int (&F)(int)>
int safe_ctype(unsigned char c) { return F(c); }

//...
char c = CHAR_MIN;
bool b = safe_ctype<isupper>(c);  // No UB.

std::string s = "value that may contain negative chars; e.g. user input";
std::transform(s.begin(), s.end(), s.begin(), &safe_ctype<toupper>);
// Must wrap toupper to eliminate UB in this case, you can't cast
// to unsigned char because the function is called inside transform.

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

int ord(char c) { return (unsigned char)c; }
char chr(int n) {
  assert(0 <= n);  // Or other error-/sanity-checking.
  assert(n <= UCHAR_MAX);
  return (unsigned char)n;
}

// Ord and chr are named to match similar functions in other languages
// and libraries.

ord(c) всегда дает неотрицательное значение - даже если передано отрицательное char или отрицательное signed char - и chr принимает любое значение, которое производит ord и возвращает точно такое же char.

На практике я, вероятно, просто использовал бы unsigned char вместо того, чтобы использовать их, но они лаконично оборачивают приведение, предоставляют удобное место для добавления проверки ошибок для int -to- char, и были бы короче и понятнее, когда вам нужно использовать их несколько раз в непосредственной близости.

11 голосов
/ 22 января 2014

Использование static_cast<int>:

int num = static_cast<int>(letter); // if letter='a', num=97

Редактировать: Возможно, вам следует избегать использования (int)

int num = (int) letter;

check * Зачем использовать static_cast (x) вместо (int) x? для получения дополнительной информации.

6 голосов
/ 17 февраля 2011

Это отчасти зависит от того, что вы подразумеваете под "конвертированием".

Если у вас есть серия символов, представляющих целое число, например «123456», то есть два типичных способа сделать это в C: использовать специальное преобразование, например atoi () или strtol () или универсальное sscanf () . C ++ (на самом деле это другой язык, маскирующийся под обновление) добавляет третий, stringstreams.

Если вы хотите, чтобы точный битовый шаблон в одной из ваших int переменных рассматривался как char, это проще. В C разные целочисленные типы действительно больше относятся к состоянию ума, чем к отдельным отдельным «типам». Просто начните использовать его там, где запрашивают char s, и с вами все будет в порядке. Возможно, вам понадобится явное преобразование, чтобы компилятор прекратил ныть время от времени, но все, что нужно сделать, это отбросить лишние биты после 256.

5 голосов
/ 10 мая 2017

У меня есть абсолютно null навыки в Си, но для простого разбора:

char* something = "123456";

int number = parseInt(something);

... это сработало для меня:

int parseInt(char* chars)
{
    int sum = 0;
    int len = strlen(chars);
    for (int x = 0; x < len; x++)
    {
        int n = chars[len - (x + 1)] - '0';
        sum = sum + powInt(n, x);
    }
    return sum;
}

int powInt(int x, int y)
{
    for (int i = 0; i < y; i++)
    {
        x *= 10;
    }
    return x;
}
3 голосов
/ 17 февраля 2011

Предположительно, вам нужно это преобразование для использования функций из стандартной библиотеки C.

В этом случае do (синтаксис C ++)

typedef unsigned char UChar;

char myCppFunc( char c )
{
    return char( someCFunc( UChar( c ) ) );
}

Выражение UChar( c ) преобразуется в unsigned char чтобы избавиться от отрицательных значений, которые, кроме EOF, не поддерживаются функциями C.

Затем результат этого выражения используется в качестве фактического аргумента для формального аргумента int.Где вы получаете автоматическое повышение до int.В качестве альтернативы вы можете написать этот последний шаг явно, как int( UChar( c ) ), но лично я нахожу это слишком многословным.

Приветствия & hth.,

0 голосов
/ 26 октября 2012

Для char или short для int, вам просто нужно присвоить значение.

char ch = 16;
int in = ch;

То же самое для int64.

long long lo = ch;

Все значения будут 16.

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