Tengo un char [] que contiene un valor como "0x1800785" pero la función a la que quiero dar el valor requiere un int, ¿cómo puedo convertir esto en un int? He buscado alrededor pero no puedo encontrar una respuesta. Gracias.
Tengo un char [] que contiene un valor como "0x1800785" pero la función a la que quiero dar el valor requiere un int, ¿cómo puedo convertir esto en un int? He buscado alrededor pero no puedo encontrar una respuesta. Gracias.
Respuestas:
¿Usted ha intentado strtol()?
strtol - convierte la cadena en un entero largo
Ejemplo:
const char *hexstring = "abcdef0";
int number = (int)strtol(hexstring, NULL, 16);
En caso de que la representación de cadena del número comience con un 0xprefijo, se debe usar 0 como base:
const char *hexstring = "0xabcdef0";
int number = (int)strtol(hexstring, NULL, 0);
(También es posible especificar una base explícita como 16, pero no recomendaría introducir redundancia).
"0x"como se indica en la pregunta, debe usar en 0lugar de 16.
strtolle da un tipo de letra longque es genial cuando se trata de un hexágono muy grande. Úselo strtollcomo tipo long longpara hexágonos aún más grandes.
O si desea tener su propia implementación, escribí esta función rápida como ejemplo:
/**
* hex2int
* take a hex string and convert it to a 32bit number (max 8 hex digits)
*/
uint32_t hex2int(char *hex) {
uint32_t val = 0;
while (*hex) {
// get current character then increment
uint8_t byte = *hex++;
// transform hex character to the 4bit equivalent number, using the ascii table indexes
if (byte >= '0' && byte <= '9') byte = byte - '0';
else if (byte >= 'a' && byte <='f') byte = byte - 'a' + 10;
else if (byte >= 'A' && byte <='F') byte = byte - 'A' + 10;
// shift 4 to make space for new digit, and add the 4 bits of the new digit
val = (val << 4) | (byte & 0xF);
}
return val;
}
Algo como esto podría ser útil:
char str[] = "0x1800785";
int num;
sscanf(str, "%x", &num);
printf("0x%x %i\n", num, num);
Leer man sscanf
%xdebe recibir la dirección de un unsigned int. E incluso si arregla eso, si el número representado por la cadena es mayor que, UINT_MAXentonces es un comportamiento indefinido nuevamente
Suponiendo que te refieres a que es una cadena, ¿qué tal strtol ?
int . +1, por cierto.
int54_ty uint53_t.
Úselo strtolsi tiene libc disponible como sugiere la respuesta principal. Sin embargo, si le gustan las cosas personalizadas o está en un microcontrolador sin libc o algo así, es posible que desee una versión ligeramente optimizada sin ramificaciones complejas.
#include <inttypes.h>
/**
* xtou64
* Take a hex string and convert it to a 64bit number (max 16 hex digits).
* The string must only contain digits and valid hex characters.
*/
uint64_t xtou64(const char *str)
{
uint64_t res = 0;
char c;
while ((c = *str++)) {
char v = (c & 0xF) + (c >> 6) | ((c >> 3) & 0x8);
res = (res << 4) | (uint64_t) v;
}
return res;
}
La magia del cambio de bits se reduce a: solo use los últimos 4 bits, pero si no es un dígito, agregue también 9.
unsigned long long int hextou64(char *str) { unsigned long long int n = 0; char c, v; for (unsigned char i = 0; i < 16; i++) { c = *(str + i); v = (c & 0xF) + (c >> 6) | ((c >> 3) & 0x8); n = (n << 4) | (unsigned long long int)v; } return n; }
(c >> 6) | ((c >> 3) & 0x8)→ se evalúa como 9 en el caso de una letra, o 0 en el caso de un decimal. Sí, bastante hacky :)
Pruebe el siguiente bloque de código, funciona para mí.
char *p = "0x820";
uint16_t intVal;
sscanf(p, "%x", &intVal);
printf("value x: %x - %d", intVal, intVal);
La salida es:
value x: 820 - 2080
Entonces, después de un tiempo de búsqueda y descubrir que strtol es bastante lento, he codificado mi propia función. Solo funciona para mayúsculas en letras, pero agregar funcionalidad en minúsculas no es un problema.
int hexToInt(PCHAR _hex, int offset = 0, int size = 6)
{
int _result = 0;
DWORD _resultPtr = reinterpret_cast<DWORD>(&_result);
for(int i=0;i<size;i+=2)
{
int _multiplierFirstValue = 0, _addonSecondValue = 0;
char _firstChar = _hex[offset + i];
if(_firstChar >= 0x30 && _firstChar <= 0x39)
_multiplierFirstValue = _firstChar - 0x30;
else if(_firstChar >= 0x41 && _firstChar <= 0x46)
_multiplierFirstValue = 10 + (_firstChar - 0x41);
char _secndChar = _hex[offset + i + 1];
if(_secndChar >= 0x30 && _secndChar <= 0x39)
_addonSecondValue = _secndChar - 0x30;
else if(_secndChar >= 0x41 && _secndChar <= 0x46)
_addonSecondValue = 10 + (_secndChar - 0x41);
*(BYTE *)(_resultPtr + (size / 2) - (i / 2) - 1) = (BYTE)(_multiplierFirstValue * 16 + _addonSecondValue);
}
return _result;
}
Uso:
char *someHex = "#CCFF00FF";
int hexDevalue = hexToInt(someHex, 1, 8);
1 porque el hexadecimal que queremos convertir comienza en el desplazamiento 1, y 8 porque es la longitud hexadecimal.
Speedtest (1.000.000 de llamadas):
strtol ~ 0.4400s
hexToInt ~ 0.1100s
Una solución rápida y sucia:
// makes a number from two ascii hexa characters
int ahex2int(char a, char b){
a = (a <= '9') ? a - '0' : (a & 0x7) + 9;
b = (b <= '9') ? b - '0' : (b & 0x7) + 9;
return (a << 4) + b;
}
Debe asegurarse de que su entrada sea correcta, sin validación incluida (se podría decir que es C). Menos mal que es bastante compacto, funciona con 'A' a 'F' y 'a' a 'f'.
El enfoque se basa en la posición de los caracteres del alfabeto en la tabla ASCII, echemos un vistazo, por ejemplo, a Wikipedia ( https://en.wikipedia.org/wiki/ASCII#/media/File:USASCII_code_chart.png ). En pocas palabras, los números están debajo de los caracteres, por lo que los caracteres numéricos (0 a 9) se convierten fácilmente restando el código por cero. Los caracteres alfabéticos (de la A a la F) se leen poniendo a cero los tres últimos bits (lo que hace que funcione efectivamente con mayúsculas o minúsculas), restando uno (porque después del enmascaramiento de bits, el alfabeto comienza en la posición uno) y sumando diez ( porque de la A a la F representan el valor 10 al 15 en código hexadecimal). Finalmente, necesitamos combinar los dos dígitos que forman el nibble inferior y superior del número codificado.
Aquí vamos con el mismo enfoque (con variaciones menores):
#include <stdio.h>
// takes a null-terminated string of hexa characters and tries to
// convert it to numbers
long ahex2num(unsigned char *in){
unsigned char *pin = in; // lets use pointer to loop through the string
long out = 0; // here we accumulate the result
while(*pin != 0){
out <<= 4; // we have one more input character, so
// we shift the accumulated interim-result one order up
out += (*pin < 'A') ? *pin & 0xF : (*pin & 0x7) + 9; // add the new nibble
pin++; // go ahead
}
return out;
}
// main function will test our conversion fn
int main(void) {
unsigned char str[] = "1800785"; // no 0x prefix, please
long num;
num = ahex2num(str); // call the function
printf("Input: %s\n",str); // print input string
printf("Output: %x\n",num); // print the converted number back as hexa
printf("Check: %ld = %ld \n",num,0x1800785); // check the numeric values matches
return 0;
}
Esta es una función para convertir directamente una matriz de caracteres hexadecimal que contiene un número entero que no necesita una biblioteca adicional:
int hexadecimal2int(char *hdec) {
int finalval = 0;
while (*hdec) {
int onebyte = *hdec++;
if (onebyte >= '0' && onebyte <= '9'){onebyte = onebyte - '0';}
else if (onebyte >= 'a' && onebyte <='f') {onebyte = onebyte - 'a' + 10;}
else if (onebyte >= 'A' && onebyte <='F') {onebyte = onebyte - 'A' + 10;}
finalval = (finalval << 4) | (onebyte & 0xF);
}
finalval = finalval - 524288;
return finalval;
}
Hice una biblioteca para hacer una conversión hexadecimal / decimal sin el uso de stdio.h. Muy simple de usar:
unsigned hexdec (const char *hex, const int s_hex);
Antes de la primera conversión, inicialice la matriz utilizada para la conversión con:
void init_hexdec ();
Aquí el enlace en github: https://github.com/kevmuret/libhex/
He hecho algo similar, creo que podría ayudarte, en realidad funciona para mí.
int main(){ int co[8],i;char ch[8];printf("please enter the string:");scanf("%s",ch);for(i=0;i<=7;i++){if((ch[i]>='A')&&(ch[i]<='F')){co[i]=(unsigned int)ch[i]-'A'+10;}else if((ch[i]>='0')&&(ch[i]<='9')){co[i]=(unsigned int)ch[i]-'0'+0;}}
aquí solo he tomado una cadena de 8 caracteres. Si quieres, puedes agregar una lógica similar para 'a' a 'f' para dar sus valores hexadecimales equivalentes, no lo he hecho porque no lo necesitaba.
Utilice xtoi (stdlib.h). La cadena tiene "0x" como dos primeros índices, así que recorta val [0] y val [1] enviando xtoi & val [2].
xtoi( &val[2] );
xtoino es una función estándar
Sé que esto es muy antiguo, pero creo que las soluciones parecían demasiado complicadas. Prueba esto en VB:
Public Function HexToInt(sHEX as String) as long
Dim iLen as Integer
Dim i as Integer
Dim SumValue as Long
Dim iVal as long
Dim AscVal as long
iLen = Len(sHEX)
For i = 1 to Len(sHEX)
AscVal = Asc(UCase(Mid$(sHEX, i, 1)))
If AscVal >= 48 And AscVal <= 57 Then
iVal = AscVal - 48
ElseIf AscVal >= 65 And AscVal <= 70 Then
iVal = AscVal - 55
End If
SumValue = SumValue + iVal * 16 ^ (iLen- i)
Next i
HexToInt = SumValue
End Function