[C] - Formatted Input/Output

Chris Kim·2024년 9월 17일

프로그래밍언어

목록 보기
3/25

printf 함수

printf 함수는 문자열을 출력하는 함수로 다음과 같은 형식으로 표현된다.

printf(string, expr1, expr2, zzz);

이때 출력되는 값은 상수, 변수, 더 나아가 복잡한 표현식이 될 수 있다. 여러 예시를 살펴보면 %와 알파벳으로 이뤄진 변환규격(conversion specifications) 을 심심치않게 찾아볼 수 있다. 여기서 % 뒤에 따라오는 문자는 어떤 형식으로 자료가 변환되어서 출력할지를 정의한다.

[주의] C 컴파일러는 변환규격과 출력 대상이 되는 아이템의 갯수를 검사하지 않는다. 따라서 갯수를 일치시키는 것에 주의하자. 더나아가, 컴파일러는 아이템의 자료형과 변환규격이 일치하는지도 검사하지 않는다. 만약 float형이 %d로 대응되는 경우, 소수점 이하는 버려진다.

변환규격(Conversion Specifications)

변환 규격은 다음과 같은 일반식으로 표현될 수 있다.

%m.pX

여기서 m은 최소자릿수다. 다시 강조한다. 최소 자릿수로 우측정렬이다. 음수로 표현된 경우, 좌측정렬이다. 다음으로 p는 precise의 p다. 즉 소수점 이하 자릿수를 정하는 것이다. 소수점 이하 자릿수를 정의하므로 뒤에 따라오는 X에 따라서 의미가 있을수도 없을수도 있다. 변환규격에는 많은 종류가 있으나 여기서 설명은 생략한다.

확장 비트열(Escape Sequences)

\n 과 같은 것을 확장 비트열이라고 부른다. 확장 비트열은 컴파일러에게 문제를 가져다 줄 수 있는 문자들을 사용할 수 있게 만든다.(예를들어, 제어를 위한 문자 혹은 컴파일러에게 있어 특별한 의미를 가지는 문자가 있다) 아래에 예시가 있다.

Alert(bell) 	\a
Backspace		\b
New  line		\n
Horizontal tab	\t

scanf 함수

scanf 함수의 예시를 살펴보자

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

먼저 printf와 마찬가지로 변환 규격의 갯수에 신경써주어야한다. 하지만 다른점도 바로 보이는데 바로 &다. 이것은 여기에 저장된다라는 의미로 이해하면된다.

[주의] 진짜 &를 까먹으면 안된다. 마냥 사용하지 않을경우, 입력값이 원하는 변수에 저장되지 않는다.

scanf 함수의 작동원리

scanf함수는 입력값을 어떻게 구분하고, 변수에 저장하는걸까? 여기서 눈여겨 볼 점은 입력값을 어떻게 구분하는지다.
먼저 scanf 함수에서 입력값은 어떤 공백, 개행이 들어가더라도 무조건 무시된다.
그럼 공백을 무시하고 입력값을 일렬로 인식하면 어떻게 구분하는가? 그것은 구문 내의 변환규격에 있다. 예를들어 변환규격이 %f인 경우, 소수로 이뤄실 수 있는 수가 올 것이다. 앞자리는 음수 혹은 양수를 나타내는 부호가 있을것이고, 그다음은 숫자들, 소숫점, 소숫점이하의 자리수가 올 것이다 하지만 이런 규칙에 어긋나면 규칙에서 어긋나기 직전까지가 %f에 저장될 값이라는 것을 알 수 있다.

서식 문자열 내의 일반 문자(Ordinary Character)

위에서 주어진 예시는 scanf 내에 변환규격만이 존재한다. scanf 내의 표현식과 순서(다른말로 하면 패턴)가 일치해야 변수에 차례대로 전달된다는 점을 확장하면 scanf 내에 일반적인 문자도 삽입할 수 있다.
1. 일반적인 문자
일반적인 문자가 서식 문자열에 들어간 경우, 입력값의 패턴과 대조될 때 사용된다. 예를들어 %d/%d로 서식 문자열이 쓰인경우, 두 개의 입력값 사이에 /가 들어가야한다.
2. 공백
공백도 들어갈 수 있다. 다만 서식문자열 내의 공백 하나 는 입력값의 공백 여러개 와 대응된다. 즉 서식문자열 내에 공백이 하나고, 입력값에서 공백이 여러개 주어지더라도, 입력값의 공백'들'은 하나로 인식된다.

하지만 만약 서식문자열의 패턴과 입력값의 패턴이 일치하지 않으면 어떻게 되는가? 답은 "그즉시, 입력값 읽기를 중단한다."다. 즉 읽기를 중단하고 변수에 값을 더이상 저장하지도 않는다. 남은 입력값들은 다음번 scanf 함수 호출이 일어날 때, 다시 읽혀질 것이다.

[주의] 만약 scnaf 함수 내에셔 %d\n 이 사용되면 어떻게 될까? 결과는 끔찍하다. scanf는 먼저 입력값의 공백을 무시하고 정수형 자료를 탐새할 것이다. 그 다음에는 개행, 즉 공백이 있는지 찾을것이다. 문제는 공백이 끝나고 다른 문자가 나올때까지 계속 공백을 탐색할 것이다. 다른말로 하자면, 유저가 공백, 개행 등이 아닌 문자를 입력해야 비로소 공백 인식을 멈춘다.

profile
회계+IT=???

0개의 댓글