printf 함수는 문자열을 출력하는 함수로 다음과 같은 형식으로 표현된다.
printf(string, expr1, expr2, zzz);
이때 출력되는 값은 상수, 변수, 더 나아가 복잡한 표현식이 될 수 있다. 여러 예시를 살펴보면 %와 알파벳으로 이뤄진 변환규격(conversion specifications) 을 심심치않게 찾아볼 수 있다. 여기서 % 뒤에 따라오는 문자는 어떤 형식으로 자료가 변환되어서 출력할지를 정의한다.
[주의] C 컴파일러는 변환규격과 출력 대상이 되는 아이템의 갯수를 검사하지 않는다. 따라서 갯수를 일치시키는 것에 주의하자. 더나아가, 컴파일러는 아이템의 자료형과 변환규격이 일치하는지도 검사하지 않는다. 만약 float형이 %d로 대응되는 경우, 소수점 이하는 버려진다.
변환 규격은 다음과 같은 일반식으로 표현될 수 있다.
%m.pX
여기서 m은 최소자릿수다. 다시 강조한다. 최소 자릿수로 우측정렬이다. 음수로 표현된 경우, 좌측정렬이다. 다음으로 p는 precise의 p다. 즉 소수점 이하 자릿수를 정하는 것이다. 소수점 이하 자릿수를 정의하므로 뒤에 따라오는 X에 따라서 의미가 있을수도 없을수도 있다. 변환규격에는 많은 종류가 있으나 여기서 설명은 생략한다.
\n 과 같은 것을 확장 비트열이라고 부른다. 확장 비트열은 컴파일러에게 문제를 가져다 줄 수 있는 문자들을 사용할 수 있게 만든다.(예를들어, 제어를 위한 문자 혹은 컴파일러에게 있어 특별한 의미를 가지는 문자가 있다) 아래에 예시가 있다.
Alert(bell) \a Backspace \b New line \n Horizontal tab \t
scanf 함수의 예시를 살펴보자
int i, j;
float x, y;
scanf("%d%d%f%f", &i, &j, &x, &y);
먼저 printf와 마찬가지로 변환 규격의 갯수에 신경써주어야한다. 하지만 다른점도 바로 보이는데 바로 &다. 이것은 여기에 저장된다라는 의미로 이해하면된다.
[주의] 진짜 &를 까먹으면 안된다. 마냥 사용하지 않을경우, 입력값이 원하는 변수에 저장되지 않는다.
scanf함수는 입력값을 어떻게 구분하고, 변수에 저장하는걸까? 여기서 눈여겨 볼 점은 입력값을 어떻게 구분하는지다.
먼저 scanf 함수에서 입력값은 어떤 공백, 개행이 들어가더라도 무조건 무시된다.
그럼 공백을 무시하고 입력값을 일렬로 인식하면 어떻게 구분하는가? 그것은 구문 내의 변환규격에 있다. 예를들어 변환규격이 %f인 경우, 소수로 이뤄실 수 있는 수가 올 것이다. 앞자리는 음수 혹은 양수를 나타내는 부호가 있을것이고, 그다음은 숫자들, 소숫점, 소숫점이하의 자리수가 올 것이다 하지만 이런 규칙에 어긋나면 규칙에서 어긋나기 직전까지가 %f에 저장될 값이라는 것을 알 수 있다.
위에서 주어진 예시는 scanf 내에 변환규격만이 존재한다. scanf 내의 표현식과 순서(다른말로 하면 패턴)가 일치해야 변수에 차례대로 전달된다는 점을 확장하면 scanf 내에 일반적인 문자도 삽입할 수 있다.
1. 일반적인 문자
일반적인 문자가 서식 문자열에 들어간 경우, 입력값의 패턴과 대조될 때 사용된다. 예를들어 %d/%d로 서식 문자열이 쓰인경우, 두 개의 입력값 사이에 /가 들어가야한다.
2. 공백
공백도 들어갈 수 있다. 다만 서식문자열 내의 공백 하나 는 입력값의 공백 여러개 와 대응된다. 즉 서식문자열 내에 공백이 하나고, 입력값에서 공백이 여러개 주어지더라도, 입력값의 공백'들'은 하나로 인식된다.
하지만 만약 서식문자열의 패턴과 입력값의 패턴이 일치하지 않으면 어떻게 되는가? 답은 "그즉시, 입력값 읽기를 중단한다."다. 즉 읽기를 중단하고 변수에 값을 더이상 저장하지도 않는다. 남은 입력값들은 다음번 scanf 함수 호출이 일어날 때, 다시 읽혀질 것이다.
[주의] 만약 scnaf 함수 내에셔 %d\n 이 사용되면 어떻게 될까? 결과는 끔찍하다. scanf는 먼저 입력값의 공백을 무시하고 정수형 자료를 탐새할 것이다. 그 다음에는 개행, 즉 공백이 있는지 찾을것이다. 문제는 공백이 끝나고 다른 문자가 나올때까지 계속 공백을 탐색할 것이다. 다른말로 하자면, 유저가 공백, 개행 등이 아닌 문자를 입력해야 비로소 공백 인식을 멈춘다.