본문 바로가기
강의/나 혼자 C언어 : 기초

만들면서 배우는 나 혼자 C언어 : 02. 입출력 함수, 자료형과 변수

by dongglessam 2022. 10. 28.
728x90
반응형
728x170

안녕하세요. 동글쌤 입니다.

지난 강의에서 기본 구조에 대해 배웠으니 이제 우리가 실제로 만들 프로그램을 보면서 C언어의 주요 기능에 대해 배워보도록 하겠습니다.

이전 글 : 2022.10.26 - [강의/나 혼자 C언어 : 기초] - 만들면서 배우는 나 혼자 C언어 : 01. 기본 구조

 

만들면서 배우는 나 혼자 C언어 : 01. 기본 구조

안녕하세요. 동글쌤 입니다. 프로그램 설치 후 C언어와 관련하여 처음 배울 것은 기본 구조 입니다. C언어와 관련된 많은 블로거들이 Hello World부터 찍는 입출력 함수부터 시작하는 경우가 많은데

choisdevil.tistory.com

 

 

우리가 만들 프로그램은?

 

나는야 프로그램!

흔히 프로그램을 만든다고 하면 되게 어렵게 생각하는데, 사실은 여러분이 만들 수 있는 작은 프로그램도 하나의 프로그램입니다. 하다못해 Hello World!를 출력하는 것도 프로그램이니까요.

저는 이 강의를 통해 여러분들이 기초 과정에서 간단한 텍스트 형태의 게임을 만들 수 있도록 진행하려 합니다.

 

출처 : 구글 검색 '텍스트 게임'

텍스트 게임은 GUI(그래픽 사용자 인터페이스)가 등장하기 전 하이텔, 천리안 등 모뎀 통신 시절에 많이 사용했던 형태로 그 당시 기술로는 그래픽으로 구현하기 힘든 부분들을 텍스트로 구현했던 게임이라고 생각하면 됩니다. 예를 들면 공격 형태, 이펙트, 잔여 HP/MP, 전투 결과, 인터페이스 등등이 몽땅 텍스트인 것이지요.

 

출처 : '던파 모바일, PC 버전으로 해봤습니다', 인벤, https://www.inven.co.kr/webzine/news/?news=269820&site=mdnf

이것을 있는 그대로 텍스트로 보여주느냐, 예쁘게 잘 꾸며서 그래픽 요소로 보여주느냐 하는 것의 차이일 뿐이지 결국 우리가 그래픽적인 요소로 보게 되는 모든 것들이 사실은 숫자 놀음이라는 것입니다.

 

우리는 게임을 만들기 앞서 게임에 접속하면 가장 먼저 볼 수 있는 회원가입과 로그인 화면을 만들어 볼 것입니다. 

'이걸 내가 어떻게 만들어?' 라고 겁먹으실 필요 없습니다. 시중에 나와있는 책을 보면서 1장부터 따라하다가는 반도 못하고 접는 학생들이 대부분이었거든요. 차라리 어떤 것을 만들어보게 하면서 그것에 필요한 것들을 찾아가면서 공부하는게 여러분들이 목표를 가지고 무언가 만들 수 있다는 자신감과 성취감을 주게 될 것입니다. 결국 C언어를 조금 더 오래 보고, 만들어볼 수 있는 동기를 가지게 될 수 있죠.

 

 

01. 화면 설계

 

무턱대고 만드는 것 보다는 어떻게 만들 것인지 화면을 먼저 구상하고, 그에 따라 필요한 요소들을 출력하도록 하는 것이 중요합니다. 로그인을 생각해볼까요? 일반적인 형태의 로그인 화면은 아래와 같이 구성되어 있습니다.

 

출처 : 네이버 로그인 화면

사용자는 각자 가지고있는 고유한 정보인 아이디와 비밀번호를 입력하고 로그인 버튼을 누릅니다. 그럼 사용자 정보가 저장된 서버에 입력한 아이디가 있는지, 비밀번호는 맞는지 확인해서 하나라도 틀리면 로그인이 실패하게 되고, 둘다 맞다면 로그인이 성공하게 됩니다.

이 과정을 C언어에서도 똑같이 구현하게 됩니다. 다만 우리는 현재 서버를 사용하지 않을 것이기 때문에 사용자 정보를 별도로 값을 저장하고, 저장된 값과 입력한 값을 비교하는 과정으로 대신하게 됩니다.

 

C언어로 구현해야 할 로그인 화면의 모습

따라서 우리가 사용자에게 입력받을 값은 아이디, 비밀번호가 될 것이고 기존에 저장되어있는 값과 일치하면 로그인이 성공하는 과정으로 보여주면 됩니다. 만약 일치하지 않는다면? 로그인이 실패했다고 보여주기만 하면 됩니다.

 

 

02. printf() 함수 : 화면 출력

 

자, 그럼 이제 위와 같은 로그인 화면을 출력해보려 합니다. 우선 입력받는 부분과 출력하는 부분을 구분해야 하는데 아래와 같이 입출력 부분을 구분할 수 있습니다.

 

1. 출력 : 로그인, ID, PW, 로그인 성공 등과 같이 프로그램이 실행됨에 따라 문자를 출력해주는 부분이 있습니다.

2. 입력1 : ID를 입력받는 부분이 있습니다. (ex. admin)

3. 입력2 : PW를 입력받는 부분이 있습니다. (ex. admin)

세 가지 부분으로 입출력을 나누었으니 우선은 입력받는 부분을 제외하고 화면에 출력을 먼저 해보겠습니다. 가장 먼저 할 일은 기본 구조 코드를 입력하는 것입니다.

당분간은 쓰고 시작해야 합니다.

화면에 내가 원하는 문자를 출력하기 위해서는 printf() 라는 함수를 씁니다. (참고 : https://ko.wikipedia.org/wiki/Printf), printf는 print, 즉 출력을 해주는 기능을 하는 함수인데 뒤에 f가 붙었습니다. f는 format string(형식 문자열)의 약자로 이해하시면 되는데, 나중에 나오겠지만 printf를 통해 문자, 문자열, 정수, 실수, 10진수, 8진수 등등... 다양한 형태의 문자열을 printf 함수를 통해 출력할 수 있습니다. 이처럼 다양한 형식(format)을 출력(print)하는 함수라는 뜻으로 printf 함수라고 합니다. 

그럼 printf() 함수를 사용하여 문자열(문자가 여러개 모여있는 집합)을 출력해보도록 하겠습니다. 문자열을 출력하고자 할 때는 printf() 함수의 소괄호 안에 원하는 문자 혹은 문자열을 " "(쌍따옴표)로 묶어서 입력해주면 됩니다.

#include <stdio.h>

int main() {
    printf(">> 로그인 <<");
    
    printf("ID : ");
    printf("PW : ");
	
    return 0;
}

좀 있어 보이나요? 아래 '로그인 성공' 부분은 사용자가 입력한 결과에 따라 출력되는 내용이 다르기 때문에 우선은 생략하도록 하겠습니다. 자 그럼 실행을 해 볼까요?

 

싸늘하다. 뭔가 이상하다.

어라? 분명히 본 대로 썼는데 실제로 출력된 결과는 한 줄에 모두 출력되고 말았습니다. 

문자열을 출력할 때는 여러 특수기호들이 있는데, 엔터키의 역할을 하는 특수기호는 개행문자인 '\n' 입니다. 역슬래시(\) 기호는 키보드의 엔터키 위에 있는 []키를 누르면 됩니다. 아래와 같이 문자열의 끝 부분에 모두 개행문자를 써 주시면 문자열이 출력된 후 '\n' 하나당 엔터키 한 번이 실행됩니다. 

#include <stdio.h>

int main() {
    printf(">> 로그인 <<\n\n");	//엔터키 두 번
    
    printf("ID : \n");		//엔터키 한 번
    printf("PW : \n");		//엔터키 한 번
	
    return 0;
}

그럼 개행문자를 추가한 코드로 다시 실행해보도록 하겠습니다.

 

개행문자 \n을 삽입한 결과 화면

printf() 3개와 개행문자 '\n' 만으로 뭔가 있어보이는 화면이 출력되었습니다. Hello World! 보다는 훨씬 좋네요. 하지만 뭔가 허전한데, ID와 PW를 입력하고 싶지만 아직은 그럴 수가 없습니다. 다음 과정을 통해 사용자가 직접 ID와 PW를 입력할 수 있도록 해주는 입력 함수에 대해 알아보도록 하겠습니다.

 

728x90

 

 

03. scanf() 함수 : 값의 입력

 

저는 사용자 ID로 admin도 입력하고 싶고, korea도 입력하고 싶어요! 하지만 지금은 입력받을 수가 없네요. 왜냐면 입력 함수를 사용하지 않았기 때문이죠.

키보드로 어떤 값을 입력받기 위해서는 scanf() 라는 함수를 사용합니다. f는 아까 printf의 f와 동일하게 format string(형식 문자열)의 약자로, 사용자가 키보드로 입력하는 값이 문자일 수도 있고, 문자열일 수도, 정수일 수도, 혹은 실수일 수도 있습니다. 이처럼 다양한 형식(format)을 입력(scan)받는 함수라는 뜻으로 scanf 함수라고 합니다. 

우리가 입력한 값이 정수인지, 실수인지, 문자열인지 컴퓨터가 알아서 해석하면 좋겠습니다만 컴퓨터는 진짜 바보같은 아이라서 우리가 입력하고자 하는 값의 형식(format)이 어떤 형태인지 지정해주어야 합니다. 쉽게 말해서 컴퓨터한테 내가 입력하려는 값이 10진수이면 10진수라고, 문자열이면 문자열이라고 얘기해줘야 합니다. 이 형식을 구분해주기 위해 '% 기호를 사용하여 어떤 형식의 문자가 들어올 것이다' 라고 scanf 함수 안에 써주어야 합니다.

형식문자 자료형 설명
%c int(char) 아스키 문자 1개로 출력
%d int 부호가 있는 10진수 정수로 출력
%o unsigned int 부호가 없는 8진수 정수로 출력
%u unsigned int 부호가 없는 10진수 정수로 출력
%x unsigned int 부호가 없는 16진수 정수(소문자)로 출력
%X unsigned int 부호가 없는 16진수 정수(대문자)로 출력
%e float, double 지수형 실수로 출력
%f float, double 부호가 있는 10진수 실수로 출력
%lf float, double 부호가 있는 10진수 실수로 출력
%p pointer 16진수 실수로 출력
%s string 문자열 출력

입, 출력에서 사용할 수 있는 형식 문자는 여러 가지가 있지만 지금은 %s 라는 것만 사용할 것입니다. ID와 PW가 영문으로만 되어있을 수도 있고, 영문+숫자, 영문+특수문자, 영문+숫자+특수문자 등 여러가지 조합으로 사용될 수도 있기 때문이죠. 그래서 여러 문자들을 모아놓은 합인 문자열 형식으로 입력을 받을 것입니다.

prinf() 함수와 마찬가지로 scanf() 함수 또한 소괄호 안에 " "(쌍따옴표)를 묶어 입력하고자 하는 형태를 알려주면 됩니다.

#include <stdio.h>

int main() {
    printf(">> 로그인 <<\n\n");	//엔터키 두 번
    
    printf("ID : ");		//개행문자 지움
    scanf("%s");	// ID 입력받음
    printf("PW : ");		//개행문자 지움
    scanf("%s");	// PW 입력받음
	
    return 0;
}

ID와 PW 옆에는 키보드로 문자열을 입력받아야 하기 때문에 개행문자를 지웠습니다. 자, 그럼 실행을 해 볼까요?

 

우리가 키보드로 문자열을 입력하고 엔터를 치면 입력을 받는 것을 확인할 수 있습니다. 정확하게는 현재 상태로는 키보드로 입력받은 값을 화면에 그대로 보여주는 것일 뿐입니다. 우리가 해야 할 일은 이제 입력한 저 값을 컴퓨터가 아이디와 비밀번호로 사용할 수 있도록 어떤 공간에 담아주어야 합니다.

* 통상적으로는 패스워드 입력 시 특수문자(*)를 사용하여 보이지 않도록 처리하지만 현재는 그 과정을 생략합니다.

 

 

반응형

 

 

04. 자료형과 변수 : 값을 저장하는 공간

 

입력한 값이 저장되지 않아 두 개가 같은지 비교가 불가능하다.

사용자가 입력한 아이디와 비밀번호를 저장하지 않으면 어떤 일이 발생할까요? 컴퓨터는 사용자가 입력한 아이디와 패스워드를 기존에 가지고있던 아이디, 패스와드와 비교해야 합니다. 하지만 키보드로 입력만 받았지 값을 담아놓지 않았기 때문에 두 개가 같은지, 다른지 비교를 할 수 없게 됩니다. 따라서 우리는 입력받은 아이디와 패스워드를 저장할 공간이 필요합니다.

값을 저장하기 위해선 어떤 공간이 필요한데, 이를 변수라고 합니다. 변수는 프로그램이 시작하면서 값을 저장한 채로 시작할 수도 있고, 사용자가 scanf() 함수나 변수 값 변경을 통해 값을 저장할 수도 있습니다. 이렇게 공간이 있어야 여러분이 어떤 값을 가지고 놀고 싶을 때 저장해서 편하게 사용할 수 있습니다.

 

변수를 만들 때 주의해야 할 것은, 변수에 저장하는 값의 형태를 컴퓨터에게 미리 알려줘야 한다는 점이죠. "지금 저장할 값은 정수 형태의 숫자야!", "지금 저장할 값은 문자열이야!" 등등. 이것을 자료의 형태, 즉 자료형이라고 합니다. 같은 2라도 문자 2와 정수 2는 서로 다른 값으로 인식하기 때문이죠.

따라서 변수를 만들면서 어떤 값(자료)의 형태를 저장할 수 있을지 함께 지정해주어야 합니다. 만약 정수만 저장할 수 있는 변수에 문자열이나 실수를 저장하려 한다면 값이 제대로 저장되지 않거나 오류가 날 수 있습니다.

 

자료형 크기 범위 용도
char 1 바이트 -128 ~ 127 문자 저장
실제 값은 정수로 저장
(ASCII 코드 사용)
int 4 바이트 -32,768 ~ 32,767 10진수 정수 저장
float 4 바이트 1.175494e-38
~ 3.402823e+38
7자리 실수 저장
double 8 바이트 2.225074e-308
~ 1.797693e+308
16자리 실수 저장

자료형에는 여러가지가 있고, unsigned가 앞에 붙으면 부호가 없는 형태로 바뀌며, 앞에 long이 붙으면 값을 저장할 수 있는 범위가 달라집니다. 하지만 지금은 필요한 변수만 먼저 배우고, 나중에 자료형에 대해 다시 언급하도록 하겠습니다. 

참고(코딩도장) : 정수 자료형의 크기 및 범위, 실수 자료형의 크기 및 범위

 

램(RAM)의 특정 공간에 변수가 생성되고, 그 안에 값이 저장된다.

그럼 이 변수는 어디에 저장되는 것일까요? 흔히 컴퓨터에서 램(RAM)이라고 부르는 주기억장치의 수많은 공간 중에서 한 곳(주소)에 변수가 만들어지고, 그곳에 값이 저장되게 됩니다. 램은 공간이 엄청 많기 때문에 변수를 만들고 값을 저장한 후에는 이 값을 찾을 수 있도록 ID, LV, HP, GOLD 등 값이 저장된 곳(주소)의 이름(변수명)을 지어주어야 합니다. 그래야 컴퓨터가 램(RAM)에서 변수 이름을 가지고 값이 저장된 곳(주소)으로 찾아갈 수 있기 때문이죠.

 

프로그램의 시작부터 종료까지 어떤 변수는 값이 변하지 않을 수도 있고, 어떤 변수는 값이 계속 바뀔 수도 있다.

변수의 가장 큰 특징은 값이 변할 수도, 변하지 않을 수도 있다는 것입니다. 예를 들어 우리가 회원가입할 때 한번 입력한 ID는 프로그램이 종료될 때까지 바뀌지 않을 것입니다. ID는 각 회원 정보를 구별할 수 있는 유일한 값이기 때문이죠. 하지만 생성한 캐릭터의 레벨(LV), 체력(HP), 골드(GOLD) 등의 값은 캐릭터가 레벨업을 함에 따라, 아이템을 사고 파는 과정에 따라 값이 변하게 됩니다. 

 

그럼 이번엔 아이디와 패스워드를 저장할 수 있는 변수를 만들어 보겠습니다. 아이디와 패스워드는 문자, 숫자, 특수문자 등이 조합되어 하나의 문자열을 만들기 때문에 문자 자료형인 char을 사용하여 선언하면 됩니다. 참고로 문자는 영문자/숫자/특수문자 1개당 1바이트, 한글 1개당 2바이트의 크기가 필요합니다.

char input_id;	// 입력한 ID 값을 저장하는 변수
char input_pw;	// 입력한 PW 값을 저장하는 변수

문자(char) 1개를 저장할 수 있는 변수 input_id(입력한 ID 저장), input_pw(입력한 PW 저장)를 각각 만들었습니다. 같은 자료형으로 여러 개의 변수를 만들 경우에는 아래와 같이 선언해도 동일한 결과를 얻을 수 있습니다.

char input_id, input_pw;

생각해보니, 자료형 char는 1바이트밖에 저장할 수 없다고 했습니다. 근데 우리가 만들 ID와 PW는? 최소 4글자(4바이트) 이상은 족히 될 것입니다. 그럼 저 변수는 한 글자밖에 저장할 수 없으니, input_id1, input_id2, input_id3... 이런 식으로 저장해야 할까요?

char input_char;	// 1바이트 글자 한 개를 저장할 수 있다
char input_string[11];	// 20바이트(21-1) 글자를 저장할 수 있다

문자들의 집합(모임)인 문자열은 char 자료형 여러개가 연속적으로 모여있어 문자열을 저장할 수 있는 형태입니다. 문자열의 크기는 대괄호( [ ] )로 지정할 수 있습니다. 문자열은 나중에 배열이라는 구조에서 다시 다루겠지만 지금은 char을 저장할 수 있는 1바이트 크기의 여러 공간이 연속적으로 붙어 있는 형태로 이해하면 됩니다. 또한 문자열의 끝에는 '\0' 문자가 자동으로 삽입되는데, 이 문자는 NULL로써 '문자열의 끝'을 나타내는 문자가 됩니다. 

단일 문자 저장 변수 input_char와 문자열 변수 input_string[11]의 차이

예를 들어 변수 char input_char에는 문자 1개만 저장할 수 있지만, char input_string[11]에는 마지막에 들어가는 '\0'을 제외한 최대 10개의 문자를 저장할 수 있습니다.

 

그럼 이제 아이디와 비밀번호를 저장할 수 있는 char 형태의 문자열 변수를 선언하고 해당 변수에 값을 저장해보도록 하겠습니다. 제대로 값이 저장됐는지 확인하기 위해 임시로 출력 함수를 사용하여 값을 출력해보도록 하겠습니다.

#include <stdio.h>

int main() {
    char input_id[11], input_pw[11];	//ID와 PW 입력받을 변수 선언
    
    printf(">> 로그인 <<\n\n");	//엔터키 두 번
    
    printf("ID : ");		//개행문자 지움
    scanf("%s", &input_id);	// 입력받은 ID를 input_id 변수에 저장
    printf("PW : ");		//개행문자 지움
    scanf("%s", &input_pw);	// 입력받은 PW를 input_pw 변수에 저장
    
    printf("\n");	//개행문자
    printf("입력한 ID는 %s, PW는 %s 입니다.", input_id, input_pw);	//input_id, input_pw 변수값 확인
	
    return 0;
}

input_id와 input_pw의 크기를 모두 11로 설정했기 때문에 저장할 수 있는 최대 글자 수는 11-1(NULL)=10글자가 됩니다. 

 

scanf() 함수로 입력받은 값을 변수에 저장

scanf() 함수에서 입력받은 값을 변수에 넣으려면 변수명 앞에 &(앤드) 기호를 사용하여 주소값(램(RAM)에서 해당 변수가 저장되어 있는 위치)을 알려줘야 합니다. & 기호는 두 가지 뜻이 있는데, 변수명 앞에 쓸 경우 주소값을 알려달라는 뜻을 가지게 됩니다. 그래서 그 변수 이름을 통해 주소(&)를 찾고, 해당 주소에 가서 값을 저장해줍니다.

printf() 함수에서 형식 지정자를 사용하여 변수값을 출력

printf() 함수를 통해 변수값을 출력할 때는 출력할 문자열(" ") 안에 변수의 자료형에 맞는 형식 지정자를 입력하고, 문자열 밖에서 변수 이름을 순서대로 작성해주면 됩니다. 

그럼 정상적으로 실행되는지 확인해보도록 하겠습니다.

이상이 없다면 위와 같이 입력한 아이디와 패스워드가 정상적으로 출력되는 것을 확인하실 수 있습니다. 

 

다음 강의 : 2022.11.08 - [강의/나 혼자 C언어 : 기초] - 만들면서 배우는 나 혼자 C언어 : 03. 조건문

 

만들면서 배우는 나 혼자 C언어 : 03. 조건문

안녕하세요. 동글쌤 입니다. 지난 강의에서 입출력 함수, 자료형과 변수를 사용해 로그인 기능을 만들어봤습니다. 이전 글 : 2022.10.28 - [강의/나 혼자 C언어 : 기초] - 만들면서 배우는 나 혼자 C언

choisdevil.tistory.com

 

728x90
반응형
그리드형

댓글