들어가며...
변수의 타입에 대해서 세부적인 설명을 하기 전에 본인이 개발한 내용을 확인하기 위해서는 크게 두가지 방법이 있는데 첫번째는 로그를 출력하는 것이고 두번째는 디버깅툴을 사용하는 것입니다.
디버깅툴을 사용하는 것은 자신이 사용하고 있는 IDE 툴에 따라 다르기 때문에 이번 포스팅에서는 C언어에서 로그를 출력하는 방법과 추가로 사용자 입력을 받는 방법에 대해서 간략하게 알아보도록 하겠습니다.
실제 C 프로그램에서는 사용자의 입력을 받을 일이 거의 없기 때문에 입력은 "scanf()"라는 함수에 대해 간략하게 알아보고 출력의 경우는 디버깅을 위해서도 사용하지만 운영중인 프로그램의 오류 및 원인파악을 위해 별도의 로그유틸을 만들어서 사용할 정도로 빈번하게 사용하기 때문에 "printf()" 함수에 대해서는 좀 더 세세하게 알아보도록 하겠습니다.
- Table of Contents
- printf() 사용법
- scanf() 사용법
- 입출력 예제
printf() 사용법
실제 사용방법을 알아보기 전에 printf() 함수의 함수원형(프로토타입, prototype)은 다음과 같습니다.
● printf 함수원형
prototype | int printf(const char *format, [argument, ...]) |
include | stdio.h |
description | STDOUT(화면출력)에 서식화된(formatted) 문자열을 출력한다. 아무런 서식없이 문자열을 출력할 수도 있으며 '%'로 시작하는 서식과 서식에 대응되는 인수를 포함하여 복잡한 조합의 문자열을 출력할 수도 있다. |
return | - 성공 : 출력한 바이트 수를 반환 - 실패 : EOF 발생 ✫ 보편적으로 printf() 함수의 반환값은 거의 사용하지 않는다. |
printf() 함수는 알고자 할 수록 매우 복잡한 함수입니다. 이번 글에서는 기본적인 서식의 종류를 포함하여 그 외 비교적 자주 사용되는 부분을 위주로 설명토록 하겠습니다.
● 기본 사용법
//< printf()을 사용하기 위해서는 "stdio.h" 헤더파일을 include하여야 한다
#include <stdio.h>
int main(int argc, const char * argv[]) {
//< 단순 문자열 출력
printf("Hello World\n");
//< 기본적인 형태 사용법
printf("Hello %s\n", "World");
return 0;
}
위 두가지 형태의 사용법은 모두 동일한 결과값 "Hello World"를 출력하게 됩니다. 보통은 두 번째와 같이 '%'라는 서식과 그에 대입되는 인수를 매핑하여 많이 사용됩니다.
● 서식의 종류
서식 | 의미 | 설명 | 인수타입 |
%d | Decimal | 10진수 정수 출력 | int, long |
%i | Integer | 10진수 정수 출력 | int, long |
%u | Unsigned | 부호없는 10진수 정수 출력 | unsigned |
%x | heXadecimal | 정수를 16진수로 출력 | |
%X | heXadecimal | 정수를 대문자 16진수로 출력 | |
%o | Octal | 정수를 8진수로 출력 | |
%c | Character | 1개의 문자를 출력 | char |
%s | String | 문자열 출력 | char * |
%f | Float | 고정 소수점 형식으로 출력 | float, double |
%e | 실수형 (부동 소수점) 형식으로 출력 | float, double | |
%E | %e와 동일하나 대문자로 출력 | float, double | |
%g | 실수형을 간소화하여 출력 | float, double | |
%G | %g와 동일하나 대문자로 출력 | float, double | |
%n | 지금까지 출력한 문자 개수 저장 | int * | |
%p | Pointer | 포인터의 번지값 출력 | |
%% | 문자 '%'를 출력 |
위의 서식 중 '%f'까지는 자주 사용되며 그 이하의 것들은 자주 사용될 일은 없을 것입니다.
● 예제코드
#include <stdio.h>
int main(int argc, const char * argv[]) {
char str[10] = "Hello";
// '%d' example
printf("'%%d' example : %d\n", -10);
// '%i' example
printf("'%%i' example : %i\n", 10);
// '%u' example
printf("'%%u' example : %u\n", -10);
// '%x' example
printf("'%%x' example : %x\n", 10);
// '%X' example
printf("'%%X' example : %X\n", 10);
// '%o' example
printf("'%%o' example : %o\n", 10);
// '%c' example
printf("'%%c' example : %c\n", 'A');
// '%s' example
printf("'%%s' example : %s\n", "10");
// '%f' example
printf("'%%f' example : %f\n", 10.1);
// '%e' example
printf("'%%e' example : %e\n", 10.1);
// '%E' example
printf("'%%E' example : %E\n", 10.1);
// '%g' example
printf("'%%g' example : %g\n", 10.1);
// '%G' example
printf("'%%G' example : %G\n", 10.1);
// '%p' example
printf("'%%p' example : %p\n", str);
return 0;
}
● 결과확인
✳︎ 생각해보기
다른 부분은 모두 이해되시리라 생각됩니다. 단, 세번째의 %u 예제에 대해 추가 설명을 하자면 -10을 unsigned로 출력하라는 의미인데 "
4294967286" 라는 값이 출력되었습니다.
이는 C언어에서의 음수표현은 2의보수를 사용하기 때문입니다. 컴퓨터에서 음수표현에 대한 내용은 기회가 되면 별도의 포스트로 설명하고 이 글에서는 2의보수를 사용한다라고만 정리하겠습니다.
2의보수를 구하는 방법은 원래 값에서 모든 비트를 반전시킨후 1을 더하여 구합니다. 아래는 1이라는 숫자를 이용하여 -1을 구하는 방법의 예시입니다.
#include <stdio.h>
int main(int argc, const char * argv[]) {
int positive_1 = 1;
int nagative_1 = 1;
// -1을 구하기 위해 1의 2의보수 값을 구한다 > 비트반전 후 1을 더함
nagative_1 = ~positive_1 + 1;
# 양수 1의 출력값 : "1 : 0x00000001"
printf("1 : 0x%08x\n", positive_1);
# 음수 1의 출력값 : "-1 : 0xffffffff"
printf("-1 : 0x%08x\n", nagative_1);
return 0
}
위와 동일한 방법으로 -10은 실제 메모리에 0xFFFFFFF6로 저장되고, 이를 unsigned으로 표현하게 되면 4294967286이 되는 것입니다.
● 폭지정 하기
간혹 출력되는 값의 폭 즉, 동일한 길이로 출력하고 싶을 때가 있습니다. 3가지 방법이 존재하며 아래의 샘플 코드를 확인하시면 됩니다.
● 예제코드
#include <stdio.h>
int main(int argc, const char * argv[]) {
// n : 출력할 폭을 지정
printf("[%5d]\n", 10);
// 0n : 출력할 폭을 지정하고 빈 자리수에는 0을 강제로 채운다.
printf("[%05d]\n", 10);
// * : 폭지정을 인수로 입력 받는다.
printf("[%*d]\n", 5, 10);
// * : 폭지정을 인수로 입력 받고 빈 자리수에는 0을 강제로 채운다.
printf("[%0*d]\n", 5, 10);
return 0;
}
● 결과확인
● 정렬하기
위의 예제에서 보았듯이 빈공간이 있을 경우 기본적으로 우측정렬을 하고 출력되게 됩니다. 이를 강제로 좌측정렬하려면 %뒤에 '-'를 추가하면 됩니다.
● 예제코드
#include <stdio.h>
int main(int argc, const char * argv[]) {
// n : 출력할 폭을 지정
printf("[%-5d]\n", 10);
// * : 폭지정을 인수로 입력 받는다.
printf("[%-*d]\n", 5, 10);
return 0;
}
● 결과확인
✳︎ 생각해보기
좌측으로 정렬할 때는 빈공간을 강제로 0으로 채우는 것은 불가합니다. 위의 예제와 같이 10의 숫자를 우측정렬하고 5자리수의 고정폭으로 출력하는데 빈공간을 0으로 채워버리면 10이 아니라 "10000"으로 출력되기 때문입니다.
scanf() 사용법
scanf() 함수는 printf() 함수와 반대로 사용자로 부터 입력을 받는 함수입니다. 단, printf() 함수와 차이점이라면 포맷부분에 서식만을 사용할 수 있으며 인수로는 입력된 값을 저장할 수 있는 변수의 주소를 넣어준다는 것입니다.
아래는 scanf() 함수의 함수원형 입니다.
● scanf 함수원형
prototype | int scanf(const char *format, [address ...]) |
include | stdio.h |
description | 사용자로 부터 서식에 해당하는 입력을 받아 인수의 주소가 가리키는 곳에 입력 값을 저장한다. 기본적인 사용법은 int a = 0; scanf("%d", *a); 와 같이 사용한다. |
return | 성공 : 입력에 성공한 필드의 개수 실패 : EOF |
● 예제
scanf() 함수를 통해 숫자(%d), 문자열(%s), 실수(%lf)를 입력 받을 수 있으며 입력 숫자 중간 중간에 스페이스를 추가하여 한번에 여러개의 값도 입력으로 전달 받을 수 있으나 주로 사용되는 정수 입력에 대한 예제만 살펴보도록 하겠습니다.
● 예제코드
#include <stdio.h>
int main(int argc, const char * argv[]) {
// 입력값을 저장할 정수형 변수 정의
int input = 0;
// 0을 입력할 때 까지 무한루프
while(1) {
// 사용법 출력
printf("숫자를 입력하세요 (종료 : 0) : ");
// 사용자 입력을 대기
scanf("%d", &input);
// 사용자가 0을 입력했을 경우 프로그램 종료
if(input == 0) {
printf("프로그램을 종료합니다.\n");
break;
}
// 0 이외의 숫자값을 입력했을 경우 해당 숫자값을 출력
printf("숫자 %d를 입력하셨습니다.\n", input);
}
return 0;
}
● 결과확인
입출력 예제
printf(), scanf() 함수 및 위의 샘플 코드들을 이용하여 간단한 입출력 예제 코드를 작성해 보았습니다. 코드를 참조하여 직접 사용해보면서 두 함수가 어떻게 동작하는 지 확인 해 보시기 바랍니다. while(반복문), switch(조건문) 등은 추후에 포스팅을 할 것이므로 지금은 저런 것이 있는 정도로만 이해하시면 되겠습니다.
● 예제코드
#include <stdio.h>
// prototype of functions
void help(void);
void printf_basic(void);
void printf_format(void);
void printf_width(void);
void printf_align(void);
/**
Main 함수
*/
int main(int argc, const char * argv[]) {
// 입력값을 저장할 정수형 변수 정의
int input = 0;
int exitFlag = 0;
// 도움말 출력
help();
// 0을 입력할 때 까지 무한루프
while(1) {
if(exitFlag != 0) {
break;
}
printf("입력 : ");
// 사용자 입력을 대기
scanf("%d", &input);
switch (input) {
case 1:
printf_basic();
break;
case 2:
printf_format();
break;
case 3:
printf_width();
break;
case 4:
printf_align();
break;
case 9:
help();
break;
case 0:
printf("프로그램을 종료합니다.\n");
exitFlag++;
break;
default:
printf("알 수 없는 입력 값입니다. 도움말이 필요하시면 9를 입력하십시오\n");
break;
}
}
return 0;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
void help() {
printf("====================================\n");
printf(" 1 : printf() 기본 예제\n");
printf(" 2 : printf() 서식 예제\n");
printf(" 3 : printf() 폭지정 예제\n");
printf(" 4 : printf() 정렬 예제\n");
printf(" 9 : 도움말 출력\n");
printf(" 0 : 종료\n");
printf("====================================\n");
}
void printf_basic() {
printf("====================================\n");
printf(" printf() 기본 예제\n");
printf("====================================\n");
// 단순 문자열 출력
printf("Hello World\n");
// 기본적인 형태 사용법
printf("Hello %s\n", "World");
}
void printf_format() {
char str[10] = "Hello";
printf("====================================\n");
printf(" printf() 서식 예제\n");
printf("====================================\n");
// '%d' example
printf("'%%d' example : %d\n", -10);
// '%i' example
printf("'%%i' example : %i\n", 10);
// '%u' example
printf("'%%u' example : %u\n", -10);
// '%x' example
printf("'%%x' example : %x\n", 10);
// '%X' example
printf("'%%X' example : %X\n", 10);
// '%o' example
printf("'%%o' example : %o\n", 10);
// '%c' example
printf("'%%c' example : %c\n", 'A');
// '%s' example
printf("'%%s' example : %s\n", "10");
// '%f' example
printf("'%%f' example : %f\n", 10.1);
// '%e' example
printf("'%%e' example : %e\n", 10.1);
// '%E' example
printf("'%%E' example : %E\n", 10.1);
// '%g' example
printf("'%%g' example : %g\n", 10.1);
// '%G' example
printf("'%%G' example : %G\n", 10.1);
// '%p' example
printf("'%%p' example : %p\n", str);
}
void printf_width() {
printf("====================================\n");
printf(" printf() 폭지정 예제\n");
printf("====================================\n");
// n : 출력할 폭을 지정
printf("[%5d]\n", 10);
// 0n : 출력할 폭을 지정하고 빈 자리수에는 0을 강제로 채운다.
printf("[%05d]\n", 10);
// * : 폭지정을 인수로 입력 받는다.
printf("[%*d]\n", 5, 10);
// * : 폭지정을 인수로 입력 받고 빈 자리수에는 0을 강제로 채운다.
printf("[%0*d]\n", 5, 10);
}
void printf_align() {
printf("====================================\n");
printf(" printf() 정렬 예제\n");
printf("====================================\n");
// n : 출력할 폭을 지정
printf("[%-5d]\n", 10);
// * : 폭지정을 인수로 입력 받는다.
printf("[%-*d]\n", 5, 10);
}
● 결과확인
마무리...
이상으로 C언어에서 사용되는 입출력 함수에 대해서 간단하게 알아봤습니다. 물론 이 외에도 입출력 함수로 많은 함수들이 있으나 앞서도 말했듯이 실제 C언어 프로그램에서는 printf()를 이용한 로그출력외에는 거의 사용 안하게 되므로 입출력에 대해서는 이걸로 마무리 하도록 하겠습니다.
U2ful은 ♥입니다. @U2ful Corp.
'Programming > C언어 초급' 카테고리의 다른 글
C언어 초급) 02.변수 : 04. 실수형 (0) | 2020.05.27 |
---|---|
C언어 초급) 02.변수 : 03. 정수형 (0) | 2020.05.25 |
C언어 초급) 02.변수 : 01. 변수의 정의 (0) | 2020.05.22 |
C언어 초급) 01.들어가며 : 04. 프로그램의 구조 (0) | 2020.05.21 |
C언어 초급) 01.들어가며 : 03. C언어의 구성요소 (0) | 2019.10.02 |