본문 바로가기
~ 2024.03/C 언어

[C 언어 기초] 서식 입출력

by Monett 2023. 12. 12.
반응형

K.N.King 의 C Programming - A Modern Approach 를 공부하며 내용을 정리한 글 입니다.
현재 블럭의 내용은 작성자의 의견 혹은 생각이며, 틀린 내용이 있을 수 있습니다. 지적 감사드립니다. 

printf 함수

printf 함수는 서식 문자열 (format string) 이라고 불리는 문자열을 문자열의 특정 부분에 추가된 값과 함께 출력하는 기능을 수행하도록 만들어졌다.

(The printf function is designed to display the contents of a string, known as the format string, with values possibly inserted at specified points in the string.)

 

printf(string, expr1, expr2, ...);

 

출력되는 값(expr..)들은 상수, 변수, 매우 복잡한 표현식일 수도 있다. 

 

서식 문자열은 일반적인 문자와 %로 시작하는 변환 규격(conversion specifications)을 모두 포함할 수 있다.

 

변환규격은 출력할 때 채워져야 하는 값을 대신하는 기호나 텍스트의 일부이다.

 

% 다음으로 나오는 정보는 값이 어떤 규격으로 변환될지를 정한다. 

예를 들어, 변환 규격 %d는 printf가 int값을 이진수로부터 10진수를 갖는 문자열로 변환되어 출력하는 규격을 정해준다.

 

변환 규격

일반적으로 변환규격은 아래와 같은 형식을 가진다.

%m.pX
%-m.pX

 

m과 p는 선택적으로 추가하는 정수 상수이고, X는 문자이다.

m과 p를 나누는 소수점은 p와 함께 사용해야 한다.

 

m은 최소 범위 너비(minimum field width)로, 출력할 글자의 최소 개수를 정한다.

출력할 값의 글자가 m개보다 적다면 주어진 범위 내에 있는 것이며, 나머지는 스페이스로 처리된다.

 

예를 들어, %4d에 값을 123으로 준다면 실제 출력되는 값은 ·123일 것이다.

반대로 출력할 값이 m보다 많다면 자동으로 범위를 필요한 만큼 넓힌다.

 

p는 정확도(precision)로, 변환 규격자(위의 X)의 종류에 따라 다르게 정의된다.

자주 사용되는 숫자의 변환 규격자는 다음과 같다.

 

  • d : 정수를 십진법 형식으로 보여준다. p는 최소자리수를 의미하며 필요하다면 0을 추가해준다. 
  • e : 소수를 지수형식으로 보여준다. p는 출력할 소수점 이하 자리수를 결정한다. 기본값은 여섯자리이다. 0이라면 출력하지 않는다.
  • f : 소수를 지수 없이 고정 소수점(floating-point) 형식으로 보여준다. p는 e 규격자와 같은 의미를 갖는다.
  • g : 소수를 숫자의 크기에 따라 지수 형식 혹은 고정 소수점 형식으로 보여준다. p는 최대 유효 숫자 자리수를 의미한다. f와 달리 추가적인 0을 출력하지 않는다. 소수점 이하 자리수가 없다면 소수점조차 출력하지 않는다. g 규격자는 사이즈를 예측할 수 없거나 사이즈가 다양할때 유용하다.
int number1 = 40;
float number2 = 839.21f;

printf("%d", number1); // 40
printf("%5d", number1); // ···40
printf("%-5d", number1); // 40···
printf("%5.3d", number1); // ··040

printf("%10.3f", number2); // ···839.210
printf("%10.3e", number2); // ·8.392e+02

printf("%-10g", number2); // 839.21

확장 비트열 (escape sequence)

지금까지 서식 문자열에서 자주 등장한 \n과 같은 코드는 확장 비트열이라고 부른다.

확장 비트열은 컴파일러에서 문제를 일으킬 수도 있는 문자들을 출력할 수 있게 해준다.

이는 프린트 되지 않는 제어 문자들이나 "와 같이 컴파일러가 특별히 다루는 문자들을 의미한다.

경보 (종소리) \a
백스페이스 \b
새 줄 \n
수평 탭 \t
" 문자 \"
\ 문자 \\
% 문자 %%

 

개인적으로 %를 쓸때 %%로 쓰는 점이 신기해서 추가했다.

scanf 함수

printf가 특정 서식에 따라 출력을 하듯, scaf는 특정 서식에 따라 입력을 받는다.

printf의 형식 문자열처럼 scanf의 형식 문자열 또한 기본적인 문자들과 변환 규격 모두를 포함할 수 있다.

 

대부분의 경우 scanf의 형식 문자열은 변환 규격만을 갖고 있는 경우가 많다.

int i;
int j;
float x;
float y;
scanf("%d%d%f%f", &i, &j, &x, &y);

 

사용자가 다음과 같이 입력했다고 가정해보자.

1 -20 .3 -4.0e3

 

scanf는 이 줄을 읽은 다음 각 문자들을 내포하고 있는 숫자로 변환하고, i j x y에 각각 할당한다.

 

printf처럼 scanf는 자신도 모르게 실수할 수 있을 때가 있기에 몇 가지를 주의해야한다.

scanf를 사용할 때 프로그래머들은 반드시 변환 규격의 개수와 입력받는 개수가 같으며, 각 변환이 해당하는 변수에 알맞는지를 확인해야 한다.

컴파일러는 printf처럼 확실하게 확인하고 넘어가지 않는다.

 

또다른 주의점은 scanf를 호출할 때 사용하는 변수 앞에 & 기호를 넣어주어야한다. 

반드시는 아니지만 꼭 필요하며, 프로그래머의 책임이다.

포인터 사용을 위해 & 기호를 넣는다. 해석하자면 i 변수의 주소가 가리키는 메모리에 입력값을 넣겠다는 의미 

 

scanf를 호출하는 것은 매우 강력하지만 데이터를 읽기에는 좋지 못한 방식이다.

대부분의 전문적인 C 프로그래머들은 scanf를 사용하지 않고, 모든 데이터를 문자 형식으로 받아 나중에 숫자 형식으로 변환하는 방식을 사용한다.

이후에 나오지만 read_line 함수등을 작성하여 한 문자씩 받는다.

 

 

반응형

'~ 2024.03 > C 언어' 카테고리의 다른 글

[C 언어 기초] 포인터  (0) 2023.12.13
[C 언어 기초] 선택문  (0) 2023.12.13
[C 언어 기초] 표현식  (0) 2023.12.13
[C 언어 기초] C 프로그램의 구조  (0) 2023.12.12
[C 언어 기초] C 언어 개요  (1) 2023.12.12