CHAPTER 4 문자열과 형식 맞춘 입출력
"우리의 모든 꿈들은 이뤄질 수 있다. 우리에게 끝까지 밀어붙일 용기가 있다면." __월트 디즈니
4.1 문자열 입출력하기
scanf()
사용주의할 점
scanf()
를 통해 일반 변수에 입력값을 넣을 때와, 배열에 입력값을 넣을 때는 & 의 사용 여부에 차이가 있다. 배열은 그 자체가 첫번째 주소를 가리키고 있기 때문에 & 를 붙이지 않는다. (붙여도 상관은 없다.) 문자열이면 %s
를 쓴다.
char fruit_name;
scanf("%c", &fruit_name);
char fruit_name[40];
scanf("%s", fruit_name);
4.2 sizeof() 연산자
sizeof(int), sizeof(a) 같이 주로 사용하기 때문에 함수라고 생각하기 쉬우나, sizeof a 라고도 사용할 수 있는 등 사실상 연산자다.
sizeof()
는 기본적으로 unsigned int 자료형으로 반환하지만, 혹시나 다른 시스템에서 다른 자료형을 사용할 것을 우려해 size_t 라는 자료형을 반환 자료형으로 쓰기도 한다.(호환이식성 관련) size_t 의 형식 지정자
(format specifier || conversion specifier)
는 %zu 이다.
4.3 문자열이 메모리에 저장되는 구조
숫자의 배열과 달리, 문자의 배열은 배열의 마지막을 알리는 null character('\0') 이 마지막 한 칸의 메모리를 차지하고 있다. 즉, char str[10];
을 선언했을 때 그 문자열에는 최대 9개의 character + 1개의 null character 가 들어간다.
4.4 strlen() 함수
#include <string.h>
필요.- null character 를 제외한 문자열의 길이를 반환함.
- 얘도 null character 까지만 길이를 재기 때문에 중간에 null character 가 삽입되면 뒤쪽에 있는 건 세지 못함.
4.5 기호적 상수와 전처리기
기호적 상수는,
#define PI 3.141592f
같이#define
전처리기를 이용해서 정의할 수 있다.. PI 와 수치 사이에 = 이 없음에 주의하자! 전처리기는 컴파일 때 해당 심볼에 미리 정해진 수치를 대입하는 것이기에 = 3.141592f 가 대입되어 버리는 불상사가 발생할 수 있다.- 요즘은 굳이 전처리기를 쓰기보다
const float pi = 3.141592f;
같이const
를 써서 기호적 상수를 만드는 게 더 일반적이다.
4.6 명백한(대표적) 상수들 Manifest Constants
- 국내 번역서에 명단 상수 라고 오역된 경우가 있다.
- 꼭 알아두어야 할 중요한 개념까지는 아니다.
- 앞서 살펴본 기호적 상수를 포함해서 각종 매크로 등에 사용되는 명백하게 용도가 정해진 상수들을 Manifest Constants 라고 한다.
4.7 printf() 함수의 변환 지정자들 Conversion specifiers
변수, 상수, 표현식들이 들어갈 자리를 지정해놓는다.
-
사실 conversion 이라고 하기엔 '변환' 하는 게 딱히 대단치 않기 때문에 형식 지정자 (format specifier) 로 더 많이 통용된다. 하지만 공식 명칭은 conversion specifier다..
-
풀 형식은
%[flag][width][.precision][length]specifier
로 상당히 길다. ex)printf("%+10.5hi", 256);
그러나 보통은 자료형만 쓰고 만다. -
printf()
에서 % 기호를 입력하고 싶다면 %% 처럼 두 개를 연달아 써주면 된다. -
printf()
내의 문자열의 길이가 지나치게 길어져 다음줄로 넘기고 싶다면 '\' 를 쓰고 다음줄로 내려야 한다. -
해당 형식이 감당하지 못하는 건 overflow 나 underflow 가 발생함에 주의하자.
-
%f 는 사실상 float 이 아닌 double 을 위한 지정자다. %lf 같이 long float 을 써도 어차피 double 이기 때문에 l 이 무시된다. (scanf() 에서는 구별이 된다!)
-
%9d 로 9자리 출력, %.2f 로 소숫점 둘째자리까지만 출력 등 다양한 옵션을 줄 수 있다.
-
printf()
도return
값이 있다.printf()
를 변수에 저장한 후 해당 변수를 %u 형식 지정자와 함께 출력해보면 해당printf()
가 출력한 문자열의 길이를 출력한다. 변수에 저장한다고 해서 출력이 이루어지지 않는 게 아니라 일단 출력이 되고 그 길이만을 반환한다는 점에 유의!int n_printed = printf("Counting!"); printf("%u\n", n_printed); // 9 를 반환. ("Counting!" 의 길이.)
4.8 변환 지정자의 수식어들(modifiers)
출력할 때의 세세한 옵션 지정이 가능하다.%[flag][width][.precision][length]specifier
의 순서로 작성하는데, 대괄호는 구분을 위한 것이지 실제로 작성하지는 않는다.
flag
-
'-' 는 default 값인 오른쪽 정렬 대신 왼쪽 정렬해준다.
-
'+' 는 양수일 경우에도 + 를 출력해준다.
-
'#' 는 진수에 따른 표기법을 다 표시해준다.
-
0 은 width 가 정해져 있는 상태에서 빈 자리가 있을 때 빈칸 대신 0 으로 채워준다.
width
-
숫자만큼의 최소 표시 자리수를 만들어준다. 예를 들어 %5i 라고 쓸 경우 한자리 수라도 5자리만큼을 차지하여 출력한다.
-
'*' 은, 그 자리에 또다른 변수를 넣을 수 있는 자리를 만든다. 즉 이 출력 옵션을 위한 변수 자리다. ex: `printf("%*i\n", 7, 456); 가 printf("%7\n", 456); 로 변환됨.`
.precision
-
소수점 이하의 정밀 표시를 위한 자릿수를 설정한다. 출력 데이터의 소수점 아래 자릿수가 설정값보다 많은 경우 반올림되며, 부족한 경우 0으로 채운다.
-
위 width 와 같이 '*' 옵션이 있다.
-
. 을 쓰고 그 뒤에 아무 숫자도 쓰지 않으면 0 이 들어간 것이라고 해석된다.
-
%.5s 처럼 string 형식에 쓰일 경우 string 의 자릿수를 정해준다. 즉 %.5s 는 5자리까지만 출력한다.
length
- 데이터타입의 크기를 정한다. short, long, signed, unsigned 등과 관련있다.
4.9 print() 함수가 인자들을 해석하는 과정
4.10 scanf() 의 사용법
-
printf() 와 달리 '*' 는 그게 붙은 지정자를 무시하는 용도로 쓰인다. 입력은 받아야 되는데 무시됨.
-
printf() 와 달리 lf(double) 와 f 자료형이 구분된다.
-
'j' 는 int_max_t 또는 uintmax_t 자료형으로 해석된다. ex:
intmax_t i; scanf("%ji", i);
-
scanf("%i", &i);
에 숫자와 문자가 섞인 입력값을 넣으면, 숫자가 아닌 것을 만난 시점에서 입력이 중지된다. 즉 '123a456' 을 입력하면 123 까지만 입력받는다. -
여러 변수를 위한 값을 입력받을 때, 기본설정인 빈칸이나 줄바꿈 대신 다른 것으로 입력값을 구분하고 싶다면 형식 지정자 사이에 원하는 것을 써넣으면 된다. ex:
scanf("%d,%d", &a, &b); // 쉼표(,) 를 기준으로 나누어져 입력됨.
-
scanf()
의 반환값은 입력받은 변수의 개수이다.
'개발공부(C, C++)' 카테고리의 다른 글
따배씨(따라 배우는 C언어_홍정모) Chapter6 (0) | 2019.12.25 |
---|---|
따배씨(따라 배우는 C언어_홍정모) Chapter5 (0) | 2019.12.25 |
따배씨(따라 배우는 C언어_홍정모) Chapter3 (0) | 2019.12.25 |
따배씨(따라 배우는 C언어_홍정모) Chapter2 (0) | 2019.12.25 |
따배씨(따라 배우는 C언어_홍정모) Chapter0 (0) | 2019.12.25 |