C string 숫자 추출 - C string susja chuchul

개요

문자열에서 영어만 추출하기

문자열에서 한글만 추출하기 

isdigit

C string 숫자 추출 - C string susja chuchul
number

https://www.cplusplus.com/reference/cctype/isdigit/?kw=isdigit 

isdigit - C++ Reference

function isdigit Check if character is decimal digit Checks whether c is a decimal digit character. Decimal digits are any of: 0 1 2 3 4 5 6 7 8 9 For a detailed chart on what the different ctype functions return for each character of the standard

www.cplusplus.com

isdigit 함수는 입력된 parameter가 숫자인지 구분하는 함수이다.

다음과 같은 형식을 취한다.

int isdigit (int c);

이 때, parameter로 들어가는 건 ASCII 번호로, char로 변환했을 때, 숫자일 경우 1을 반환하고 아닌 경우 0을 반환한다.

C string 숫자 추출 - C string susja chuchul
ASCII Code

사실상 bool 함수에 parameter로 char 변수가 들어가는 셈.

직접 함수를 짜볼 수 있다. 매우 간단하다.

int my_isdigit(int ch)
{
	if (ch >= 48 && ch <= 57) // ASCII 코드에서 48 ~ 57은 0 ~ 9 를 나타낸다.
		return 1;	
	return 0;
}

숫자만 추출하기

반복문과 isdigit을 이용하면 문자열에서 숫자만 추출 해낼 수 있다.

#include <stdio.h>
#include <ctype.h>
int main ()
{
	char *str = "2021년 11월 06일";
	char buff[20] = {0,};
	int i = 0;
	
	while(*str)
	{
		if(isdigit(*str))
		{
			buff[i++] = *str;
		}
		str++;
	}
	printf("%s\n",buff);
}

/* 결과
20211106
*/

문자열 유형 분석 1 - 문자열에서 숫자(정수) 추출하기

저번 포인터 과제에 이어서 문자열 과제에서도 연속해서 등장한 문제로, 문자열에서 숫자를 빼내는 연습을 해보겠습니다.

문자열에서 숫자가 저장되는 방식은 각각의 정수가 하나의 원소로 자리를 가지게 됩니다. 따라서 그림처럼 25와 35를 입력하더라도 문자열에서는 2,5 3,5 각각이 독립적으로 존재하기때문에 정수 25,35를 얻어내기 위해서는 숫자로 분리해내는 알고리즘이 필요합니다.

C string 숫자 추출 - C string susja chuchul

문자열을 다룰때 이러한 작업이 자유자재로 동반되어야 문제를 잘 해결할수있기때문에 이번 포스트에서 다루어보겠습니다.

문제는 다음과 같습니다.

문자열을 입력받고 영문자는 영문자끼리 모아서 하나의 배열에 담고, 숫자는 문자열에 등장한 각 숫자들의 합을 구합니다.

입력 예시

baNaNa25aPPLE35

출력예시

baNaNaaPPLE

60

이 문제를 본격적으로 접근하기전에 간단하게 몇가지를 떠올려보겠습니다.

숫자를 어떻게 분리할 것인가?

1. 문자열을 이루는 원소들은 숫자이거나 숫자가 아니다. 따라서 숫자가 아닌 문자들을 따로 배열에 담는다

2. 숫자가 끝났다는 것을 알기위해서는 숫자->문자 순서로 원소가 존재해야한다

3. 따라서 숫자가 연속해서 나올때는 숫자를 계속해서 만들어주다가 문자가 등장하면 그 값은 완성된 숫자로 판단한다

풀이코드

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

#pragma warning(disable:4996)

#include <stdio.h>

#include <string.h>

int main() {

char str[101],alpha[101];

int alpha_idx = 0;

scanf("%s", str);

char* p;

int len = strlen(str),sum=0,num=0,is_number=0;

for (p = str; p < str + len; p++) {

if ('0' <= *&& *<= '9') {//정수라면

if (is_number == 1) {

num = num * 10;

num = num + *- 48;

}

else {

num = *- 48;

}

is_number = 1;

}

else {//문자라면

if (is_number == 1) {//정수->문자라면

sum = sum + num;

num = 0;

}

alpha[alpha_idx] = *p;

alpha_idx++;

is_number = 0;

}

}

if (is_number == 1) {

sum = sum + num;

num = 0;

}

alpha[alpha_idx] = NULL;

printf("%s\n", alpha);

printf("%d", sum);

return 0;

}

cs

풀이를 하기전에 고려했던 사항들을 바탕으로 간단하게 구현해보았습니다.

숫자들을 배열에 담고싶다면, sum 변수가 아닌 숫자배열을 만들어서 저장해주면 될 것입니다.

++심화하기

여기서 심화해서 문자열에 공백이 들어가는 경우가 있습니다.

입력예시가 baN aNa2 5aP PLE3 5

와 같이 주어지고 gets 함수를 이용해 공백을 포함한 문자열을 받는 경우입니다.

이럴때는 문제를 단순화시키는 것이 중요합니다. 문제풀이전에 공백을 먼저 제거해준뒤에 문제를 풀이해주면 됩니다.

//문자열의 공백을 지우기

C string 숫자 추출 - C string susja chuchul
문자열의 공백을 지우기

이런 것도 생각해보면 매우 단순한 코드이지만, 시작부터 복잡하게 생각해버리면 매우 난이도 높은 문제가 되기때문에 주의해야합니다.

자 이제 위에서 배운 문자열에서 숫자분리하기를 활용하는 예제를 풀어보겠습니다.

문제는 다음과 같습니다.

문자열 A와 B 두개를 입력 받고  다음의 표에 규칙에 맞추어 A를 B로 변환합니다

C string 숫자 추출 - C string susja chuchul
문자열 변환 조건

만약 A에서 B로 변환이 가능하다면 1을, B를 A로 변환가능하다면 2를, 양방향 변환이 가능하다면 3을 출력합니다.

temp배열을 만들어서, 초기화해주면서 N을 1부터 10까지 반복하며 변환이 되는지 테스트해주면 되는 간단한 문제입니다.

주의해야할 것은 숫자일 경우 해당 숫자 번째의 알파벳 대문자를 N번 반복해서 배열에 저장해야합니다. 이때 숫자를 분리하는 알고리즘이 쓰입니다. 위의 문제를 그대로 응용해서 문제를 풀이하면 어렵지않게 풀수 있을 것입니다.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

#pragma warning(disable:4996)

#include <stdio.h>

#include <string.h>

int change_array(char sentence[], char B[]);

void init(char p[]);

int main() {

char sentence[21];

char B[25];

gets(sentence);

gets(B);

int chg_AB = 0, chg_BA = 0;

chg_AB=change_array(sentence, B);

chg_BA= change_array(B, sentence);

if (chg_AB == 1 && chg_BA == 1printf("3");

else if (chg_BA == 1printf("2");

else if (chg_AB == 1printf("1");

else printf("0");

return 0;

}

int change_array(char sentence[], char B[]) {

int N, temp_idx = 0;

int is_number = 0, num = 0,pass=0;

char temp[25= { NULL };

for (N = 1; N <= 10; N++) {

if (pass >= 1break;

is_number = 0;

temp_idx = 0;

init(temp);

printf("B는 %s\n", B);

printf("sentence는 %s\n", sentence);

for (int i = 0; i < strlen(sentence); i++) {

if ('0' <= sentence[i] && sentence[i] <= '9') {//숫자일 경우

if (is_number == 1) {

num = num * 10;

num = num + sentence[i] - 48;

}

else {

num = sentence[i] - 48;

}

is_number = 1;

}

else {//문자일경우

if (is_number == 1) {

for (int i = 0; i < N&&temp_idx <= 20; i++) {

temp[temp_idx] = 'A' + num - 1;

temp_idx++;

}

}

if (sentence[i] >= 'A' && sentence[i] <= 'Z') {

temp[temp_idx] = sentence[i] + N;

temp_idx++;

}

else if (sentence[i] >= 'a' && sentence[i] <= 'z') {

temp[temp_idx] = sentence[i] - N;

temp_idx++;

}

else {

temp[temp_idx] = ' ';

temp_idx++;

}

is_number = 0;

}

}

if (is_number == 1) {

for (int i = 0; i < N&&temp_idx<=20; i++) {

temp[temp_idx] = 'A' + num - 1;

temp_idx++;

}

}

temp[temp_idx] = NULL;

if (strcmp(temp, B) == 0) pass++;

}

if (pass >= 1return 1;

else return 0;

}

void init(char p[]) {

char* a;

for (a = p; *a!=NULL; a++) {

*= '\0';

}

}

cs