본문 바로가기
C언어

야메 C언어 강좌: 5. 문자의 비밀과 출력(ASCII, 아스키코드)

by 케찹이 2020. 4. 26.

저번 시간에 굉장히 다양한 변수들과 그 변수들을 사칙연산을 통한 활용에 관하여 배워보았다. 그리고 오늘은 잠깐 문자와 관해서 조금 만 더 설명을 진행하고 출력에 관해서 얘기해보려고 한다.

 

문자 변수는 char이다. 저번 강의를 살펴보았다면 char는 모든 변수중에서 가장 작은 범위의 수를 담을 수 있는 변수이다. 그 이유는 기본적으로 영어문자들을 모두 담을 수 있게 하기 위함이라고 설명을 하였다. 

그럼 char 변수에 문자를 넣어보는 코드를 보이겠다. 

 

#include<stdio.h>

int main(){
	char a = 'a';
	
	printf("a를 %%d로 출력한다면? : %d\n",a);
	printf("a를 %%c로 출력한다면? : %c\n",a);
	return 0;
}

일단 char에 문자를 저장하는 방식은 ''안에 문자를 써 저장한다. 근데 printf를 두가지 방식으로 출력을 해보았다. 이 코드의 결과는 밑과 같이 나온다. 

우리가 원하는 값은 두번째  줄에 출력이 되었고 첫번째 줄에는 우리가 저장한 문자 'a'가 아닌 숫자 97이 나왔다. 이게 어찌된 일일까?

 

%d는 우리가 앞서 말했듯이 int변수의 값을 출력할 때 printf에서 사용한 표현이다. 근데 그것을 char에 사용했다면 단순히 우리가 잘못을 한것인가? 그것은 아니다. 그 이유는 바로 모든 문자는 사실 숫자로 이루어져있다는 사실 때문이다. 

위 표는 아스키코드(ASCII)라는 표이다. 참고로 ASCII는 American Standard Code information for interchange의 간체이다. 위 표을 살펴보면 DEC HX Oct Char라고 써져 있는데 우리가 살펴볼건 Dec와 Char줄의 내용이다. 모든 문자는 해당되는 숫자가 있다는 것을 보여준다. 그리고 영어,특수문자 심지어 '숫자'인 문자들도 포함되어 있다. char는 문자를 저장하는 변수이지만 동시에 숫자를 저장할 수 있는 변수라고도 생각해주면 되겠다. 그럼 우리가 저장한 소문자 a를 찾아보자, 빨간색이 문자이다. a를 찾았다면 그 옆에 DEC엔 97이라고 써져있는 것을 확인 할 수있다. 97은 딱 우리가 컴파일 된 그 결과와 같은 숫자이다. 

그럼 한글과 한자 같은 문자는 어떻게 저장하냐 라는 질문이 있을 수도 있다. 안타깝지만 아스키코드에선 그 뜻에 살펴볼 수 있듯이 영어에 초점이 맞춰져있는 정의이다. 그래서 현재 다른 나라의 언어 문자들은 유니코드라는 체계에서 활용할 수 있다. 그 이상의 내용은 굳이 언급하지 않겠다. 딱히 우리의 다른 강의에 영향이 없기 때문이다. 이것에 관심있는 분들은 직접 찾아보도록 하자. 

 

 

 

 

우리가 두번째 강의 때 출력을 배웠다. 출력이 있다면 입력도 있다는게 인지상정이다! 그럼 이제 입력에 관해서 배워보도록 하자. 입력은 무엇을 하는 기능인가? 바로 우리가 코드를 짜면서 데이터를 입력하는게 아니라 컴파일 완료후 프로그램을 실행할 때 사용자가 원하는 데이터를 집어넣을 수 있는 기능을 입력이라고 한다. 

입력의 기본 함수는 scanf이며 사용방법을 살펴보자.

 

#include<stdio.h>

int main(){
	char a;
	int b;
	short c
	double d;
	float e;
	long f;
	
	scanf("%c",&a);
	scanf("%d",&b);
	scanf("%hd",&c);
	scanf("%lf",&d);
	scanf("%f",&e);
	scanf("%ld",&lo);
	
	printf("a를 출력 : %c\n",a);
	printf("b를 출력 : %d\n",a);
	printf("c를 출력 : %d\n",a);
	printf("d를 출력 : %f\n",a);
	printf("e를 출력 : %f\n",a);
	printf("f를 출력 : %ld\n",a);
	
	return 0;
}

scanf를 쓰고 괄호안에 printf에서 사용하던 %형식을 쓰고 ""밖에서 &변수명 을 작성하면 해당 함수가 작동합니다. printf처럼 간단하지만 나중에 알게될 사실이지만 printf만큼 다루기 쉬운 함수는 아니다. 그 이유는 printf와 다른점인 &에 있다. &는 주소를 뜻한다. 갑자기 이에 대해서 설명을 하자면 이해하기도 힘들고 하니 나중에 얘기를 하도록 하겠다. 

 

여기서 최신 비주얼 스튜디오를 사용하고 계시는 분들은 scanf가 아닌 scanf_s를 사용하여야 오류가 없이 컴파일러가 작동할 것이다. 비주얼 스튜디오가 scanf가 아닌 scanf_s를 사용하게 된 계기가 바로 scanf의 까다로운 관리 문제이다. scanf를 잘못 사용할 경우 아주 쉽게 코드가 위험에 처할 수 있다. 위험에 처한다는 것은 바로 해커의 공격에 치명적일 수 있다 라는 것을 뜻한다. 그리고 이것을 정확한 개념으로 얘기하자면 Buffer Overflow가 일어날 수 있다. 쉽게 얘기해보자면 

scanf("%c",&sentence);

위 처럼 문자형인 변수를 입력하는 코드가 있다. 근데 알고보니 sentence라는 변수는 int형 변수인것이다. 컴파일러에 따라 다르지만 어떤 컴파일러는 오류라고 얘기해줄 수도 있지만 어떤 컴파일러는 오류라는 얘기 없이 컴파일이 진행된다. 만약에 사용자가 char의 최대 범위인 257이상의 숫자를 입력했다면 굉장히 기괴한 값들이 저장되게 된다. 주로 이런 값은 쓰레기 값이라고도 한다. 그리고 이러한 점은 코드의 약점이 될 수 있다는 것이다. 그러니 한동안 여러분들이 scanf를 사용할 때에는 제가 사용한데로 사용을 해야 좋은 코드를 작성할 수 있을 것이다. 

 

여기까지 배워온 여러분들은 오늘 강의를 통해서 더 많은 코드를 만드실 수 있을 것입니다. 제가 작성한 개념으로 자신만의 코드들을 작성해보도록 해보세요!

댓글