모두의 코드 - 5. 문자 입력 받기

2024. 9. 24. 23:47Programming Language/C

5. 문자 입력 받기

문자 형식의 변수와 키보드로 부터 입력을 받는 입력에 대해 알아보자.

 

컴퓨터는 0과 1만 처리하는데 문자를 어떻게 처리할까.

문자를 숫자에 대응 시키는 것이다.

이걸 ASCII CODE라고 한다.

아스키 코드는 아래 표와 같다.

10진수 ASCII 10진수 ASCII 10진수 ASCII 10진수 ASCII
0 NULL 32 SP 64 @ 96 `
1 SOH 33 ! 65 A 97 a
2 STX 34 " 66 B 98 b
3 ETX 35 # 67 C 99 c
4 EOT 36 $ 68 D 100 d
5 ENQ 37 % 69 E 101 e
6 ACK 38 & 70 F 102 f
7 BEL 39 ' 71 G 103 g
8 BS 40 ( 72 H 104 h
9 HT 41 ) 73 I 105 i
10 LF 42 * 74 J 106 j
11 VT 43 + 75 K 107 k
12 FF 44 , 76 L 108 l
13 CR 45 - 77 M 109 m
14 SO 46 . 78 N 110 n
15 SI 47 / 79 O 111 o
16 DLE 48 0 80 P 112 p
17 DC1 49 1 81 Q 113 q
18 SC2 50 2 82 R 114 r
19 SC3 51 3 83 S 115 s
20 SC4 52 4 84 T 116 t
21 NAK 53 5 85 U 117 u
22 SYN 54 6 86 V 118 v
23 ETB 55 7 87 W 119 w
24 CAN 56 8 88 X 120 x
25 EM 57 9 89 Y 121 y
26 SUB 58 : 90 Z 122 z
27 ESC 59 ; 91 [[ 123 {
28 FS 60 < 92 \ 124 |
29 GS 61 = 93 } 125 }
30 RS 62 > 94 ^ 126 ~
31 US 63 ? 95 _ 127 DEL

아스키 코드는 8비트 데이터를 이용해서 여러 문자에 번호를 붙인 것이다.

 

위 표에 0 부터 127까지 밖에 없는 이유는 표준을 정할 당시에 7비트만으로 충분하다고 생각했기 때문이다.

근데 IBM에서 더 많은 종류의 문자가 필요하게 되어 1 비트를 추가해서 확장된 아스키 코드를 만들었다. 

그런데 그렇게 해도 부족하기 때문에 유니코드(Unicode)라는 새로운 형식의 문자 체계를 도입했다.

유니코드는 한 문자를 1에서 4바이트 까지 다양한 길이로 처리한다.

근데 우리는 아직 유니코드를 다룰 필요까지 없기에 신경 쓰지 않기로..!

 

scanf의 도입

만약 위 소스를 실행할 때 

이런 에러가 발생할 수 있는데 이건 visual studio 2013버전 이상 버전을  사용하고 있기 때문일 것이다.

 

더보기

해결 방법으로 scan_f나 _CRT_SECURE_NO_WARNINGS를 사용하라고 하기에 _CRT_SECURE_NO_WARNINGS를 사용해보자.

 

솔루션 탐색기에서 프로젝트명 우클릭 -> 속성 으로 들어가자.

 

구성속성 > C/C++ > 전처리기 선택

 

 전처리기 정의 부분의 맨 마지막에 ; _CRT_SECURE_NO_WARNINGS;를 넣어주면 된다.

적용 > 확인하고 다시 빌드해보자.

문제 없이 빌드한다.

 

근데 가장 좋은건 그냥 scanf_s를 사용하는 것이라고 한다.

직접 사이즈를 정해줘서 scanf의 취약점인 버퍼 오버플로우를 방지하는 방법이 좋다고 한다.

 

 

문제가 해결 되었다면 코드를 실행시켜보자.

입력을 요구하고 100이라는 숫자를 입력해보면

값을 받아 화씨로 변경된 값을 출력한다.

 

이제 소스를 한번 확인해보자.

이 소스에서 중요한 부분만 확인해볼텐데 

 

제일 먼저 

이 부분이다.

scanf는 키보드로부터 결과를 받아들이는 입력함수다.

흔히 printf와 scanf를 합쳐서 입출력함수라고 부른다.

 

scanf는 우리가 어떤 입력을 하기 전까지는 계속 기다리고 입력할 때 엔터를 눌러야지만 입력으로 처리해준다.

scanf와 printf는 비슷하게 변수의 타입마다 입력받는 포맷을 달리야해야한다.

 

위 처럼 double형의 변수를 입력받기 위해서는 %lf(소문자 LF)로 출력해야한다.

printf보다 까다로운 점은 %f로 float, double형을 모두 커버했던 것과는 다르게 float는 무조건 %f, double은 무조건 %lf로 입력받아야 한다.

동일하게 scanf의 경우는 모든 타입에 따라 포멧을 다르게 입력해줘야만 한다.

 

포멧 타입
%c char
%hd short
%d int
%ld long
%f float
%lf double

이렇게 타입별로 입력을 받아 출력해보자.

 

여기서 일단 제일 먼저 문자를 입력 받는 부분을 보자.

한글은 2바이트 이상을 처리하기에 최대 1바이트를 차지하는 char형 변수인 ch에 한글을 치면 오류가 나는데 이렇게 허용된 메모리 이상이 데이터를 넣는 오류를 버퍼 오버플로우(buffer Overflow)라고 하며 보안상 매우 취약하다.