문자 숫자를 C의 해당 정수로 변환


103

C에서 문자를 정수로 변환하는 방법이 있습니까?

예를 들어에서 '5'5까지?

답변:


149

다른 답변에 따라 이것은 괜찮습니다.

char c = '5';
int x = c - '0';

또한 오류 검사를 위해 isdigit (c)가 참인지 먼저 확인하는 것이 좋습니다. 예를 들어 다음과 같이 문자에 대해 완전히 이식 할 수는 없습니다.

char c = 'b';
int x = c - 'a'; // x is now not necessarily 1

표준은 숫자 '0'에서 '9'까지의 char 값이 연속적임을 보장하지만 알파벳 문자와 같은 다른 문자에 대해서는 보장하지 않습니다.


3
@Paul Tomblin : 대답에서 말했듯이 표준 보장 '0'에서 '9'는 연속적이지만 'a'에서 'z'와 같은 다른 문자에 대해서는 이러한 보장을하지 않기 때문에 문자가 아닌 숫자에 대해서는 예입니다.
Chris Young

char c = 'b'; int x = c- 'a'; 그러면 x는 ASCII에서만 1이 될까요?
Pan

@Pan ASCII를 포함한 모든 인코딩에서 'a'보다 'b'가 1 더 많습니다. 이것은 EBCDIC에서 여전히 유효하지만 ( 'j'- 'i') == 8이됩니다.
Chris Young

@ChrisYoung 왜? EBCDIC에서 'j'는 'i'보다 1이 더 많지 않습니까?
Pan

2
atoi가 사용되지 않는 곳에서 내가 무엇을 놓치고 있습니까?
Daniel

41

다음과 같이 '0'을 뺍니다.

int i = c - '0';

표준 C의 범위에있는 각 디지트를 보장한다 '0'..'9'(섹션에서 이전 자리에 1을 더한 5.2.1/3C99 초안 ). C ++도 마찬가지입니다.


1
이 대답은 char이 / 이미 / 실제로 정수이고 구현 정의 기호 (즉, 서명되거나 서명되지 않을 수 있음)에 관계없이 CHAR_BITS 길이라고 언급 한 경우 더 좋을 것입니다.
Arafangion

그게 정말 도움이되는지 잘 모르겠습니다. 그러나 Chris는 a..z가 반드시 연속적이지 않은 좋은 지적을했습니다. 나는 대신 그것을 언급 했어야했다. 지금은 경주 : 원이야
litb - 요하네스 SCHAUB을

1
당신의 대답은 당신이 당신의 대답을 인정했기 때문에 더 낫습니다.-Chris는 그의 물건을 아주 잘 만들었을 것입니다. :)
Arafangion

감사합니다. 나는 C의 상태에 대해 확신하지 못했다는 것을 인정한다. 그래서 나는 찾아 보았고, 내가 이미 거기에 있었기 때문에 나는 대답에 참조를 붙여 넣었다. :)
Johannes Schaub-litb

그리고 그게 나보다 몇 점 더 많은 이유입니다. :)
Arafangion

29

우연의 일치로 문자열 을 정수 로 변환 하려면 그렇게 할 수도 있습니다!

char *num = "1024";
int val = atoi(num); // atoi = ASCII TO Int

val지금은 1024입니다. 분명히 atoi()괜찮습니다. 앞서 언급 한 내용은 저에게만 적용됩니다 (OS X (여기에 Lisp 농담 삽입)). 다음 예제에 대략적으로 매핑되는 매크로라고 들었습니다.이 매크로 strtol()는보다 일반적인 용도의 함수 인을 사용하여 대신 변환을 수행합니다.

char *num = "1024";
int val = (int)strtol(num, (char **)NULL, 10); // strtol = STRing TO Long

strtol() 다음과 같이 작동합니다.

long strtol(const char *str, char **endptr, int base);

으로 변환 *str하여 long기본 base숫자 인 것처럼 처리합니다 . **endptrnull이 아닌 경우 strtol()발견 된 첫 번째 숫자가 아닌 문자를 보유합니다 (하지만 누가 신경 쓰는지).


atoi에는 스레드 문제가 없으며 (정적 데이터가 없음) 더 이상 사용되지 않습니다. 사실 기능적으로 다음과 같습니다. #define atoi (x) (int) (strtol ((x), NULL, 10)
Evan Teran

5
atoi의 문제는 "여기에서 숫자를 찾을 수 없음"값으로 0을 사용하므로 atoi ( "0") 및 atoi ( "one") 모두 0을 반환합니다. 이것이 작동하지 않는 경우 다시 사용하려면 strtol () 또는 sscanf ()를 찾으십시오.
David Thornley

물론 strtol의 또 다른 장점은 숫자 뒤에 오는 동일한 문자열에서 다른 것을 읽어야 할 수도 있다는 것입니다.
dfeuer 2012

@EvanTeran 불행히도 Visual Studio를 실행하면 감가 상각 경고가 표시됩니다 (비활성화하지 않으면 컴파일되지 않음). VS는 이제 itoa_s().
Simon

7

다음과 같이 char '0'또는 int 48을 뺍니다.

char c = '5';
int i = c - '0';

설명 : 내부적으로 ASCII 값으로 작동 합니다. ASCII 테이블에서 문자 5 의 10 진수 값 은 53 이고 0은 48 입니다. 따라서 53-48 = 5

또는

char c = '5';
int i = c - 48; // Because decimal value of char '0' is 48

즉 , 숫자 문자에서 48 을 빼면 정수가 자동으로 변환됩니다.


6
char numeralChar = '4';
int numeral = (int) (numeralChar - '0');

numeralChar - '0'이미 유형 int이므로 캐스트가 필요하지 않습니다. 아니더라도 캐스트가 필요하지 않습니다.
Alok Singhal

응, 강압적이지 않습니까? Java가 내 인식을 채색했을 수도 있습니다. 아니면 내가 완전히 착각하여 Java로 강압 될 수도 있습니다. :)
Kevin Conner

5

문자 숫자를 해당 정수로 변환합니다. 다음과 같이하십시오.

char c = '8';                    
int i = c - '0';

위 계산의 논리는 ASCII 값을 사용하는 것입니다. 문자 8의 ASCII 값은 56, 문자 0의 ASCII 값은 48입니다. 정수 8의 ASCII 값은 8입니다.

두 문자를 빼면 ASCII 문자 사이에서 빼기가 발생합니다.

int i = 56 - 48;   
i = 8;

왜 나만 찬성 투표를합니까? 설명은 간단하고 유익한 정보 : +1 :
브랜든 Benefield

0

ASCII의 단일 문자 0-9 인 경우 ASCII 값에서 ASCII 0 문자의 값을 빼면 정상적으로 작동합니다.

더 큰 숫자를 변환하려면 다음을 수행하십시오.

char *string = "24";

int value;

int assigned = sscanf(string, "%d", &value);

** 상태를 확인하는 것을 잊지 마십시오 (위의 경우에 작동했다면 1이어야 함).

폴.


0
char chVal = '5';
char chIndex;

if ((chVal >= '0') && (chVal <= '9')) {

    chIndex = chVal - '0';
}
else 
if ((chVal >= 'a') && (chVal <= 'z')) {

    chIndex = chVal - 'a';
}
else 
if ((chVal >= 'A') && (chVal <= 'Z')) {

    chIndex = chVal - 'A';
}
else {
    chIndex = -1; // Error value !!!
}

0

이와 같은 작업을 수행해야 할 때 원하는 값으로 배열을 미리 굽습니다.

const static int lookup[256] = { -1, ..., 0,1,2,3,4,5,6,7,8,9, .... };

그러면 변환이 쉽습니다.

int digit_to_int( unsigned char c ) { return lookup[ static_cast<int>(c) ]; }

이것은 기본적으로 ctype 라이브러리의 많은 구현에서 취하는 접근 방식입니다. 16 진수로도 작동하도록 이것을 간단하게 조정할 수 있습니다.


단일 십진수 (또는 8 진수)를 변환하는 데는 매우 비효율적으로 보입니다. 룩업 테이블의 관련 부분이 L1 캐시에 있지 않으면 하나의 값을 얻기 위해 여러 사이클을 불어 넣어 가져옵니다. 솔직히, 전체 숫자를 변환하는 경우 이것이 좋은 생각이라고 의심하는 경향이 있지만 측정해야합니다. 물론 헥스에 대해서는 훨씬 더 경쟁력이 있습니다.
dfeuer 2012-07-21

0

이것을 확인하십시오.

char s='A';

int i = (s<='9')?(s-'0'):(s<='F')?((s-'A')+10):((s-'a')+10);

0,1,2, ...., E, F에만 해당됩니다.


0

다음 atol()기능을 사용하십시오 .

#include <stdio.h>
#include <stdlib.h>

int main() 
{
    const char *c = "5";
    int d = atol(c);
    printf("%d\n", d);

}

0

예를 들어 숫자가 '5'ASCII이면 이진수 0011 0101(53)로 표시됩니다. 모든 숫자는 가장 높은 4 비트를 0011가지며 가장 낮은 4 비트는 bcd의 숫자를 나타냅니다. 그래서 당신은

char cdig = '5';
int dig = cdig & 0xf; // dig contains the number 5

가장 낮은 4 비트 또는 동일한 숫자를 가져옵니다. asm에서는 (다른 답변에서와 같이) and대신 작업을 사용 합니다 sub.


'5'53 (이다 00110101)
eyllanesc는

@eyllanesc 처음에는 4였습니다. 감사합니다. 편집했습니다.
Garmekain

0

다음은 char의 숫자를 int로 또는 그 반대로 변환 할 수있는 도우미 함수입니다.

int toInt(char c) {
    return c - '0';
}

char toChar(int i) {
    return i + '0';
}

-2

함수를 사용하십시오 : 배열에서 정수로의 경우 atoi, 배열에서 부동 유형으로의 경우 atof; 또는

char c = '5';
int b = c - 48;
printf("%d", b);

여러 답변이 이미 이것을 다루었습니다. 이것은 그들이 이미 다루지 않은 것을 추가합니다.
ShadowRanger 2017 년

-3

당신은 그것을 int (또는 float 또는 double 또는 당신이 원하는 다른 무엇이든)로 캐스팅하고 anoter 변수에 저장합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.