특정 입력받은 문자열을 정수형으로 변환하는 방법을 알아보도록 하겠습니다.
포스팅을 읽기 전에 이전에 포스팅했던 atoi에 대해 아직 보지 못하신 분은 한번 참고해 주시길 바라겠습니다.
https://hig0617.tistory.com/100
만약에 문자열에 공백들이 있으면 이를 제거해 주어야 합니다.
부호가 여러개가 있으면 '-'가 홀수이면 음수로 짝수이면 양수로 부호를 정해 주어야 합니다.
저희는 위의 역할을 해주는 함수를 OdOp_sign이라 정하겠습니다.
OdOp_sign
char* OdOp_sign(int* sign, char* str)
{
while (*str == 32 || (*str >= 9 && *str <= 13))
{
str++;
}
while (1)
{
if (*str == '-')
*sign *= -1;
else if (*str != '+')
break;
str++;
}
return (str);
}
이부분의 자세한 설명은 이전 포스팅(https://hig0617.tistory.com/100) 잘 나와있습니다.
다음으로 바꿀 진법의 인자의 형태가 적절한 형태인지와 몇 진법인지 파악해야 합니다.
이게 무슨 말인지 아래에서 하나하나 설명해 드리겠습니다.
저희는 위의 역할을 해주는 함수를 OdOp_base이라 정하겠습니다.
OdOp_base
int OdOp_base(char *base)
{
int n;
int i;
n = 0;
while (base[n] != '\0')
{
i = 0;
if (base[n] == '+' || base[n] == '-')
return (0);
else if (base[n] == 32 || (base[n] >= 9 && base[n] <= 13))
return (0);
while (base[i] != '\0')
{
if (base[i] == base[n] && i != n)
return (0);
i++;
}
n++;
}
return (n);
}
진법 인자인 base 문자열에 부호가 있으면 부호를 표시할 수 없기 때문에 0을 리턴하게 했습니다.
공백이 포함되어 있으면 tab과 구분을 할 수 없을 수 있기 때문에 역시 0을 리턴하게 했습니다.
마지막으로 같은 것이 반복이 되면 0을 리턴하게 했습니다.
모든 부분을 만족한다면 문자열의 길이를 리턴하여 몇 진법인지 파악하게 했습니다.
다음으로 진법의 형태를 파악했으니 정수형으로 바꾸도록 하겠습니다.
OdOp_answer
int OdOp_answer(int n, char *str, char *base)
{
int i;
int answer;
answer = 0;
while (*str != '\0')
{
i = 0;
while (*str != base[i] && base[i] != '\0')
{
i++;
}
if (base[i] != '\0')
{
answer *= n;
answer += i;
}
else
break ;
str++;
}
return (answer);
}
str에 저장된 문자가 base에 저장이 되어있다면 정수형으로 계산해 줍니다.
str문자가 끝나거나 더이상 base에 저장이 되어있지 않다면 현재까지 변환한 정수를 리턴해 줍니다.
이제 위의 함수를 합쳐봅시다.
OdOp_atoi_base
int OdOp_atoi_base(char *str, char *base)
{
int answer;
int sign;
int n;
sign = 1;
str = OdOp_sign(&sign, str);
n = OdOp_base(base);
if (n < 2)
{
return (0);
}
answer = OdOp_answer(n, str, base);
return (answer * sign);
}
여기서 특이한 부분은 n이 2미만일 경우에는 0을 리턴하게 했습니다.
진법이 1이거나 0이면 가능하지 않기 때문에 정수를 리턴할 수 없습니다.
예시를 한번 살펴보겠습니다.
#include <stdio.h>
char* OdOp_sign(int* sign, char* str)
{
while (*str == 32 || (*str >= 9 && *str <= 13))
{
str++;
}
while (1)
{
if (*str == '-')
*sign *= -1;
else if (*str != '+')
break;
str++;
}
return (str);
}
int OdOp_base(char *base)
{
int n;
int i;
n = 0;
while (base[n] != '\0')
{
i = 0;
if (base[n] == '+' || base[n] == '-')
return (0);
else if (base[n] == 32 || (base[n] >= 9 && base[n] <= 13))
return (0);
while (base[i] != '\0')
{
if (base[i] == base[n] && i != n)
return (0);
i++;
}
n++;
}
return (n);
}
int OdOp_answer(int n, char *str, char *base)
{
int i;
int answer;
answer = 0;
while (*str != '\0')
{
i = 0;
while (*str != base[i] && base[i] != '\0')
{
i++;
}
if (base[i] != '\0')
{
answer *= n;
answer += i;
}
else
break ;
str++;
}
return (answer);
}
int OdOp_atoi_base(char *str, char *base)
{
int answer;
int sign;
int n;
sign = 1;
str = OdOp_sign(&sign, str);
n = OdOp_base(base);
if (n < 2)
{
return (0);
}
answer = OdOp_answer(n, str, base);
return (answer * sign);
}
int main(void)
{
char test7[] = " -+-+---235Hsa";
char *base1 = "0123456789ABCDEF";
printf("str : ' -+-+---235Hsa' | base : 0123456789ABCDEF\n");
printf("answer : -565 | your result : %d\n", OdOp_atoi_base(test7, base1));
return (0);
}
'Algorithm > Algorithm' 카테고리의 다른 글
C언어, 피보나치 수열 (0) | 2023.12.09 |
---|---|
putnbr_base, 숫자를 진법으로 변환하기 (1) | 2023.12.07 |
문자열 소문자로 변환하기 (0) | 2023.10.23 |
문자열 대문자로 변환하기 (0) | 2023.10.22 |
겹치지 않는 N자리 수를 오름차순으로 출력하기 (0) | 2023.10.18 |