<개인공부>/[C언어, C++]

[C언어/C++] atoi, atof, atol 함수 (char* to int)

BlockDMask 2019. 3. 14. 00:03
반응형

안녕하세요. BlockDMask 입니다.

오늘은 C, C++에서 문자열을 숫자(정수, 실수)로 변환하는 함수들에 대해서 알아보겠습니다.


(C/C++ 에서 string -> char* -> int 로 변경? [바로가기])

(C++에서 int -> string 으로 바로 바꾸는 것을 보고싶다면 [바로가기])

(C++ 에서 string -> int 의 변경?  [바로가기])


<목차>

1. 문자열을 숫자로 atoi, atof, atol 함수 이름의 기원

2. atoi, atof, atol 함수 원형

3. 문자를 숫자로 바꿔주는 atoi, atol, atof 예제

4. 만약 숫자가 아닌 문자를 숫자로 바꾸려 한다면?

5. atoi("문자열"), atoi("0")의 반환형이 같다면? 어떻게 구분을 할까?


1. atoi, atof, atol 함수 이름의 기원


atoi 함수를 살펴보면 a - to - i 이렇게 나눌 수 있습니다. a = char(ASCII), i = int 로 보면 char(ASCII) to integer 라는 이름으로 풀 수 있습니다.

즉. char 타입을 int 타입으로 변경한다. 이렇게 이해하시면 되겠습니다.


atoi = char to int = 문자열을 정수 타입으로

atof = char to double = 문자열을 실수 타입으로

atol = char to long int = 문자열을 long 정수 타입으로


중요한것은 여기서 char는 char[N], char* 로 표현이 되는 문자열을 말합니다.

개인적으로는 저는 char* to int 이 표현이 더 정확한 표현이라고 생각이 듭니다.


C++ 에서는 string 클래스에 의해서 문자열을 string으로 표현할 수 있는데, C언어에서는 string 클래스가 존재하지 않기 때문에 char 배열을 이용하여 문자열을 표현하기 때문입니다.


2. atoi, atof, atol 함수의 원형


헤더파일 : <stdlib.h> <cstdlib>


int atoi (const char* cStr);

double atof (const char* cStr);

long int atol (const char* cStr);


cStr이라고 적은 이유는 C스타일의 문자열이라는 것을 강조하기 위해서 변수명을 그렇게 지정했습니다.

만약에 C++의 string을 이용했다면 c_str() 함수를 이용해서 C스타일의 문자열로 변환해서 이용해야합니다.



3. atoi, atof, atol 함수사용법


> atoi 예제 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//#include<cstdlib>    //C++
//#include<cstdio>
#include<stdlib.h>
#include<stdio.h>
int main()
{
    int num = 0;
    char cStr[30= "2019";
    
    //문자열 타입으로 출력.
    printf("char* = %s\n", cStr);
    
    //char* -> int
    num = atoi(cStr);
 
    //숫자 타입으로 출력.
    printf("int   = %d\n", num);
 
    system("pause");
    return 0;
}
cs


> 출력 결과



4. 만약 숫자가 아닌 문자를 숫자로 바꾸려 한다면?


char 타입을 int로 바꾸려고 하는데, 항상 다 숫자가 들어있지는 않을것 입니다.

만약에 char[]에....

- 숫자가 아닌 문자들만 들어있다면?

- 숫자 + 문자가 들어있다면?

- 문자 + 숫자가 들어있다면?

어떤식으로 결과가 나올까요?

궁금하지 않나요??


예제코드 한번 보시죠.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<iostream>
#include<cstdlib>
using namespace std;
int main(void)
{    
    char str1[] = "BlockDMask";     //문자열만 있는 경우
    char str2[] = "2019";           //숫자만 있는 경우
    char str3[] = "2019BlockDMask"//숫자+문자
    char str4[] = "BlockDMask2019"//숫자+문자
 
    cout << "atoi(\"문자만\"); -"   << atoi(str1) << endl;
    cout << "atoi(\"숫자만\"); -"   << atoi(str2) << endl;
    cout << "atoi(\"숫자+문자\"); -" << atoi(str3) << endl;
    cout << "atoi(\"문자+숫자\"); -" << atoi(str4) << endl;
    return 0;
}
cs


▶결과


결론.

1. atoi("문자") : 문자가 맨처음 나왔기 때문에 0을 반환합니다.

2. atoi("숫자") : 숫자를 반환합니다.

3. atoi("숫자+문자") : 문자가 나오기 전까지의 숫자를 반환합니다.

4. atoi("문자+숫자") : 문자가 바로 나오기 때문에 0을 반환합니다.


atoi() 함수의 원리는 매개변수로 들어온 문자열을 앞에서 부터 읽어서, "공백" or "숫자가아닌문자" 가 올때까지 숫자로 변환을 해주는 원리 입니다.

그렇기 때문에 "2019BlockDMask" 가 들어오면 앞에서부터 2,0,1,9 읽다가 "B"가 오니까 2019까지 반환하게 되는것입니다.


또한 atoi 함수가 표현할수 있는 수의 MAX와 MIN이 정해져 있으므로 오버플로우와 언더플로우를 조심해야합니다.

ex) atoi("999999999999999999999") //오버플로

ex) atoi("-99999999999999999999") //언더플로


5. atoi("문자") vs atoi("0") 의 구분에 대해서


그렇다면. atoi("문자")의 반환이 0이라면???

atoi("0")과 결과값이 똑같네요?

그럼 숫자 0이 반환 된 건지, 문자가 나와서 0이 반환 된 건지 알 수 없게됩니다.

이런경우는 어떤식으로 구분을 해야할까요?


atoi("0") 함수의 반환값은 0 이 나옵니다. 숫자 "0"이니까요.

atoi("BlockDMask") 함수의 반환값은 0이 나옵니다. 문자열이 숫자가 아닌 "문자"이기 때문이죠.


저같은 경우에는 비효율적이지만 이런경우 isdigit()을 이용해서 판단합니다.

같은 결과를 가지고 온다면, 문자열의 길이가 1이고

맨앞의 문자가 isdigit('0') 으로 true라면 숫자 0인거고, isdigit('B')이 false라면 문자열로만 이루어진 문자로 판단을 내립니다.


다른분들은 어떤식으로 판단을 하시나요? 조금 생각이 필요한 부분인것 같습니다.

감사합니다.

반응형