@ Matt: sería una buena idea ser más concreto. preguntar sobre una generalización solo invita a respuestas generalizadas que no son aplicables o incluso correctas para su tarea. tenga en cuenta que, cuando tenga que preguntar, probablemente no sepa lo suficiente para generalizar correctamente.
Saludos y hth. - Alf
@Alf P. Steinbach: La pregunta original era vaga sobre qué idioma. Con palabras clave cy c++, creo que las respuestas que enfrentan ambos idiomas son razonables.
Matt Joiner
8
Desde mi amplia experiencia en otros foros técnicos, mi intuición es que el OP realmente significa "¿cómo tomo la representación textual de un número (en la base 10) y la convierto en el número correspondiente?" En términos generales, los neófitos C y C ++ generalmente tienen ideas increíblemente confusas sobre cómo funciona el texto en esos lenguajes y lo que charrealmente significa.
Karl Knechtel
3
@KarlKnechtel: Si eso es cierto (le doy alrededor de 50/50, ya que muchos de los primeros tutoriales también alientan a sacar los valores ASCII de los caracteres, a pesar de que ASCII no cubre el rango completo), el OP necesita claridad, pero eso es un engaño de stackoverflow.com/questions/439573/… .
Fred Nurk
3
El OP tuvo tres horas para aclarar esta pregunta y no lo hizo. Tal como están las cosas, no hay forma de saber qué se pregunta realmente. Votado para cerrar.
sbi
Respuestas:
552
Depende de lo que quieras hacer:
Para leer el valor como un código ASCII, puede escribir
char a ='a';int ia =(int)a;/* note that the int cast is not necessary -- int ia = a would suffice */
para convertir el carácter '0' -> 0, '1' -> 1etc, se puede escribir
char a ='4';int ia = a -'0';/* check here if ia is bounded by 0 and 9 */
Explicación : a - '0'es equivalente a ((int)a) - ((int)'0'), lo que significa que los valores ascii de los caracteres se restan entre sí. Como 0viene directamente antes 1en la tabla ascii (y así sucesivamente hasta 9), la diferencia entre los dos da el número que arepresenta el personaje .
@KshitijBanerjee Esa no es una buena idea por dos razones: le da un número negativo para caracteres ascii antes de '0' (como &-> -10), y le da números mayores que 10 (como x-> 26)
SheetJS
2
int ia = a - '0' - eso es lo que necesitas
funk
55
@ kevin001 Si desea convertir el carácter a int y un carácter '1'proporciona un número ASCII que no lo es 1, debe eliminar el desplazamiento '0'para realinearlo y contar de 0 a 9. Los números consecutivos 1-9 son adyacentes en el número entero ascii.
krisdestruction
No se requiere / desea el reparto
Craig Estey
97
Bueno, en el código ASCII, los números (dígitos) comienzan desde 48 . Todo lo que necesitas hacer es:
@chad: no solo es más legible, también es más portátil. C y C ++ no garantizan una representación ASCII, pero sí garantizan que cualquier representación que esté en uso, las representaciones de los 10 dígitos decimales son contiguas y en orden numérico.
Ben Voigt
Lo único que habría cambiado es cumplir 48 años, lo que parece un poco "mágico"'0'
ArielGro
59
C y C ++ siempre promueven tipos al menos int. Además, los literales de caracteres son de tipo intC ychar en C ++.
Puede convertir un chartipo simplemente asignándolo a un int.
También podría utilizar el unario muy poco apreciado operator+()para este propósito.
Cubbi
24
-1 La respuesta es incorrecta para la única interpretación significativa de la pregunta. Este (código int a = c;) mantendrá cualquier valor negativo, que las funciones de biblioteca estándar de C no pueden manejar. Las funciones de la biblioteca estándar de C establecen el estándar de lo que significa manejar charvalores como int.
Saludos y hth. - Alf
66
@ Matt: Me quedo con el voto negativo. ¡Lo fortalecería si fuera posible! La interpretación de la pregunta que usted y otros han asumido no es significativa, porque es demasiado trivial, y porque para la combinación particular de tipos del OP hay un problema práctico no muy trivial muy importante. El consejo que da es directamente peligroso para el novato. Lo más probable es que resulte en Comportamiento indefinido para sus programas que usan funciones de clasificación de caracteres de biblioteca estándar de C. Re ref. a la respuesta de @ Sayam, ha eliminado esa respuesta.
Saludos y hth. - Alf
3
-1 por ser incorrecto: isupper () tendrá resultados indefinidos si pasa un carácter de 1252 bits altos.
Chris Becke
1
¿Qué quieres decir con "siempre promocionar"? Los valores se promueven durante las conversiones implícitas, ciertos tipos de parámetros que pasan (por ejemplo, a una función varargs) y cuando un operador debe hacer que sus operandos sean compatibles. Pero ciertamente hay momentos en que no se promueve un valor (como si le paso un carácter a una función que espera un carácter), de lo contrario no tendríamos ningún tipo más pequeño que un int.
Adrian McCarthy
31
char es solo un entero de 1 byte. ¡No hay nada mágico con el tipo char! Así como puedes asignar un short a un int, o un int a un long, puedes asignar un char a un int.
Sí, el nombre del tipo de datos primitivo es "char", lo que insinúa que solo debe contener caracteres. Pero en realidad, "char" es solo una mala elección de nombre para confundir a todos los que intentan aprender el idioma. Un mejor nombre para él es int8_t, y puede usar ese nombre en su lugar, si su compilador sigue el último estándar de C.
Aunque, por supuesto, debe usar el tipo char al hacer el manejo de cadenas, porque el índice de la tabla ASCII clásica cabe en 1 byte. Usted podría sin embargo hacer manejo de cadenas de enteros normales, así, aunque no hay ninguna razón práctica en el mundo real por la que va a querer hacer eso. Por ejemplo, el siguiente código funcionará perfectamente:
int str[]={'h','e','l','l','o','\0'};for(i=0; i<6; i++){
printf("%c", str[i]);}
Debes darte cuenta de que los caracteres y las cadenas son solo números, como todo lo demás en la computadora. Cuando escribe 'a' en el código fuente, se procesa previamente en el número 97, que es una constante entera.
Entonces, si escribes una expresión como
char ch ='5';
ch = ch -'0';
esto es realmente equivalente a
char ch =(int)53;
ch = ch -(int)48;
que luego pasa por las promociones de enteros en lenguaje C
ch =(int)ch -(int)48;
y luego truncado a un carácter para ajustarse al tipo de resultado
ch =(char)((int)ch -(int)48);
Hay muchas cosas sutiles como esta sucediendo entre líneas, donde char se trata implícitamente como un int.
Como la pregunta no está etiquetada ascii, no debe asumir ninguna codificación específica. Establecer charigual a int8_testá mal porque igualmente podría ser uint8_to uint24_t.
Roland Illig
1
@RolandIllig No, a charsiempre es 1 byte y si los tipos int8_t/ uint8_texisten en el sistema dado (lo cual es muy probable), podrán ajustar el resultado de a char, porque entonces serán 8 bits. En sistemas altamente exóticos como varios DSP obsoletos, chartendrá 16 bits y uint8_tno existirá. Escribir código para la compatibilidad con DSP obsoletos no tiene sentido, al igual que escribir para la compatibilidad con los sistemas de complemento o signo y magnitud. Gran pérdida de tiempo, ya que tales sistemas apenas existen en el mundo real.
Lundin
18
(Esta respuesta aborda el lado C ++ de las cosas, pero el problema de la extensión del signo también existe en C).
El manejo de los tres chartipos ( signed, unsignedy char) es más delicado de lo que parece. Los valores en el rango de 0 a SCHAR_MAX(que es 127 para un 8 bits char) son fáciles:
char c = somevalue;signedchar sc = c;unsignedchar uc = c;int n = c;
Pero, cuando somevalueestá fuera de ese rango, solo pasar unsigned charle da resultados consistentes para los "mismos" charvalores en los tres 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.
Esto es importante cuando se utilizan funciones de ctype.h , como isuppero toupper, debido a la extensión del signo:
char c = negative_char;// Assuming CHAR_MIN < 0.int n = c;bool b = isupper(n);// Undefined behavior.
Tenga en cuenta que la conversión a través de int es implícita; esto tiene el mismo UB:
char c = negative_char;bool b = isupper(c);
Para solucionar esto, vaya unsigned char, lo que se hace fácilmente envolviendo las funciones ctype.h a través de 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.
Esto funciona porque cualquier función que tome cualquiera de los tres tipos de caracteres también puede tomar los otros dos tipos de caracteres. Lleva a dos funciones que pueden manejar cualquiera de los 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)siempre le da un valor no negativo, incluso cuando se pasa un valor negativo charo negativo signed char, y chrtoma cualquier valor que ordproduce y devuelve exactamente el mismochar .
En la práctica, probablemente solo transmitiría en unsigned charlugar de usar estos, pero lo hacen de forma sucinta, proporcionan un lugar conveniente para agregar la comprobación de errores para int-to- char, y sería más corto y más claro cuando necesite usarlos varias veces en estrecha proximidad.
Si tiene una serie de caracteres que representa un número entero, como "123456", hay dos formas típicas de hacerlo en C: utilice una conversión de propósito especial como atoi () o strtol () , o el sscanf de propósito general () . C ++ (que es realmente un lenguaje diferente disfrazado de una actualización) agrega un tercer flujo de cadena.
Si quiere decir que desea que el patrón de bits exacto en una de sus intvariables sea tratado como unchar , eso es más fácil. En C, los diferentes tipos enteros son realmente más un estado mental que los "tipos" separados reales. Simplemente comience a usarlo donde charse le solicite, y debería estar bien. Es posible que necesite una conversión explícita para que el compilador deje de quejarse en ocasiones, pero todo lo que debería hacer es soltar cualquier bit adicional más allá de 256.
Tengo absolutamente nullhabilidades en C, pero para un análisis simple:
char* something ="123456";int number = parseInt(something);
... esto funcionó para mí:
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;}
Este código invoca rápidamente un comportamiento indefinido y, por lo tanto, no es adecuado para copiar y pegar. (desbordamiento int)
Roland Illig
4
Presumiblemente, desea esta conversión para usar funciones de la biblioteca estándar de C.
En ese caso, hacer (sintaxis de C ++)
typedefunsignedcharUChar;char myCppFunc(char c ){returnchar( someCFunc(UChar( c )));}
La expresión se UChar( c )convierte unsigned charen para deshacerse de los valores negativos, que, a excepción de EOF, no son compatibles con las funciones de C.
Luego, el resultado de esa expresión se usa como argumento real para un intargumento formal. Donde obtienes la promoción automática int. Alternativamente, puede escribir ese último paso explícitamente, comoint( UChar( c ) ) , pero personalmente me parece demasiado detallado.
Estaba teniendo problemas para convertir una matriz de caracteres como "7c7c7d7d7d7d7c7c7c7d7d7d7d7c7c7c7c7c7c7d7d7c7c7c7c7d7c7d7d7d7c7c2e2e2e"en su valor entero real que podría ser representado por '7C' como un valor hexadecimal. Entonces, después de buscar ayuda, creé esto, y pensé que sería genial compartirlo.
Esto separa la cadena de caracteres en sus enteros correctos, y puede ser útil para más personas que solo yo;)
¿Alguna vez has probado este código? El 50 debería ser un 48, el 55 solo funciona para letras mayúsculas ASCII, mientras que su ejemplo contiene letras minúsculas.
Roland Illig
0
Para char o short to int, solo necesita asignar el valor.
c
yc++
, creo que las respuestas que enfrentan ambos idiomas son razonables.char
realmente significa.Respuestas:
Depende de lo que quieras hacer:
Para leer el valor como un código ASCII, puede escribir
para convertir el carácter
'0' -> 0
,'1' -> 1
etc, se puede escribirExplicación :
a - '0'
es equivalente a((int)a) - ((int)'0')
, lo que significa que los valores ascii de los caracteres se restan entre sí. Como0
viene directamente antes1
en la tabla ascii (y así sucesivamente hasta9
), la diferencia entre los dos da el número quea
representa el personaje .fuente
&
-> -10), y le da números mayores que 10 (comox
-> 26)'1'
proporciona un número ASCII que no lo es1
, debe eliminar el desplazamiento'0'
para realinearlo y contar de 0 a 9. Los números consecutivos 1-9 son adyacentes en el número entero ascii.Bueno, en el código ASCII, los números (dígitos) comienzan desde 48 . Todo lo que necesitas hacer es:
fuente
'0'
C y C ++ siempre promueven tipos al menos
int
. Además, los literales de caracteres son de tipoint
C ychar
en C ++.Puede convertir un
char
tipo simplemente asignándolo a unint
.fuente
operator+()
para este propósito.int a = c;
) mantendrá cualquier valor negativo, que las funciones de biblioteca estándar de C no pueden manejar. Las funciones de la biblioteca estándar de C establecen el estándar de lo que significa manejarchar
valores comoint
.char es solo un entero de 1 byte. ¡No hay nada mágico con el tipo char! Así como puedes asignar un short a un int, o un int a un long, puedes asignar un char a un int.
Sí, el nombre del tipo de datos primitivo es "char", lo que insinúa que solo debe contener caracteres. Pero en realidad, "char" es solo una mala elección de nombre para confundir a todos los que intentan aprender el idioma. Un mejor nombre para él es int8_t, y puede usar ese nombre en su lugar, si su compilador sigue el último estándar de C.
Aunque, por supuesto, debe usar el tipo char al hacer el manejo de cadenas, porque el índice de la tabla ASCII clásica cabe en 1 byte. Usted podría sin embargo hacer manejo de cadenas de enteros normales, así, aunque no hay ninguna razón práctica en el mundo real por la que va a querer hacer eso. Por ejemplo, el siguiente código funcionará perfectamente:
Debes darte cuenta de que los caracteres y las cadenas son solo números, como todo lo demás en la computadora. Cuando escribe 'a' en el código fuente, se procesa previamente en el número 97, que es una constante entera.
Entonces, si escribes una expresión como
esto es realmente equivalente a
que luego pasa por las promociones de enteros en lenguaje C
y luego truncado a un carácter para ajustarse al tipo de resultado
Hay muchas cosas sutiles como esta sucediendo entre líneas, donde char se trata implícitamente como un int.
fuente
ascii
, no debe asumir ninguna codificación específica. Establecerchar
igual aint8_t
está mal porque igualmente podría seruint8_t
ouint24_t
.char
siempre es 1 byte y si los tiposint8_t
/uint8_t
existen en el sistema dado (lo cual es muy probable), podrán ajustar el resultado de achar
, porque entonces serán 8 bits. En sistemas altamente exóticos como varios DSP obsoletos,char
tendrá 16 bits yuint8_t
no existirá. Escribir código para la compatibilidad con DSP obsoletos no tiene sentido, al igual que escribir para la compatibilidad con los sistemas de complemento o signo y magnitud. Gran pérdida de tiempo, ya que tales sistemas apenas existen en el mundo real.(Esta respuesta aborda el lado C ++ de las cosas, pero el problema de la extensión del signo también existe en C).
El manejo de los tres
char
tipos (signed
,unsigned
ychar
) es más delicado de lo que parece. Los valores en el rango de 0 aSCHAR_MAX
(que es 127 para un 8 bitschar
) son fáciles:Pero, cuando
somevalue
está fuera de ese rango, solo pasarunsigned char
le da resultados consistentes para los "mismos"char
valores en los tres tipos:Esto es importante cuando se utilizan funciones de ctype.h , como
isupper
otoupper
, debido a la extensión del signo:Tenga en cuenta que la conversión a través de int es implícita; esto tiene el mismo UB:
Para solucionar esto, vaya
unsigned char
, lo que se hace fácilmente envolviendo las funciones ctype.h a través de safe_ctype :Esto funciona porque cualquier función que tome cualquiera de los tres tipos de caracteres también puede tomar los otros dos tipos de caracteres. Lleva a dos funciones que pueden manejar cualquiera de los tipos:
ord(c)
siempre le da un valor no negativo, incluso cuando se pasa un valor negativochar
o negativosigned char
, ychr
toma cualquier valor queord
produce y devuelve exactamente el mismochar
.En la práctica, probablemente solo transmitiría en
unsigned char
lugar de usar estos, pero lo hacen de forma sucinta, proporcionan un lugar conveniente para agregar la comprobación de errores paraint
-to-char
, y sería más corto y más claro cuando necesite usarlos varias veces en estrecha proximidad.fuente
Uso
static_cast<int>
:Editar: Probablemente debería intentar evitar usar
(int)
echa un vistazo a qué uso static_cast <int> (x) en lugar de (int) x? para más información.
fuente
Depende de lo que quieras decir con "convertir".
Si tiene una serie de caracteres que representa un número entero, como "123456", hay dos formas típicas de hacerlo en C: utilice una conversión de propósito especial como atoi () o strtol () , o el sscanf de propósito general () . C ++ (que es realmente un lenguaje diferente disfrazado de una actualización) agrega un tercer flujo de cadena.
Si quiere decir que desea que el patrón de bits exacto en una de sus
int
variables sea tratado como unchar
, eso es más fácil. En C, los diferentes tipos enteros son realmente más un estado mental que los "tipos" separados reales. Simplemente comience a usarlo dondechar
se le solicite, y debería estar bien. Es posible que necesite una conversión explícita para que el compilador deje de quejarse en ocasiones, pero todo lo que debería hacer es soltar cualquier bit adicional más allá de 256.fuente
Tengo absolutamente
null
habilidades en C, pero para un análisis simple:... esto funcionó para mí:
fuente
Presumiblemente, desea esta conversión para usar funciones de la biblioteca estándar de C.
En ese caso, hacer (sintaxis de C ++)
La expresión se
UChar( c )
convierteunsigned char
en para deshacerse de los valores negativos, que, a excepción de EOF, no son compatibles con las funciones de C.Luego, el resultado de esa expresión se usa como argumento real para un
int
argumento formal. Donde obtienes la promoción automáticaint
. Alternativamente, puede escribir ese último paso explícitamente, comoint( UChar( c ) )
, pero personalmente me parece demasiado detallado.Saludos y hth.
fuente
Estaba teniendo problemas para convertir una matriz de caracteres como
"7c7c7d7d7d7d7c7c7c7d7d7d7d7c7c7c7c7c7c7d7d7c7c7c7c7d7c7d7d7d7c7c2e2e2e"
en su valor entero real que podría ser representado por '7C' como un valor hexadecimal. Entonces, después de buscar ayuda, creé esto, y pensé que sería genial compartirlo.Esto separa la cadena de caracteres en sus enteros correctos, y puede ser útil para más personas que solo yo;)
¡Espero eso ayude!
fuente
Para char o short to int, solo necesita asignar el valor.
Lo mismo para int64.
Todos los valores serán 16.
fuente
Puede usar este método atoi para convertir char a int. Para obtener más información, puede consultar este http://www.cplusplus.com/reference/cstdlib/atoi/ , http://www.cplusplus.com/reference/string/stoi/ .
fuente