[C] 6. printf를 좀 더 잘 써봅시다. <필드폭 및 소수점 조정, 이스케이프 문자>
C | C++/C

[C] 6. printf를 좀 더 잘 써봅시다. <필드폭 및 소수점 조정, 이스케이프 문자>

Woon2World :: Programming & Art Life

 

지난 글에서 printf와 scanf를 다루면서 서식 문자까지 살펴보았었죠.

이번 글은 printf에 대해 조금의 보충 설명을 하는 글입니다.

중요도로 따지면 지난 글에 비해서는 떨어지니

쉬어가는 글, 가볍게 읽는 글로 생각하고 읽어주세요.

 

 

printf에서,
서식 문자는 출력할 폭과 소수 자릿수를 지정할 수 있습니다.
특별한 출력을 하는 이스케이프 문자들이 있습니다.



 

 

필드폭 지정

 

필드폭이란, 서식 문자를 출력할 때 사용하는 공간의 폭입니다.

말해 무엇합니까.

이것은 직접 눈으로 보는 게 빠릅니다.

 

이번 소스의 이름은 "6. 필드폭 및 소수점 조정, 이스케이프 문자.c"입니다.

 

#include <stdio.h>
 
int main()
{
    int a, b;
    scanf_s("%d, %d"&a, &b);
    printf("%d + %d = %d\n", a, b, a + b);
 
    return 0;
}
cs

 

두 숫자를 입력받아 덧셈을 하는 간단한 프로그램입니다.

scanf_s에서 "%d, %d"라는 문자열을 입력받기 때문에,

"정수, 정수" 꼴의 입력이 필요합니다.

예를 들어 "2, 4", "3, 5", "5, 6" 등의 입력이 있을 수 있겠죠.

"2 4", "3 5", "5 6"와 같이 입력하면 scanf_s에서 ,를 입력받도록 되어있는데 ,를 입력하지 않아 문제가 발생합니다.

실행 결과입니다.

이제 여기서 필드폭 지정을 해봅시다.

 

#include <stdio.h>
 
int main()
{
    int a, b;
    scanf_s("%d, %d"&a, &b);
    printf("%03d + %03d = %03d\n", a, b, a + b);
 
    return 0;
}
cs

 

필드폭 지정을 하니, 003, 005, 008과 같은 형태로 출력이 됩니다.

간단하게, 출력할 칸 수를 지정한다 생각하시면 되겠습니다.

 

필드폭 지정의 종류는 다음과 같습니다.

  • %n(자료형 약자) : n칸 만큼의 공간을 확보하고, 오른쪽 정렬합니다.
  • %0n(자료형 약자) : n칸 만큼의 공간을 확보하고, 오른쪽 정렬합니다. 남는 자리는 모두 0으로 채웁니다.
  • %-n(자료형 약자) : n칸 만큼의 공간을 확보하고, 왼쪽 정렬합니다.
  • %+n(자료형 약자) : n칸 만큼의 공간을 확보하고, 오른쪽 정렬합니다. +/- 부호를 표시합니다.

 

#include <stdio.h>
 
int main()
{
    int a, b;
    scanf_s("%d, %d"&a, &b);
    printf("%03d + %03d = %03d\n", a, b, a + b);
 
    printf("%-10s %20s\n""전공필수""C언어프로그래밍");
    printf("%-10s %20s\n""전공필수""선형대수학");
    printf("%-10s %20s\n""전공선택""게임기획1");
    printf("%-10s %20s\n""핵심교양""글쓰기");
 
    return 0;
}
cs

 

재밌는 것 몇 가지를 더 추가해보았습니다.

%s는 문자열 서식 문자죠?

따라서 %-10s는 10칸 만큼의 공간에 왼쪽 정렬된 문자열,

%20s는 20칸 만큼의 공간에 오른쪽 정렬된 문자열을 의미합니다.

서식 문자가 두 개이니, printf는 문자열 외에 두 개의 인자를 추가로 요구합니다.

서식 문자가 %s인 만큼 추가적인 인자들도 문자열입니다.

따라서 인자는 문자열 세 개가 되는 것이죠.

출력 결과는 이렇습니다.

 

소수점 조정

 

부동소수점 자료형의 경우, 출력할 때에 소수 자릿수를 정할 수 있습니다.

일단 자릿수 지정을 하지 않아보죠.

 

#include <stdio.h>
 
int main()
{
    int a, b;
    scanf_s("%d, %d"&a, &b);
    printf("%03d + %03d = %03d\n", a, b, a + b);
 
    printf("%-10s %20s\n""전공필수""C언어프로그래밍");
    printf("%-10s %20s\n""전공필수""선형대수학");
    printf("%-10s %20s\n""전공선택""게임기획1");
    printf("%-10s %20s\n""핵심교양""글쓰기");
 
    float c;
    scanf_s("%f"&c);
    printf("%f\n", c);
 
    return 0;
}
cs

 

문자열들의 출력이 끝난 후에, 0을 입력했더니 출력값은 0.000000이 나왔습니다.

어떤 값을 입력하든 소수 자릿수는 여섯 자릿수가 나올 겁니다.

 

    printf("%.f\n", c);
cs

 

c를 출력하는 부분에서 %f%.f로 바꿔줍시다.

그랬더니, 0이 그대로 나옵니다!

심지어는 3.14도 3으로 나오는군요.

 

소수점 조정 방법은 이렇습니다.

  • %.n(자료형 약자) : 소수점 아래 n+1번째 자리에서 반올림하여 소수점 아래 n개의 자릿수만을 표시합니다.
    n을 지정하지 않으면 소수점 아래 자릿수들을 표시하지 않습니다.

%.2f를 썼다면 소수점 아래 3번째 자리에서 반올림하여 소수점 아래 2개의 자릿수까지만 표시합니다.

%.3f를 썼다면 소수점 아래 4번째 자리에서 반올림하여 소수점 아래 3개의 자릿수까지만 표시합니다.

 

%f에 해당하는 예시만 들었지만, %lf도 가능합니다.

%.2lf, %.3lf와 같이 적으면 됩니다.

 

소수점 아래 몇 자리까지만 표시해야 할 때가 있죠?

상상해보세요.

그럴 때 이런 기능이 있는 줄 모르고서는 직접 반올림하는 프로그램을 짜버립니다.

그 프로그램은 0을 적게 되더라도 항상 소수점 아래 6자리까지 출력해버리는 결과를 띄우겠죠.

프로그래머는 도저히 어찌 할 수가 없어 벽을 느끼고 분노하게 됩니다.

이런 일이 여러분들에게는 안 일어나야겠죠?

하지만 이는 분명 C언어를 갓 배우기 시작한 사람들에게 흔하게 일어나는 일입니다.

정말 눈물나는 일입니다.

여러분은 그럴 일이 없도록 잘 기억해주시기 바랍니다.

 

이스케이프 문자

 

printf에서 일반적인 문자와는 달리 출력될 때 특수한 기능을 하는 문자들이 있습니다.

바로, 이스케이프 문자(escape sequence)들인데요.

여러분들이 자주 보셨던 줄넘김 문자, \n도 이 이스케이프 문자입니다.

이스케이프 문자들은 전부 \(역슬래쉬)로 시작합니다.

 

이스케이프 문자 의미 기능
\a 경보(alert) 비프음 출력
\b 백스페이스(back space) 백스페이스
\f 폼피드(form feed) 커서를 다음 페이지의 시작 부분으로 넘김
\n 개행(new line) 커서를 다음 줄 첫 번째 위치로 넘김
\t 수평 탭(horizontal tab) 키보드의 tab키와 같은 기능
\v 수직 탭(vertical tab) 수직 탭
\r 캐리지 리턴(carriage return) 커서를 다음 줄로 넘기지 않고, 첫 번째 위치로 넘김
\\ 백슬래쉬(backslash) 역슬래쉬 자체를 출력
\' 작은 따옴표
(single quotation marks)
작은 따옴표 자체를 출력
\" 큰 따옴표
(double quotation marks)
큰 따옴표 자체를 출력
\(숫자) 8진수(octal number) 뒤의 숫자가 8진수임을 나타냄 ex) \101 ('A' 출력)
아스키코드에서 해당 숫자에 해당되는 문자로 대치됨.
\x(숫자) 16진수(hexadecimal number) 뒤의 숫자가 16진수임을 나타냄 ex) \x5A ('Z' 출력)
아스키코드에서 해당 숫자에 해당되는 문자로 대치됨.
\u(숫자) 유니코드(unicode) 뒤의 16진수가 유니코드임을 나타냄 ex) \uAC00 ('가' 출력)

 

보통 자주 쓰는 이스케이프 문자에만 굵게, 파랑색 처리를 했습니다.

이 표는 여태껏 나왔던 모든 표 중에서 중요도가 제일 낮으니 외우시지 마시기 바랍니다.

 

문자열은 "" 안에  쓰는 것으로 그것이 문자열임을 나타내는데,

그럼 문자열 안에서 "를 쓰는 데 난관이 있죠.

문자로서의 "와 문자열의 종료를 알리는 "가 같으니까요.

이 때 필요한 게 \"입니다.

문자로서의 " 자체를 출력하려면 \와 함께 적어주어야 합니다.

\'도 같은 맥락입니다.

 

 

#include <stdio.h>
 
int main()
{
    int a, b;
    scanf_s("%d, %d"&a, &b);
    printf("%03d + %03d = %03d\n", a, b, a + b);
 
    printf("%-10s %20s\n""전공필수""C언어프로그래밍");
    printf("%-10s %20s\n""전공필수""선형대수학");
    printf("%-10s %20s\n""전공선택""게임기획1");
    printf("%-10s %20s\n""핵심교양""글쓰기");
 
    float c;
    scanf_s("%f"&c);
    printf("%.f\n", c);
 
    printf("\"Hello, World!\"\n");
 
    return 0;
}
cs

 

"Hello, World!"의 큰 따옴표까지 출력을 해보았습니다.

\"\n이 붙어있는 게 눈에 잘 안 들어오시겠지만, 큰 따옴표 자체를 출력하고, 줄넘김을 하는 것입니다.

 

꽤나 지엽적인 내용이었습니다.

그래도 깔끔한 출력을 원할 때 필드폭 지정과 소수점 조정을 쓰긴 하니까요.

이런 지엽적인 내용 알아서 뭐해! 하지는 말아주세요 ㅠㅠ.

이스케이프 문자는 \n이 이스케이프 문자였다는 점과

'와 " 자체를 출력할 때에 \를 적어주면 된다는 점 정도만 알면 되죠.

이번 글은 필요할 때 찾아서 보는 글 정도로 여겨주셨으면 좋겠습니다.

슬슬 여러분들의 흥미를 돋굴 만한 여러 문제들을 만들어보면 좋겠군요.