@ Matt: seria uma boa idéia ser mais concreto. perguntar sobre uma generalização apenas convida respostas generalizadas que não são aplicáveis ou mesmo corretas para sua tarefa. tenha em mente que, quando precisar perguntar, provavelmente não sabe o suficiente para generalizar corretamente.
Saúde e hth. - Alf
@Alf P. Steinbach: A pergunta original era vaga em relação a qual idioma. Com palavras c- chave e c++, acho que as respostas que confrontam os dois idiomas são razoáveis.
Matt Joiner
8
Da minha vasta experiência em outros fóruns técnicos, minha intuição é que o OP realmente significa "como faço para pegar a representação textual de um número (na base 10) e convertê-la no número correspondente?" De um modo geral, os neófitos C e C ++ geralmente têm idéias incrivelmente nebulosas sobre como o texto funciona nessas linguagens e o que charrealmente significa.
Karl Knechtel
3
@KarlKnechtel: Se isso é verdade (eu dou cerca de 50/50, pois muitos tutoriais iniciais também incentivam a obtenção de valores ASCII de caracteres, mesmo que o ASCII não cubra toda a gama), o OP precisa ser esclarecido - mas isso é uma bobagem de stackoverflow.com/questions/439573/… .
Fred Nurk
3
O PO teve três horas para esclarecer esta questão e não conseguiu. Como é, não há como saber o que realmente é perguntado. Votou para fechar.
SBI
Respostas:
552
Depende do que você quer fazer:
para ler o valor como um código ascii, você pode escrever
char a ='a';int ia =(int)a;/* note that the int cast is not necessary -- int ia = a would suffice */
para converter o personagem '0' -> 0, '1' -> 1, etc, você pode escrever
char a ='4';int ia = a -'0';/* check here if ia is bounded by 0 and 9 */
Explicação : a - '0'é equivalente a ((int)a) - ((int)'0'), o que significa que os valores ascii dos caracteres são subtraídos um do outro. Como 0vem diretamente antes 1na tabela ascii (e assim por diante até 9), a diferença entre os dois fornece o número que o caractere arepresenta.
@KshitijBanerjee Essa não é uma boa ideia por dois motivos: fornece um número negativo para caracteres ascii antes de '0' (como &-> -10) e números maiores que 10 (como x-> 26)
SheetJS
2
int ia = a - '0' - que é o que você precisa
o funk
5
@ kevin001 Se você deseja converter o caractere para int e um caractere '1'fornece um número ASCII que não é 1, você precisa remover o deslocamento '0'para realinhar o número de 0 a 9. Os números consecutivos 1-9 são adjacentes no número inteiro ascii.
Krisdestruction
Nenhum elenco é obrigatório / desejado
Craig Estey
97
Bem, no código ASCII, os números (dígitos) começam em 48 . Tudo que você precisa fazer é:
@chad: Não apenas mais legível, como também mais portátil. C e C ++ não garantem uma representação ASCII, mas garantem que, independentemente da representação em uso, as representações dos 10 dígitos decimais sejam contíguas e em ordem numérica.
Ben Voigt
A única coisa que eu teria mudado seria fazer 48 anos, o que parece um pouco "mágico" para'0'
ArielGro
59
C e C ++ sempre promovem tipos para pelo menos int. Além disso, literais de caracteres são do tipo intem C e charem C ++.
Você pode converter um chartipo simplesmente atribuindo a um int.
Você também pode usar o unário extremamente subestimado operator+()para esse fim.
Cubbi
24
-1 A resposta está incorreta para a única interpretação significativa da pergunta. Este (código int a = c;) manterá quaisquer valores negativos, com os quais as funções da biblioteca padrão C não podem lidar. As funções da biblioteca padrão C definem o padrão para o que significa manipular charvalores como int.
Saúde e hth. - Alf
6
@ Matt: Eu estou mantendo o voto negativo. Eu o reforçaria se possível! A interpretação da pergunta que você e outras pessoas assumiram não é significativa, porque é totalmente trivial e, porque, para a combinação específica de tipos do OP, existe uma questão prática muito importante e não tão trivial. O conselho que você dá é diretamente perigoso para o novato. Provavelmente resultará em Comportamento indefinido para seus programas que usam funções de classificação de caracteres de biblioteca padrão C. Ref. para a resposta de @ Sayam, ele excluiu essa resposta.
Saúde e hth. - Alf
3
-1 por estar incorreto: isupper () terá resultados indefinidos se for passado um caractere de 1252 highbit.
precisa
11
O que você quer dizer com "sempre promover"? Os valores são promovidos durante conversões implícitas, certos tipos de parâmetros passando (por exemplo, para uma função varargs) e quando um operador deve tornar seus operandos tipos compatíveis. Mas certamente há momentos em que um valor não é promovido (como se eu passar um caractere para uma função que espera um caractere); caso contrário, não teríamos nenhum tipo menor que um int.
Adrian McCarthy
31
char é apenas um número inteiro de 1 byte. Não há nada mágico com o tipo de caractere! Assim como você pode atribuir um curto a um int, ou um int a um longo, também pode atribuir um char a um int.
Sim, o nome do tipo de dados primitivo passa a ser "char", o que insinua que ele deve conter apenas caracteres. Mas, na realidade, "char" é apenas uma má escolha para confundir todos que tentam aprender o idioma. Um nome melhor para ele é int8_t e você pode usá-lo, se o seu compilador seguir o padrão C mais recente.
Embora, é claro, você deva usar o tipo char ao manipular string, porque o índice da tabela ASCII clássica cabe em 1 byte. No entanto, você também pode manipular cordas com ints regulares, embora não exista uma razão prática no mundo real para fazer isso. Por exemplo, o código a seguir funcionará perfeitamente:
int str[]={'h','e','l','l','o','\0'};for(i=0; i<6; i++){
printf("%c", str[i]);}
Você precisa entender que caracteres e seqüências de caracteres são apenas números, como tudo o mais no computador. Quando você escreve 'a' no código-fonte, ele é pré-processado no número 97, que é uma constante inteira.
Então, se você escrever uma expressão como
char ch ='5';
ch = ch -'0';
isso é realmente equivalente a
char ch =(int)53;
ch = ch -(int)48;
que passa pelas promoções de números inteiros da linguagem C
ch =(int)ch -(int)48;
e, em seguida, truncado para um caractere para caber no tipo de resultado
ch =(char)((int)ch -(int)48);
Há muitas coisas sutis como essas acontecendo nas entrelinhas, onde char é implicitamente tratado como int.
Como a pergunta não está marcada ascii, você não deve assumir nenhuma codificação específica. Definir charigual a int8_testá errado porque poderia igualmente ser uint8_tou uint24_t.
Roland Illig 31/03
11
@RolandIllig Não, a charé sempre 1 byte e se os tipos int8_t/ uint8_texistirem no sistema fornecido (o que é muito provável), eles poderão ajustar o resultado de a char, porque serão 8 bits. Em sistemas altamente exóticos, como vários DSPs obsoletos, charhaverá 16 bits e uint8_teles não existirão. Escrever código para compatibilidade com DSPs obsoletos não faz sentido, assim como escrever para compatibilidade com os sistemas de complemento ou sinal e magnitude. Enorme perda de tempo, uma vez que tais sistemas mal existem no mundo real.
Lundin
18
(Esta resposta aborda o lado C ++, mas o problema de extensão de sinal também existe em C).
O manuseio dos três chartipos ( signed, unsignede char) é mais delicado do que parece à primeira vista. Os valores no intervalo de 0 a SCHAR_MAX(que é 127 para um de 8 bits char) são fáceis:
char c = somevalue;signedchar sc = c;unsignedchar uc = c;int n = c;
Mas, quando somevalueestá fora desse intervalo, apenas a unsigned charexecução fornece resultados consistentes para os "mesmos" charvalores nos três tipos:
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.
Isso é importante ao usar funções de ctype.h , como isupperou toupper, devido à extensão de sinal:
char c = negative_char;// Assuming CHAR_MIN < 0.int n = c;bool b = isupper(n);// Undefined behavior.
Observe que a conversão através de int está implícita; isso tem o mesmo UB:
char c = negative_char;bool b = isupper(c);
Para corrigir isso, prossiga unsigned char, o que é feito facilmente, envolvendo as funções ctype.h por 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.
Isso funciona porque qualquer função que aceite um dos três tipos de caracteres também pode aceitar os outros dois tipos de caracteres. Isso leva a duas funções que podem lidar com qualquer um dos tipos:
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)sempre fornece um valor não negativo - mesmo quando passado como negativo charou negativo signed char- e chraceita qualquer valor que ordproduz e devolve exatamente o mesmo char.
Na prática, eu provavelmente apenas transmiti-lo em unsigned charvez de usá-los, mas eles encapsulam sucintamente o elenco, fornecem um local conveniente para adicionar verificação de erros para - e - e intfica charmais curto e mais claro quando você precisa usá-los várias vezes nas proximidades.
Se você possui uma série de caracteres que representam um número inteiro, como "123456", existem duas maneiras comuns de fazer isso em C: Use uma conversão de finalidade especial como atoi () ou strtol () ou sscanf de uso geral () . O C ++ (que é realmente uma linguagem diferente que se disfarça de atualização) adiciona uma terceira sequência de strings.
Se você quer que o padrão de bits exato em uma de suas intvariáveis seja tratado como um char, é mais fácil. Em C, os diferentes tipos de números inteiros são realmente mais um estado de espírito do que os "tipos" reais separados. Basta começar a usá-lo onde charfor solicitado e você deve estar bem. Você pode precisar de uma conversão explícita para fazer com que o compilador pare de choramingar de vez em quando, mas tudo o que você deve fazer é eliminar quaisquer bits extras além de 256.
Eu tenho absolutamente nullhabilidades em C, mas para uma análise simples:
char* something ="123456";int number = parseInt(something);
... isso funcionou para mim:
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;}
Esse código chama rapidamente um comportamento indefinido e, portanto, não é adequado para copiar e colar. (int overflow)
Roland Illig 31/03
4
Presumivelmente, você deseja essa conversão para usar funções da biblioteca padrão C.
Nesse caso, faça (sintaxe C ++)
typedefunsignedcharUChar;char myCppFunc(char c ){returnchar( someCFunc(UChar( c )));}
A expressão é UChar( c )convertida unsigned charem para se livrar de valores negativos, que, exceto o EOF, não são suportados pelas funções C.
Em seguida, o resultado dessa expressão é usado como argumento real para um intargumento formal. Para onde você recebe a promoção automática int. Como alternativa, você pode escrever explicitamente esse último passo int( UChar( c ) ), mas pessoalmente acho isso muito detalhado.
Eu estava tendo problemas para converter uma matriz de caracteres "7c7c7d7d7d7d7c7c7c7d7d7d7d7c7c7c7c7c7c7d7d7c7c7c7c7d7c7d7d7d7c7c2e2e2e"em seu valor inteiro real que poderia ser representado por `7C 'como um valor hexadecimal. Então, depois de procurar ajuda, criei isso e achei que seria legal compartilhar.
Isso separa a sequência de caracteres char em seus números inteiros certos e pode ser útil para mais pessoas do que apenas para mim;)
c
- chave ec++
, acho que as respostas que confrontam os dois idiomas são razoáveis.char
realmente significa.Respostas:
Depende do que você quer fazer:
para ler o valor como um código ascii, você pode escrever
para converter o personagem
'0' -> 0
,'1' -> 1
, etc, você pode escreverExplicação :
a - '0'
é equivalente a((int)a) - ((int)'0')
, o que significa que os valores ascii dos caracteres são subtraídos um do outro. Como0
vem diretamente antes1
na tabela ascii (e assim por diante até9
), a diferença entre os dois fornece o número que o caracterea
representa.fonte
&
-> -10) e números maiores que 10 (comox
-> 26)'1'
fornece um número ASCII que não é1
, você precisa remover o deslocamento'0'
para realinhar o número de 0 a 9. Os números consecutivos 1-9 são adjacentes no número inteiro ascii.Bem, no código ASCII, os números (dígitos) começam em 48 . Tudo que você precisa fazer é:
fonte
'0'
C e C ++ sempre promovem tipos para pelo menos
int
. Além disso, literais de caracteres são do tipoint
em C echar
em C ++.Você pode converter um
char
tipo simplesmente atribuindo a umint
.fonte
operator+()
para esse fim.int a = c;
) manterá quaisquer valores negativos, com os quais as funções da biblioteca padrão C não podem lidar. As funções da biblioteca padrão C definem o padrão para o que significa manipularchar
valores comoint
.char é apenas um número inteiro de 1 byte. Não há nada mágico com o tipo de caractere! Assim como você pode atribuir um curto a um int, ou um int a um longo, também pode atribuir um char a um int.
Sim, o nome do tipo de dados primitivo passa a ser "char", o que insinua que ele deve conter apenas caracteres. Mas, na realidade, "char" é apenas uma má escolha para confundir todos que tentam aprender o idioma. Um nome melhor para ele é int8_t e você pode usá-lo, se o seu compilador seguir o padrão C mais recente.
Embora, é claro, você deva usar o tipo char ao manipular string, porque o índice da tabela ASCII clássica cabe em 1 byte. No entanto, você também pode manipular cordas com ints regulares, embora não exista uma razão prática no mundo real para fazer isso. Por exemplo, o código a seguir funcionará perfeitamente:
Você precisa entender que caracteres e seqüências de caracteres são apenas números, como tudo o mais no computador. Quando você escreve 'a' no código-fonte, ele é pré-processado no número 97, que é uma constante inteira.
Então, se você escrever uma expressão como
isso é realmente equivalente a
que passa pelas promoções de números inteiros da linguagem C
e, em seguida, truncado para um caractere para caber no tipo de resultado
Há muitas coisas sutis como essas acontecendo nas entrelinhas, onde char é implicitamente tratado como int.
fonte
ascii
, você não deve assumir nenhuma codificação específica. Definirchar
igual aint8_t
está errado porque poderia igualmente seruint8_t
ouuint24_t
.char
é sempre 1 byte e se os tiposint8_t
/uint8_t
existirem no sistema fornecido (o que é muito provável), eles poderão ajustar o resultado de achar
, porque serão 8 bits. Em sistemas altamente exóticos, como vários DSPs obsoletos,char
haverá 16 bits euint8_t
eles não existirão. Escrever código para compatibilidade com DSPs obsoletos não faz sentido, assim como escrever para compatibilidade com os sistemas de complemento ou sinal e magnitude. Enorme perda de tempo, uma vez que tais sistemas mal existem no mundo real.(Esta resposta aborda o lado C ++, mas o problema de extensão de sinal também existe em C).
O manuseio dos três
char
tipos (signed
,unsigned
echar
) é mais delicado do que parece à primeira vista. Os valores no intervalo de 0 aSCHAR_MAX
(que é 127 para um de 8 bitschar
) são fáceis:Mas, quando
somevalue
está fora desse intervalo, apenas aunsigned char
execução fornece resultados consistentes para os "mesmos"char
valores nos três tipos:Isso é importante ao usar funções de ctype.h , como
isupper
outoupper
, devido à extensão de sinal:Observe que a conversão através de int está implícita; isso tem o mesmo UB:
Para corrigir isso, prossiga
unsigned char
, o que é feito facilmente, envolvendo as funções ctype.h por safe_ctype :Isso funciona porque qualquer função que aceite um dos três tipos de caracteres também pode aceitar os outros dois tipos de caracteres. Isso leva a duas funções que podem lidar com qualquer um dos tipos:
ord(c)
sempre fornece um valor não negativo - mesmo quando passado como negativochar
ou negativosigned char
- echr
aceita qualquer valor queord
produz e devolve exatamente o mesmochar
.Na prática, eu provavelmente apenas transmiti-lo em
unsigned char
vez de usá-los, mas eles encapsulam sucintamente o elenco, fornecem um local conveniente para adicionar verificação de erros para - e - eint
ficachar
mais curto e mais claro quando você precisa usá-los várias vezes nas proximidades.fonte
Use
static_cast<int>
:Edit: Você provavelmente deve tentar evitar o uso
(int)
confira Por que usar static_cast <int> (x) em vez de (int) x? para mais informações.
fonte
Depende do que você quer dizer com "converter".
Se você possui uma série de caracteres que representam um número inteiro, como "123456", existem duas maneiras comuns de fazer isso em C: Use uma conversão de finalidade especial como atoi () ou strtol () ou sscanf de uso geral () . O C ++ (que é realmente uma linguagem diferente que se disfarça de atualização) adiciona uma terceira sequência de strings.
Se você quer que o padrão de bits exato em uma de suas
int
variáveis seja tratado como umchar
, é mais fácil. Em C, os diferentes tipos de números inteiros são realmente mais um estado de espírito do que os "tipos" reais separados. Basta começar a usá-lo ondechar
for solicitado e você deve estar bem. Você pode precisar de uma conversão explícita para fazer com que o compilador pare de choramingar de vez em quando, mas tudo o que você deve fazer é eliminar quaisquer bits extras além de 256.fonte
Eu tenho absolutamente
null
habilidades em C, mas para uma análise simples:... isso funcionou para mim:
fonte
Presumivelmente, você deseja essa conversão para usar funções da biblioteca padrão C.
Nesse caso, faça (sintaxe C ++)
A expressão é
UChar( c )
convertidaunsigned char
em para se livrar de valores negativos, que, exceto o EOF, não são suportados pelas funções C.Em seguida, o resultado dessa expressão é usado como argumento real para um
int
argumento formal. Para onde você recebe a promoção automáticaint
. Como alternativa, você pode escrever explicitamente esse último passoint( UChar( c ) )
, mas pessoalmente acho isso muito detalhado.Cheers & hth.,
fonte
Eu estava tendo problemas para converter uma matriz de caracteres
"7c7c7d7d7d7d7c7c7c7d7d7d7d7c7c7c7c7c7c7d7d7c7c7c7c7d7c7d7d7d7c7c2e2e2e"
em seu valor inteiro real que poderia ser representado por `7C 'como um valor hexadecimal. Então, depois de procurar ajuda, criei isso e achei que seria legal compartilhar.Isso separa a sequência de caracteres char em seus números inteiros certos e pode ser útil para mais pessoas do que apenas para mim;)
Espero que ajude!
fonte
Para char ou short para int, você só precisa atribuir o valor.
O mesmo que o int64.
Todos os valores serão 16.
fonte
Você pode usar esse método atoi para converter char para int. Para obter mais informações, você pode consultar este http://www.cplusplus.com/reference/cstdlib/atoi/ , http://www.cplusplus.com/reference/string/stoi/ .
fonte