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, unsigned및 char)을 모두 처리하는 것이 처음 나타나는 것보다 더 섬세합니다. 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.