"0x1800785"와 같은 값을 포함하는 char []가 있지만 값을 제공하려는 함수에는 int가 필요합니다. 어떻게 이것을 int로 변환 할 수 있습니까? 주변을 수색했지만 답을 찾을 수 없습니다. 감사.
답변:
시도해 보셨습니까 strtol()
?
예:
const char *hexstring = "abcdef0";
int number = (int)strtol(hexstring, NULL, 16);
경우에 숫자의 문자열 표현은 시작 0x
접두사, 하나는 있어야 기지로 0을 사용한다 :
const char *hexstring = "0xabcdef0";
int number = (int)strtol(hexstring, NULL, 0);
(16과 같은 명시 적 기반을 지정하는 것도 가능하지만 중복성을 도입하는 것은 권장하지 않습니다.)
"0x"
그냥 사용해야하는 문제에 주어진 0
대신 16
.
strtol
유형 long
을 제공합니다 . 더 큰 헥스에 strtoll
대한 유형 long long
에 사용하십시오 .
또는 자체 구현을 원할 경우이 빠른 함수를 예로 작성했습니다.
/**
* 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;
}
문자열이라고 가정하면 strtol은 어떻습니까?
int54_t
및 uint53_t
.
strtol
최상위 답변이 제안한 것처럼 libc를 사용할 수 있으면 사용하십시오 . 그러나 사용자 정의 항목을 좋아하거나 libc가없는 마이크로 컨트롤러를 사용하는 경우 복잡한 분기없이 약간 최적화 된 버전을 원할 수 있습니다.
#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;
}
비트 이동 마법은 다음과 같이 요약됩니다. 마지막 4 비트 만 사용하고 숫자가 아닌 경우 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)
→ 문자의 경우 9, 소수의 경우 0으로 평가됩니다. 예, 상당히 해키 :)
그래서 잠시 검색하고 strtol이 상당히 느리다는 것을 알게 된 후, 저는 제 자신의 함수를 코딩했습니다. 문자의 대문자에서만 작동하지만 소문자 기능을 추가하는 것은 문제가되지 않습니다.
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;
}
용법:
char *someHex = "#CCFF00FF";
int hexDevalue = hexToInt(someHex, 1, 8);
변환하려는 16 진수가 오프셋 1에서 시작하기 때문에 1이고 16 진수 길이이기 때문에 8입니다.
Speedtest (1.000.000 호출) :
strtol ~ 0.4400s
hexToInt ~ 0.1100s
빠르고 더러운 솔루션 :
// 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;
}
입력이 정확하고 유효성 검사가 포함되지 않았는지 확인해야합니다 (C라고 말할 수 있음). 다행스럽게도 매우 컴팩트합니다. 'A'에서 'F'로, 'a'에서 'f'로 작동합니다.
접근 방식은 ASCII 테이블에서 알파벳 문자의 위치에 의존합니다. 예를 들어 Wikipedia ( https://en.wikipedia.org/wiki/ASCII#/media/File:USASCII_code_chart.png ) 를 살펴 보겠습니다 . 간단히 말해서 숫자는 문자 아래에 있으므로 숫자 (0 ~ 9)는 0에 대한 코드를 빼면 쉽게 변환됩니다. 알파벳 문자 (A ~ F)는 마지막 3 비트 이외의 0으로 읽히고 (효과적으로 대문자 또는 소문자로 작동하도록 함) 1을 빼고 (비트 마스킹 후 알파벳이 위치 1에서 시작하기 때문에) 10을 더합니다 ( A에서 F는 16 진수 코드에서 10 번째에서 15 번째 값을 나타 내기 때문입니다. 마지막으로 인코딩 된 숫자의 하단 및 상단 니블을 형성하는 두 자리를 결합해야합니다.
여기에서는 동일한 접근 방식을 사용합니다 (사소한 변형 포함).
#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;
}
char 배열을 포함하는 16 진수를 추가 라이브러리가 필요없는 정수로 직접 변환하는 함수입니다.
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;
}
나는 사용하지 않고 16 진수 / 10 진수 변환을 위해 librairy를 만들었습니다 stdio.h
. 사용하기 매우 간단합니다.
unsigned hexdec (const char *hex, const int s_hex);
첫 번째 변환 전에 다음을 사용하여 변환에 사용되는 배열을 초기화하십시오.
void init_hexdec ();
여기 github의 링크 : https://github.com/kevmuret/libhex/
나는 비슷한 일을했는데, 그것이 실제로 나를 위해 일하는 데 도움이 될 것이라고 생각합니다.
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;}}
여기에서는 8 자 문자열 만 가져 왔습니다. u가 동일한 16 진수 값을 제공하기 위해 'a'에 대한 유사한 논리를 'f'에 추가 할 수 있기를 원한다면, 나는 그것을 필요로하지 않았기 때문에 그렇게하지 않았습니다.
xtoi (stdlib.h)를 사용하십시오. 문자열에는 처음 두 인덱스로 "0x"가 있으므로 xtoi & val [2]를 전송하여 val [0] 및 val [1]을 잘라냅니다.
xtoi( &val[2] );
xtoi
표준 기능이 아님
나는 이것이 정말 오래되었다는 것을 알고 있지만 솔루션이 너무 복잡해 보였다고 생각합니다. 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