농담곰담곰이의곰담농

C 프로그래밍 : 현대적 접근 03 | 서식 입출력

by 브이담곰

1 printf 함수

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

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

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

% 다음으로 나오는 정보는 값이 어떤 규격으로 본래 형식에서 출력되는 형식이 변환되는지 정함.

 

서식 문자열은 생긴 그대로 출력되지만, 변형 규격은 출력되어야 할 값들로 바뀌어져서 출력된다.

int i;
int j;
float x;
float y;

i = 10;
j = 20;
x = 43.2892f;
y = 5527.0f;

printf("i = %d, j = %d, x = %f, y = %f\n", i, j, x, y);

 

변환 규격

%m.pX . %-m.pX와 같은 형식을 갖는다.

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

 

%.1f  소수점 한 자리까지 출력

%10f 정수 10자리까지 출력

 

확장 비트열 escape sequence
경보(종소리) \a
백스페이스 \b
새 줄 \n
수평탭 \t

 

 

2 scanf 함수

scanf 함수는 호출될 때 문자열을 왼쪽부터 처리한다.

해당 아이템을 읽고, 해당 아이템과 무관한 문자가 나오면 읽는것을 멈춘다. 

읽기가 완료되면 그 다음엔 남은 나머지 서식문자열을 처리한다.

어떤 아이템이라도 제대로 읽히지 않았다면 scanf함수는 나머지 서식문자열은 확인도 하지 않고 즉시 값을 반환한다.

 

scanf 함수는 공란문자(white-space-characters, 빈칸, 수평/수직 탭, 폼-피드, 개행문자)를 무시한다.

→ 숫자는 한 줄에만 있을 수도 있고, 여러 줄에 걸쳐 적혀있을 수도 있다.

 

scanf의 작동 방식
scanf("%d%d%f%f", &i, &j, &x, &y);

 위의 입력 함수에 따라 아래와 같이 입력을 했다고 한다면

scanf함수는 세 줄이 아닌 하나의 연속된 문자로 인식한다.

scanf 함수는 숫자를 읽어야 하므로 모든 공란문자를 무시하고, 숫자만 읽는다!

 

 

💡 서식 문자열에 변환규격자가 아닌 일반적인 문자를 추가해줬을 경우.
scanf 서식문자열 내의 일반적인 문자 처리방식 = 문자가 공란문자인지 아닌지에 따라 달라짐!
서식 문자열 내에 하나 혹은 연속된 공란문자가 존재할 경우 scanf는 (뒤로 미룰) 공란문자를 찾기 전까지 계속해서 공란문자를 읽는다. ( 서식 문자열에 공란문자가 몇개 있는지는 중요하지 않다! )
만약 짝이 지어지지 않는다면 scanf은 해당 문자를 다시 입력에 돌려놓고 읽기 과정을 취소하여 서식문자열을 처리하거나 입력 문자들을 더 이상 읽지 않는다.

ex)"%d/%d"
_5/_96을 읽을 때는, 
1. 빈칸 무시
2. %d 와 5를 짝 지어진다.
3. /와 / 가 짝지어진다.
4. 빈칸 무시
5. %d와 96이 짝지어진다.

_5_/_96
1. 빈칸 무시
2. %d 와 5를 짝 지어진다.
3. /를 짝지어 주어야하는데 빈칸이므로 빈칸을 뒤로 물린다.  
4. 나머니 _/_96은 다음 scanf 호출에 의해 읽힐 수 있게 내버려 둔다.
→ 첫번째 정수 이후에 빈칸을 허용하려면 서식문자열을 "%d /%d"로 해야한다.

 

scanf과 printf의 구분
printf("%d %d\n", &i, &j);    /*** WRONG ***/

‼️ 위 코드를 실행하면 i,j의 값이 아닌 i,j의 value 값이 나온다.

 

scanf("%d, %d", &i, &j);

💡 scanf는 우선 정수값을 찾을 것이고, 이는 i 변수에 저장된다. 다음에는 ,를 짝지어 주어야하는데, 만약 입력이 , 가 들어오지 않으면 j의 값을 읽지 않은 채로 scanf는 종료된다.

 

 

Q&A
 %i 와 %d의 차이

printf에서는 큰 차이가 없지만, scanf에서는 차이가 있다.

%d는 오로지 정수만 입력받을 수 있지만, %i는 10,8,16진수를 모두 인식할 수 있다.

만약 입력값이 0으로 시작한다면 %i는 입력값을 8진수로 시작한다. 0X는 16진수로 취급!

따라서 왠만하면 %d를 사용하는 것이 좋다.

 

printf에서 %의 출력 방법
printf("농담곰 나이: %d%%\n", profit);

% 두 개를 연이어서 쓰면 된다.

 

scanf 이 숫자를 읽어야할 때 숫자가 아닌 값을 입력해준 경우
printf("숫자를 입력하세요: );
scanf("%d", &i);

 

첫번째 경우 

입력값 = 23foo

scanf는 2와3을 읽고 i에 저장한다.

foo는 다음 scanf나 다른 입력 함수 호출 때 사용된다.

 

두번째 경우

입력값 = foo

이 경우 i의 값은 정의되지 않는다. foo는 다음 scanf에 맡겨지게 된다.

 

scanf의 작동 방식

프로그램은 유저가 입력한대로 입력값을 읽지 않는다.

입력 값은 scanf가 사용할 수 있는 숨겨진 버퍼에 저장이 되고, scanf는 다음에 계속해서 읽기 과정을 진행하기 위해 문자를 다시 이 버퍼에 미루는 것이 가능하다.

 

 

블로그의 정보

농담곰담곰이의곰담농

브이담곰

활동하기