C 및 C ++에서 char을 int로 변환


400

C 및 C ++에서 a char를 어떻게 변환 int합니까?


1
@Matt : 좀 더 구체적으로 작성하는 것이 좋습니다. 일반화에 대한 질문은 해당 작업에 맞지 않거나 맞지 않는 일반화 된 답변 만 초대합니다 . 요청해야 할 때 올바르게 일반화하기에 충분하지 않을 수도 있습니다.
건배와 hth. -Alf

@Alf P. Steinbach : 원래 질문은 어떤 언어에 관한 모호한 것이었다. 키워드로 c하고 c++, 나는 두 언어를 직면 답변을 합리적인 생각합니다.
매트 소목 장이

8
다른 기술 포럼에 대한 폭 넓은 경험을 바탕으로 OP는 실제로 "숫자 (기본 10)의 텍스트 표현을 가져 와서 해당 숫자로 변환하는 방법"을 의미합니다. 일반적으로 C 및 C ++ 네오 피트는 일반적으로 해당 언어에서 텍스트가 작동하는 방식과 실제로 의미하는 것에 대해 매우 모호한 아이디어를 가지고 있습니다 char.
Karl Knechtel

3
@ KarlKnechtel : 그것이 사실이라면 (ASCII가 전체 범위를 다루지 않더라도 많은 초기 자습서가 문자에서 ASCII 값을 가져 오는 것을 권장하기 때문에 약 50/50), OP는 명확해야합니다.하지만 그것은 속임수입니다. 의 stackoverflow.com/questions/439573/... .
Fred Nurk

3
OP는이 질문을 명확하게하는 데 3 시간이 걸렸지 만 실패했습니다. 따라서 실제로 요청되는 내용을 알 수있는 방법이 없습니다. 결선 투표.
sbi

답변:


551

수행하려는 작업에 따라 다릅니다.

ASCII 코드로 값을 읽으려면 다음을 작성할 수 있습니다.

char a = 'a';
int ia = (int)a; 
/* note that the int cast is not necessary -- int ia = a would suffice */

문자 변환 '0' -> 0, '1' -> 1등, 당신은 쓸 수 있습니다

char a = '4';
int ia = a - '0';
/* check here if ia is bounded by 0 and 9 */

설명 :
a - '0'((int)a) - ((int)'0')문자와 동일하며 문자의 ASCII 값을 뺍니다. ascii 테이블에서 0바로 앞에 오기 때문에 1(그리고까지 계속 9)이 둘의 차이는 문자가 a나타내는 숫자를 나타냅니다.


14
ia = (a- '0') % 48;
Kshitij Banerjee

@KshitijBanerjee 두 가지 이유로 좋은 생각이 아닙니다. '0'이전의 ASCII 문자에 음수를 제공하고 (예 &: -10)-10보다 큰 숫자를 제공합니다 (예 : x-> 26)
SheetJS

2
int ia = a- '
funk

5
@ kevin001 char을 int로 변환하고 문자가 '1'아닌 ASCII 숫자를 제공 1하려면 오프셋 '0'을 제거하여 0-9에서 카운트하도록 다시 정렬해야합니다. 연속적인 숫자 1-9는 ASCII 정수에 인접 해 있습니다.
krisdestruction

캐스트가 필요하지 않습니다 / 희망
Craig Estey

97

ASCII 코드에서 숫자 (숫자)는 48 부터 시작 합니다. 당신이해야 할 일은 :

int x = (int)character - 48;

19
@chad : 더 읽기 쉽고 이식성이 뛰어납니다. C 및 C ++는 ASCII 표현을 보장하지는 않지만 사용중인 표현이 10 진수 10 진수의 표현이 연속적이고 숫자 순서임을 보장합니다.
벤 Voigt

내가 바꿨 '0'

59

C 및 C ++는 항상 형식을 적어도로 승격 int시킵니다. 또한 문자 리터럴은 intC 및 charC ++ 형식입니다.

char에 할당하여 간단히 유형을 변환 할 수 있습니다 int.

char c = 'a'; // narrowing on C
int a = c;

3
이 목적을 위해 심하게 평가되지 않은 단항 operator+() 을 사용할 수도 있습니다 .
Cubbi

24
-1 질문에 대한 의미있는 해석에 대한 답은 틀립니다. 이 (code int a = c;)는 C 표준 라이브러리 함수가 처리 할 수없는 음수 값을 유지합니다. C 표준 라이브러리 함수는 char값을로 처리한다는 의미에 대한 표준을 설정합니다 int.
건배와 hth. -Alf

6
@ 매트 : 나는 downvote를 유지하고 있습니다. 가능하면 강화하겠습니다! 당신과 다른 사람들이 생각한 질문 해석은 너무 사소하기 때문에 의미가 없으며 OP의 특정 유형 조합에 대해서는 그리 중요하지 않은 실질적인 문제가 있기 때문입니다. 당신이주는 조언 은 초보자 에게 직접 위험 합니다. C 표준 라이브러리 문자 분류 기능을 사용하는 프로그램에 대해서는 정의되지 않은 동작 이 발생할 가능성이 큽니다 . 심판. @Sayam의 답변에, 그는 그 대답을 삭제했습니다.
건배와 hth. -Alf

3
-1이 올바르지 않은 경우 : 1252 하이 비트 문자를 전달하면 isupper ()에 정의되지 않은 결과가 나타납니다.
Chris Becke

1
"항상 홍보"란 무엇을 의미합니까? 암시 적 변환, 특정 유형의 매개 변수가 전달되는 동안 (예 : varargs 함수로), 연산자가 피연산자를 호환 가능한 유형으로 만들어야하는 경우 값이 승격됩니다. 그러나 값이 승격되지 않는 경우가 있습니다 (char를 기대하는 함수에 char을 전달하는 경우와 같이). 그렇지 않으면 int보다 작은 유형은 없습니다.
Adrian McCarthy

31

char은 1 바이트 정수입니다. char 타입에는 마법이 없습니다! int에 short를, int에 long을 할당 할 수 있듯이 char을 int에 할당 할 수 있습니다.

그렇습니다. 기본 데이터 유형의 이름은 "char"이며 문자 만 포함해야합니다. 그러나 실제로 "char"는 언어를 배우려고하는 모든 사람을 혼란스럽게 만드는 나쁜 선택입니다. 더 좋은 이름은 int8_t이며, 컴파일러가 최신 C 표준을 따르는 경우 그 이름을 대신 사용할 수 있습니다.

물론 당신의 생각 한다 문자열 처리를 할 때의 문자 형식을 사용하기 때문에 1 바이트의 고전 ASCII 테이블 적합의 인덱스입니다. 당신은 할 수 당신이 이제까지 그렇게 할 이유를 현실 세계에서 실제적인 이유가 없음에도 불구하고 그러나,뿐만 아니라 일반의 int와 문자열 처리를 할. 예를 들어 다음 코드는 완벽하게 작동합니다.

  int str[] = {'h', 'e', 'l', 'l', 'o', '\0' };

  for(i=0; i<6; i++)
  {
    printf("%c", str[i]);
  }

문자와 문자열은 컴퓨터의 다른 모든 것과 마찬가지로 숫자라는 것을 알아야합니다. 소스 코드에 'a'를 쓰면 정수 상수 인 숫자 97으로 사전 처리됩니다.

따라서 다음과 같은 표현식을 작성하면

char ch = '5';
ch = ch - '0';

이것은 실제로

char ch = (int)53;
ch = ch - (int)48;

그런 다음 C 언어 정수 프로모션을 진행합니다.

ch = (int)ch - (int)48;

그런 다음 결과 유형에 맞게 문자로 자릅니다.

ch = (char)( (int)ch - (int)48 );

char이 암시 적으로 int로 처리되는 줄 사이에 이와 같은 미묘한 것들이 많이 있습니다.


질문에 태그가 지정되어 ascii있지 않으므로 특정 인코딩을 가정해서는 안됩니다. 설정 char과 동일하기 int8_t가 똑같이 가능성이있을 수 있기 때문에 잘못 uint8_t이나 uint24_t.
Roland Illig

1
@RolandIllig 아니요, a char는 항상 1 바이트이며 주어진 시스템에 유형 int8_t/ uint8_t존재하는 경우 (아마도 가능성이 높음) char8 비트이므로 a의 결과에 맞출 수 있습니다. 다양한 구식 DSP와 같은 매우 이국적인 시스템에서는 char16 비트가되고 uint8_t존재하지 않습니다. 더 이상 사용되지 않는 DSP와의 호환성을위한 코드 작성은 타당하지 않으며, 보완 또는 부호 및 크기 시스템과의 호환성을 위해 작성하는 것입니다. 그러한 시스템은 현실 세계에 거의 존재하지 않기 때문에 엄청난 시간 낭비입니다.
Lundin

18

(이 답변은 C ++ 측면을 다루지 만 부호 확장 문제는 C에도 존재합니다.)

세 가지 char유형 ( signed, unsignedchar)을 모두 처리하는 것이 처음 나타나는 것보다 더 섬세합니다. 0에서 SCHAR_MAX8 까지의 값 은 127입니다 char.

char c = somevalue;
signed char sc = c;
unsigned char uc = c;
int n = c;

그러나 somevalue해당 범위를 벗어나 면 세 가지 유형 unsigned char의 "동일한" char값에 대해 일관된 결과 만 제공 됩니다.

char c = somevalue;
signed char sc = c;
unsigned char uc = c;
// Might not be true: int(c) == int(sc) and int(c) == int(uc).
int nc = (unsigned char)c;
int nsc = (unsigned char)sc;
int nuc = (unsigned char)uc;
// Always true: nc == nsc and nc == nuc.

에서 기능을 사용할 때 중요 ctype.h 같은, isupper또는 toupper때문에 부호 확장의 :

char c = negative_char;  // Assuming CHAR_MIN < 0.
int n = c;
bool b = isupper(n);  // Undefined behavior.

int를 통한 변환은 암시 적입니다. 이것은 동일한 UB를 가지고 있습니다 :

char c = negative_char;
bool b = isupper(c);

이 문제를 해결하려면 safe_ctype을 통해 ctype.h 함수를 unsigned char래핑하여 쉽게 수행 하십시오 .

template<int (&F)(int)>
int safe_ctype(unsigned char 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.

세 가지 문자 유형 중 하나를 사용하는 모든 함수가 다른 두 가지 문자 유형도 사용할 수 있기 때문에 작동합니다. 모든 유형을 처리 할 수있는 두 가지 기능이 있습니다.

int ord(char c) { return (unsigned char)c; }
char chr(int n) {
  assert(0 <= n);  // Or other error-/sanity-checking.
  assert(n <= UCHAR_MAX);
  return (unsigned char)n;
}

// Ord and chr are named to match similar functions in other languages
// and libraries.

ord(c)부정적인 통과하더라도 - 항상 당신에게 음수가 아닌 값을 제공 char또는 음을 signed char- 그리고 chr값 소요 ord생산을 다시 똑같은 제공합니다 char.

실제로, 나는 아마 통해 캐스팅 것 unsigned char대신 다음을 사용하지만, 간결, 캐스팅 포장에 대한 오류 검사를 추가 할 수있는 편리한 장소 제공 할 intDi의를 char당신이 그 (것)들에게 여러 번 사용해야하는 경우에, 짧은 더 명확한 것 가까이에.



7

"변환"의 의미에 따라 다릅니다.

"123456"과 같이 정수를 나타내는 일련의 문자가있는 경우 C에서 두 가지 일반적인 방법이 있습니다. atoi () 또는 strtol () 과 같은 특수 목적 변환 또는 범용 sscanf () . C ++ (업그레이드로 가장 다른 언어 임)은 세 번째 문자열 스트림을 추가합니다.

int변수 중 하나의 정확한 비트 패턴 을으로 취급 하려는 경우 char더 쉽습니다. C에서 다른 정수 유형은 실제로 별도의 "유형"보다 더 마음의 상태입니다. chars가 필요한 곳에 사용하기 시작하면 괜찮을 것입니다. 컴파일러가 가끔씩 종료되도록 명시 적으로 변환해야 할 수도 있지만 256 이상으로 여분의 비트를 삭제하기 만하면됩니다.


6

나는 nullC에서 절대적으로 기술을 가지고 있지만 간단한 파싱을 위해 :

char* something = "123456";

int number = parseInt(something);

... 이것은 나를 위해 일했다 :

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;
}

이 코드는 정의되지 않은 동작을 빠르게 호출하므로 복사 및 붙여 넣기에는 적합하지 않습니다. (int overflow)
Roland Illig

4

아마도 C 표준 라이브러리의 함수를 사용하기 위해이 변환을 원할 것입니다.

이 경우 (C ++ 구문)

typedef unsigned char UChar;

char myCppFunc( char c )
{
    return char( someCFunc( UChar( c ) ) );
}

음수 값을 제거하기 위해 식이 UChar( c )변환됩니다 unsigned char. 음수 값은 EOF를 제외하고 C 함수에서 지원되지 않습니다.

그런 다음 해당 표현식의 결과는 int공식 인수에 대한 실제 인수로 사용됩니다 . 자동 프로모션을받는 곳 : int. 또는 마지막 단계를와 같이 명시 적으로 작성할 수 int( UChar( c ) )있지만 개인적으로는 너무 장황합니다.

건배 & hth.,


0

char 배열을 "7c7c7d7d7d7d7c7c7c7d7d7d7d7c7c7c7c7c7c7d7d7c7c7c7c7d7c7d7d7d7c7c2e2e2e"실제 정수 값으로 변환하는 데 문제 가있었습니다.이 정수 값은`7C '로 16 진수 값으로 나타낼 수 있습니다. 그래서 도움을 구한 후 이것을 만들었고 공유하는 것이 좋을 것이라고 생각했습니다.

이것은 char 문자열을 올바른 정수로 분리하며 나보다 더 많은 사람들에게 도움이 될 수 있습니다.)

unsigned int* char2int(char *a, int len)
{
    int i,u;
    unsigned int *val = malloc(len*sizeof(unsigned long));

    for(i=0,u=0;i<len;i++){
        if(i%2==0){
            if(a[i] <= 57)
                val[u] = (a[i]-50)<<4;
            else
                val[u] = (a[i]-55)<<4;
        }
        else{
            if(a[i] <= 57)
                val[u] += (a[i]-50);
            else
                val[u] += (a[i]-55);
            u++;
        }
    }
    return val;
}

그것이 도움이되기를 바랍니다!


이 코드를 테스트 한 적이 있습니까? 50은 48이어야하고 55는 대문자 ASCII 문자에만 사용할 수 있으며 예제에는 소문자가 포함되어 있습니다.
Roland Illig

0

char 또는 short to int의 경우 값을 지정하면됩니다.

char ch = 16;
int in = ch;

int64와 동일

long long lo = ch;

모든 값은 16입니다.


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