@Matt: было бы неплохо быть более конкретным. вопрос об обобщении просто предлагает обобщенные ответы, которые не применимы или даже не подходят для вашей задачи. имейте в виду, что когда вам приходится спрашивать, вы, вероятно, не знаете достаточно, чтобы правильно обобщать.
ура и hth. - Альф
@Alf P. Steinbach: первоначальный вопрос был неопределенным в отношении того, на каком языке. С ключевыми словами cи c++, я думаю, ответы на оба языка являются разумными.
Мэтт Джоунер
8
Исходя из моего большого опыта работы на других технических форумах, моя интуиция заключается в том, что ОП на самом деле означает «как взять текстовое представление числа (в базе 10) и преобразовать его в соответствующее число?» Вообще говоря, неофиты C и C ++ обычно имеют невероятно смутные представления о том, как работает текст на этих языках и что на charсамом деле означает.
Карл Кнехтель
3
@KarlKnechtel: Если это правда (я даю около 50/50, так как многие ранние учебники также поощряют получение значений ASCII из символов, даже если ASCII не охватывает весь диапазон), ОП требует ясности - но это обман of stackoverflow.com/questions/439573/… .
Фред Нурк
3
У ОП было три часа, чтобы уточнить этот вопрос, и он не смог этого сделать. Как это, нет никакого способа узнать, что на самом деле спрашивают. Проголосовал за закрытие.
sbi
Ответы:
552
Зависит от того, что вы хотите сделать:
чтобы прочитать значение в виде кода 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 */
Пояснение : a - '0'эквивалентно ((int)a) - ((int)'0'), что означает, что значения ascii символов вычитаются друг из друга. Поскольку 0непосредственно 1в таблице ascii (и так далее, до тех пор 9, пока не будет ), различие между ними дает число, которое aпредставляет символ .
@KshitijBanerjee Это не очень хорошая идея по двум причинам: он дает вам отрицательное число для символов ascii перед '0' (например, &-> -10), и это дает вам числа больше 10 (как x-> 26)
SheetJS
2
int ia = a - '0' - это то, что вам нужно
фанк
5
@ kevin001 Если вы хотите преобразовать char в int, а символ '1'предоставляет число ascii, которого нет 1, вам нужно удалить смещение, '0'чтобы выровнять его, чтобы считать от 0 до 9. Последовательные числа 1-9 соседствуют в целом числе ascii.
krisdestruction
В ролях не требуется / не желательно
Крейг Эстей,
97
Ну, в коде ASCII числа (цифры) начинаются с 48 . Все, что вам нужно сделать, это:
@chad: не только более читабельный, но и более портативный. C и C ++ не гарантируют представление ASCII, но они гарантируют, что независимо от того, какое представление используется, представления 10 десятичных цифр являются смежными и в числовом порядке.
Бен Фойгт
Единственное, что я бы изменил, - это повернул 48, что кажется немного «волшебным» для'0'
ArielGro
59
C и C ++ всегда продвигают типы по крайней мере int. Кроме того, символьные литералы имеют тип intв C и charв C ++.
Вы можете преобразовать charтип, просто присвоив int.
Вы также можете использовать очень недооцененный унарныйoperator+() для этой цели.
Cubbi
24
-1 Ответ неверен только для осмысленного толкования вопроса. Это (код int a = c;) будет хранить любые отрицательные значения, с которыми стандартные функции библиотеки C не могут иметь дело. Стандартные библиотечные функции C устанавливают стандарт того, что значит обрабатывать charзначения как int.
ура и hth. - Альф
6
@Matt: я держу вниз голосов. Я бы усилил это, если это возможно! Интерпретация вопроса, которую вы и другие предположили, не имеет смысла, потому что она слишком тривиальна, и потому что для конкретной комбинации типов OP существует не так уж и тривиальная очень важная практическая проблема. Совет, который вы даете, напрямую опасен для новичка. Скорее всего, это приведет к неопределенному поведению для их программ, которые используют функции классификации символов стандартной библиотеки C. Реф. на ответ @ Sayam он удалил этот ответ.
ура и hth. - Альф
3
-1 за неправильность: isupper () будет иметь неопределенные результаты, если передан 1252 старшего символа.
Крис Бекке
1
Что вы подразумеваете под «всегда продвигать»? Значения продвигаются во время неявных преобразований, передачи определенных типов параметров (например, в функцию varargs) и когда оператор должен сделать свои операнды совместимыми типами. Но, безусловно, бывают случаи, когда значение не продвигается (например, если я передаю символ функции, ожидающей символ), иначе у нас не было бы типов, меньших, чем int.
Адриан Маккарти
31
char - это всего лишь 1-байтовое целое число. В типе char нет ничего волшебного! Точно так же, как вы можете назначить short для int или int для long, вы можете назначить char для int.
Да, имя типа данных примитива бывает «char», что означает, что он должен содержать только символы. Но на самом деле «char» - это просто плохое имя, которое может сбить с толку всех, кто пытается выучить язык. Лучшее имя для него - int8_t, и вы можете использовать это имя, если ваш компилятор следует последнему стандарту Си.
Хотя, конечно, вы должны использовать тип 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.
Поскольку вопрос не помечен ascii, вы не должны предполагать какую-либо конкретную кодировку. Установка charравным int8_tявляется неправильным, потому что это может быть равно uint8_tили uint24_t.
Роланд Иллиг
1
@RolandIllig Нет, a charвсегда равен 1 байту, и если типы int8_t/ uint8_tсуществуют в данной системе (что весьма вероятно), они смогут соответствовать результату a char, поскольку тогда он будет равен 8 битам. В очень экзотических системах, таких как различные устаревшие DSP, charбудет 16 бит, и их uint8_tне будет. Написание кода для совместимости с устаревшими DSP не имеет смысла, так же как написание для совместимости с системами дополнения или знака и величины. Огромная трата времени, поскольку такие системы практически не существуют в реальном мире.
Лундин
18
(Этот ответ касается стороны C ++, но проблема расширения знака существует и в C).
Обработка всех трех charтипов ( signed,, unsignedи char) более сложна, чем кажется на первый взгляд. Значения в диапазоне от 0 до SCHAR_MAX(что составляет 127 для 8-разрядного char) просты:
char c = somevalue;signedchar sc = c;unsignedchar uc = c;int n = c;
Но когда somevalueвыход за пределы этого диапазона, только прохождение unsigned charдает вам согласованные результаты для «одинаковых» charзначений во всех трех типах:
char c = somevalue;signedchar sc = c;unsignedchar uc = c;// Might not be true: int(c) == int(sc) and int(c) == int(uc).int nc =(unsignedchar)c;int nsc =(unsignedchar)sc;int nuc =(unsignedchar)uc;// Always true: nc == nsc and nc == nuc.
Это важно при использовании функций из ctype.h , таких как isupperor 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(unsignedchar 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(unsignedchar)c;}char chr(int n){assert(0<= n);// Or other error-/sanity-checking.assert(n <= UCHAR_MAX);return(unsignedchar)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, и были бы короче и понятнее, когда вам нужно использовать их несколько раз. в непосредственной близости.
Это зависит от того, что вы подразумеваете под «конвертировать».
Если у вас есть серия символов, представляющих целое число, например «123456», то в C есть два типичных способа сделать это: использовать специальное преобразование, такое как atoi () или strtol () , или универсальный sscanf. () . C ++ (который на самом деле является другим языком, маскирующимся под обновление) добавляет третий, stringstream.
Если вы имеете в виду, что хотите, чтобы точный битовый шаблон в одной из ваших intпеременных рассматривался как a char, это проще. В C разные целочисленные типы действительно больше относятся к состоянию ума, чем к отдельным отдельным «типам». Просто начните использовать его там, где вас charпросят, и вы должны быть в порядке. Возможно, вам понадобится явное преобразование, чтобы компилятор прекратил ныть, но все, что нужно сделать, это отбросить все лишние биты после 256.
У меня есть абсолютно nullнавыки в C, но для простого разбора:
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;}
Этот код быстро вызывает неопределенное поведение и поэтому не подходит для копирования и вставки. (переполнение)
Роланд Иллиг,
4
Предположительно, вы хотите это преобразование для использования функций из стандартной библиотеки C.
В этом случае do (синтаксис C ++)
typedefunsignedcharUChar;char myCppFunc(char c ){returnchar( someCFunc(UChar( c )));}
Выражение UChar( c )конвертируется unsigned charв, чтобы избавиться от отрицательных значений, которые, кроме EOF, не поддерживаются функциями C.
Затем результат этого выражения используется в качестве фактического аргумента для intформального аргумента. Где вы получаете автоматическое продвижение в int. В качестве альтернативы вы можете написать этот последний шаг явно, например int( UChar( c ) ), но лично я нахожу это слишком многословным.
У меня были проблемы с преобразованием массива типа char "7c7c7d7d7d7d7c7c7c7d7d7d7d7c7c7c7c7c7c7d7d7c7c7c7c7d7c7d7d7d7c7c2e2e2e"в его действительное целочисленное значение, которое могло бы быть представлено 7C как одно шестнадцатеричное значение. Итак, после поиска помощи я создал это и подумал, что было бы здорово поделиться.
Это разделяет строку char на правильные целые числа и может быть полезна большему количеству людей, чем только я;)
Вы когда-нибудь тестировали этот код? 50 должно быть 48, 55 работает только для прописных букв ASCII, в то время как ваш пример содержит строчные буквы.
Роланд Иллиг
0
Для char или short для int вам просто нужно присвоить значение.
c
иc++
, я думаю, ответы на оба языка являются разумными.char
самом деле означает.Ответы:
Зависит от того, что вы хотите сделать:
чтобы прочитать значение в виде кода ASCII, вы можете написать
для преобразования символов
'0' -> 0
,'1' -> 1
и т.д., вы можете написатьПояснение :
a - '0'
эквивалентно((int)a) - ((int)'0')
, что означает, что значения ascii символов вычитаются друг из друга. Поскольку0
непосредственно1
в таблице ascii (и так далее, до тех пор9
, пока не будет ), различие между ними дает число, котороеa
представляет символ .источник
&
-> -10), и это дает вам числа больше 10 (какx
-> 26)'1'
предоставляет число ascii, которого нет1
, вам нужно удалить смещение,'0'
чтобы выровнять его, чтобы считать от 0 до 9. Последовательные числа 1-9 соседствуют в целом числе ascii.Ну, в коде ASCII числа (цифры) начинаются с 48 . Все, что вам нужно сделать, это:
источник
'0'
C и C ++ всегда продвигают типы по крайней мере
int
. Кроме того, символьные литералы имеют типint
в C иchar
в C ++.Вы можете преобразовать
char
тип, просто присвоивint
.источник
operator+()
для этой цели.int a = c;
) будет хранить любые отрицательные значения, с которыми стандартные функции библиотеки C не могут иметь дело. Стандартные библиотечные функции C устанавливают стандарт того, что значит обрабатыватьchar
значения какint
.char - это всего лишь 1-байтовое целое число. В типе char нет ничего волшебного! Точно так же, как вы можете назначить short для int или int для long, вы можете назначить char для int.
Да, имя типа данных примитива бывает «char», что означает, что он должен содержать только символы. Но на самом деле «char» - это просто плохое имя, которое может сбить с толку всех, кто пытается выучить язык. Лучшее имя для него - int8_t, и вы можете использовать это имя, если ваш компилятор следует последнему стандарту Си.
Хотя, конечно, вы должны использовать тип char при обработке строк, потому что индекс классической таблицы ASCII умещается в 1 байт. Тем не менее, вы могли бы также выполнять обработку строк с помощью обычных целочисленных значений, хотя в реальном мире нет практической причины, по которой вы захотите это сделать. Например, следующий код будет отлично работать:
Вы должны понимать, что символы и строки - это просто числа, как и все остальное в компьютере. Когда вы пишете «а» в исходном коде, он предварительно обрабатывается до числа 97, которое является целочисленной константой.
Так что если вы напишите выражение, как
это на самом деле эквивалентно
который затем проходит через целочисленные продвижения языка C
а затем обрезается до символа, чтобы соответствовать типу результата
Между строк происходит много таких тонких вещей, когда char неявно рассматривается как int.
источник
ascii
, вы не должны предполагать какую-либо конкретную кодировку. Установкаchar
равнымint8_t
является неправильным, потому что это может быть равноuint8_t
илиuint24_t
.char
всегда равен 1 байту, и если типыint8_t
/uint8_t
существуют в данной системе (что весьма вероятно), они смогут соответствовать результату achar
, поскольку тогда он будет равен 8 битам. В очень экзотических системах, таких как различные устаревшие DSP,char
будет 16 бит, и ихuint8_t
не будет. Написание кода для совместимости с устаревшими DSP не имеет смысла, так же как написание для совместимости с системами дополнения или знака и величины. Огромная трата времени, поскольку такие системы практически не существуют в реальном мире.(Этот ответ касается стороны C ++, но проблема расширения знака существует и в C).
Обработка всех трех
char
типов (signed
,,unsigned
иchar
) более сложна, чем кажется на первый взгляд. Значения в диапазоне от 0 доSCHAR_MAX
(что составляет 127 для 8-разрядногоchar
) просты:Но когда
somevalue
выход за пределы этого диапазона, только прохождениеunsigned char
дает вам согласованные результаты для «одинаковых»char
значений во всех трех типах:Это важно при использовании функций из ctype.h , таких как
isupper
ortoupper
, из-за расширения знака:Обратите внимание, что преобразование через int неявное; это тот же UB:
Чтобы исправить это, пройти через
unsigned char
, который легко сделать обертывание ctype.h функций через safe_ctype :Это работает, потому что любая функция, принимающая любой из трех типов символов, может также принимать другие два типа символов. Это приводит к двум функциям, которые могут обрабатывать любые типы:
ord(c)
всегда дает вам неотрицательное значение - даже если передано отрицательноеchar
или отрицательноеsigned char
- иchr
принимает любое значение,ord
производит и возвращает точно то же самоеchar
.На практике я, вероятно, просто использовал бы приведение
unsigned char
вместо того, чтобы использовать их, но они кратко оборачивают приведение, предоставляют удобное место для добавления проверки ошибок дляint
-to-char
, и были бы короче и понятнее, когда вам нужно использовать их несколько раз. в непосредственной близости.источник
Используйте
static_cast<int>
:Редактировать: вы, вероятно, должны стараться избегать использования
(int)
проверить почему использовать static_cast <int> (x) вместо (int) x? для получения дополнительной информации.
источник
Это зависит от того, что вы подразумеваете под «конвертировать».
Если у вас есть серия символов, представляющих целое число, например «123456», то в C есть два типичных способа сделать это: использовать специальное преобразование, такое как atoi () или strtol () , или универсальный sscanf. () . C ++ (который на самом деле является другим языком, маскирующимся под обновление) добавляет третий, stringstream.
Если вы имеете в виду, что хотите, чтобы точный битовый шаблон в одной из ваших
int
переменных рассматривался как achar
, это проще. В C разные целочисленные типы действительно больше относятся к состоянию ума, чем к отдельным отдельным «типам». Просто начните использовать его там, где васchar
просят, и вы должны быть в порядке. Возможно, вам понадобится явное преобразование, чтобы компилятор прекратил ныть, но все, что нужно сделать, это отбросить все лишние биты после 256.источник
У меня есть абсолютно
null
навыки в C, но для простого разбора:... это сработало для меня:
источник
Предположительно, вы хотите это преобразование для использования функций из стандартной библиотеки C.
В этом случае do (синтаксис C ++)
Выражение
UChar( c )
конвертируетсяunsigned char
в, чтобы избавиться от отрицательных значений, которые, кроме EOF, не поддерживаются функциями C.Затем результат этого выражения используется в качестве фактического аргумента для
int
формального аргумента. Где вы получаете автоматическое продвижение вint
. В качестве альтернативы вы можете написать этот последний шаг явно, напримерint( UChar( c ) )
, но лично я нахожу это слишком многословным.Ура & hth.,
источник
У меня были проблемы с преобразованием массива типа char
"7c7c7d7d7d7d7c7c7c7d7d7d7d7c7c7c7c7c7c7d7d7c7c7c7c7d7c7d7d7d7c7c2e2e2e"
в его действительное целочисленное значение, которое могло бы быть представлено 7C как одно шестнадцатеричное значение. Итак, после поиска помощи я создал это и подумал, что было бы здорово поделиться.Это разделяет строку char на правильные целые числа и может быть полезна большему количеству людей, чем только я;)
Надеюсь, поможет!
источник
Для char или short для int вам просто нужно присвоить значение.
То же самое для int64.
Все значения будут 16.
источник
Вы можете использовать этот метод atoi для преобразования char в int. Для получения дополнительной информации вы можете обратиться к этому http://www.cplusplus.com/reference/cstdlib/atoi/ , http://www.cplusplus.com/reference/string/stoi/ .
источник