[C]atoi & itoa
- atoi함수는 문자형정수를 int형정수로 바꿔주는 함수입니다.
- itoa함수는 int형정수를 원하는 진수(radix)로 문자형정수로 바꿔주는 함수입니다.
1️⃣ 함수원형
< atoi >
int atoi(const char *str)
< itoa >
char *itoa(int value, char *buffer, int radix)
2️⃣ 헤더파일, 반환값
- 반환값:
- atoi : int형 정수(10진수) or 0(숫자문자를 한개도 못읽었을 경우)
- itoa : 문자열(2진수 ~ 40진수)
- 헤더파일: <stdlib.h>
3️⃣ 함수구현
< atoi >
int atoi(const char *str)
{
int cnt;
int minus;
int result;
cnt = 0;
minus = 1;
result = 0;
while (str[cnt] == ' ' || (str[cnt] >= '\t' && str[cnt] <= '\r'))
cnt++;
if (str[cnt] == '-' || str[cnt] == '+')
{
if (str[cnt] == '-')
minus *= -1;
cnt++;
}
while (str[cnt] >= '0' && str[cnt] <= '9')
{
result = (result * 10) + (str[cnt] - '0');
cnt++;
}
return (result * minus);
}
< itoa >
char *itoa(int value, char *buffer, int radix)
{
int cnt;
unsigned int no_decimal, result_value;
cnt = 0;
if (value == 0) // value가 0일때
{
buffer[0] = '0';
buffer[1] = '\0';
return (buffer);
}
else if (value < 0) // value가 음수일때
{
if (radix == 10) // 10진수일때(음수)
{
buffer[0] = '-';
value *= -1;
cnt++;
result_value = value;
while (value >= radix)
{
value /= radix;
cnt++;
}
}
else // 10진수가 아닐때(음수)
{
no_decimal = UINT_MAX + value + 1;
result_value = no_decimal;
while (no_decimal >= radix)
{
no_decimal /= radix;
cnt++;
}
}
}
else // value가 양수일때
{
result_value = value;
while (value >= radix)
{
value /= radix;
cnt++;
}
}
buffer[cnt + 1] = '\0';
while (result_value > 0)
{
if (result_value % radix <= 9)
buffer[cnt] = result_value % radix + '0';
else // 11진수 이상일때만 해당('a' ~ '~')
buffer[cnt] = result_value % radix + 'a' - 10;
result_value /= radix;
cnt--;
}
return (buffer);
}
4️⃣ 특징 & 주의사항
< atoi >
- int형의 최대값(2,147,483,647)보다 큰 값을 넣으면 원하지않는 값이 표시됩니다.
- int형의 최소값(-2,147,483,648)보다 작은 값을 넣으면 원하지않는 값이 표시됩니다.
- 중간에 숫자가 아닌 문자형이 들어오면 그 문자앞의 숫자만 변환되어 표시됩니다.
- 숫자문자를 한개도 못읽었을 경우(숫자가아닌 문자가 먼저있는 경우 포함) 0을 반환합니다.
< itoa >
- 리눅스에는 구현되있지 않은 함수이며 윈도우에서는 <stdlib.h>헤더파일에 선언되어 있습니다.
- 음수일경우 10진수만 (signed int형)’-‘를 표시해주며 나머지는 (unsigned int형)의 음수표시법으로 적용되었습니다.
- 한자리 최대 표시값이 ‘z’ 인 36진수까지가 아닌 ‘~’(ascci:126)인 40진수까지 유효한 값이 표시되었습니다.
(2진수 ~ 40진수 범위내에서만 사용하는 것이 좋을 것 같습니다.) - 진수의 종류를 잘 고려해서 buffer의 크기를 잘 잡아야 합니다. (2진수는 최대 ‘36’[sizeof(char)]의 크기가 필요)
5️⃣ 코드예시(특이케이스)
1. < itoa에서 36진수보다 높은 진수를 사용할 경우 >
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char buffer[33];
printf("40진수 최대표시값: %s\n", itoa(39, buffer, 40));
printf("39진수 최대표시값: %s\n", itoa(38, buffer, 39));
printf("38진수 최대표시값: %s\n", itoa(37, buffer, 38));
printf("37진수 최대표시값: %s\n", itoa(36, buffer, 37));
printf("36진수 최대표시값: %s\n", itoa(35, buffer, 36));
}
/*---출력---*/
40진수 최대표시값: ~
39진수 최대표시값: }
38진수 최대표시값: |
37진수 최대표시값: {
36진수 최대표시값: z
- 이처럼 itoa함수는 알파벳 ‘z’(ascci: 122)보다 큰 ‘~’(ascci: 126)까지 표시가 가능합니다.
- 눈에보이는 값을 사용하기 위해서는 2 ~ 40진수에서만 사용하는 것이 좋을 것 같습니다.