printf 함수와 scanf 함수를 이용해도 문자열의 입출력이 가능하다.
하지만, scanf 함수는 공백이 포함된 형태의 문자열을 입력 받는데 제한이 있지 않았나.
이번에 소개하는 문자열의 입력 함수는 공백을 포함하는 문자열도 입력 가능하다.
문자열 출력 함수 : puts, fputs
#include <stdio.h>
int puts(const char * s);
int fputs(const char * s, FILE * stream);
성공 시 0이 아닌 값을, 실패 시 EOF 반환
puts 함수는 출력의 대상이 stdout으로 결정되어 있지만, fputs 함수는 두 번째 인자를 통해서 출력의 대상을 결정할 수 있음.
둘의 출력의 형태 차이는 예제를 통해 확인
#include <stdio.h>
int main(void)
{
char* str = "simple string";
printf("1. puts test ----- \n");
puts(str);
puts("So simple string");
printf("2. fputs test ----- \n");
fputs(str, stdout); printf("\n");
fputs("So simple string", stdout); printf("\n");
printf("3. end of main ---- \n");
return 0;
}
"puts 함수가 호출되면 문자열 출력 후 자동으로 개행이 이뤄지지만, fputs 함수가 호출되면 문자열 출력 후 자동으로 개행이 이뤄지지 않는다."
문자열 입력 함수 : gets, fgets
#include <stdio.h>
int* gets(char * s);
int* fgets(const char * s, int n, FILE * stream);
파일의 끝에 도달하거나 함수호출 실패 시 NULL 포인터 반환
gets 함수는 다음의 유형으로 호출
int main(void)
{
char str[7]; // 7바이트의 메모리 공간 할당
gets(str); // 입력 받은 문자열을 배열 str에 저장
}
키보드로부터 문자열을 입력 받게 되니, 확실히 문장구성을 간단하다.
하지만, 미리 마련해 놓은 배열을 넘어서는 길이의 문자열이 입력되면, 할당 받지 않은 메모리 공간을 침범하여 실행 중 오류가 발생한다는 단점이 있음.
그래서 가급적이면 다음의 형태로 fgets 함수를 호출
int main(void)
{
char str[7]; // 7바이트의 메모리 공간 할당
fgets(str, sizeof(str), stdin); // stdin으로부터 문자열 입력 받아서 str에 저장
}
fgets의 의미
"stdin으로부터 문자열을 입력 받아서 배열 str에 저장하되 sizeof(str)의 길이만큼만 저장해라"
문자열을 입력 받으면 문자열의 끝에 자동으로 NULL 문자가 추가된다.
따라서 하나가 작은 길이의 문자열이 저장.
fgets 예제
#include <stdio.h>
int main(void)
{
char str[7]; // 공간 할당
for (int i = 0; i < 3; i++)
{
fgets(str, sizeof(str), stdin);
printf("Read %d : %s \n", i + 1, str);
}
}
fgets 함수를 총 3회 호출
입력한 문자열의 길이가 배열의 길이를 넘어서다 보니, fgets 함수는 7보다 작은 6의 길이만큼 문자열을 읽어 들이고 있음
따라서 프로그램 사용자는 딱 한번 입력하였지만 fgets 함수는 총 3회 호출.
전체 문자열을 읽어 들이지 못하는 상황
만약에 fgets 함수를 총 4회 호출하거나 배열의 길이를 늘린다면 모두 읽을 수 있음
위를 보면 printf 함수 호출문에 개행을 의미하는 \n이 하나 삽입되어 있다.
그런데 위 결과를 보면 문장이 출력될 때마다 개행이 두 번 이뤄졌음을 알 수 있다. 이유는?
fgets 함수는 \n을 만날 때까지 문자열을 읽어 들이는데, \n을 제외시키거나 버리지 않고 문자열의 일부로 받아 들인다. 쉽게 말해서 내가 입력 한 엔터 키의 정보까지도 문자열의 일부로 저장되는 것이다.
그래서 printf 함수호출 시 문자열의 일부였던 \n에 의해서 한번,
printf 함수 호출 문에 삽입된 \n에 의해서 또 한번 개행이 이뤄지는 것.
마지막으로 공백을 포함하는 형태의 문자열을 입력 하는 방식 -> scanf 불가능
참고 : [윤성우 열혈 C 프로그래밍] - 대부분의 내용 및 코드는 이 책에서 개인 공부 정리 목적으로 참고하였습니다.
'Language&Framework&Etc > C' 카테고리의 다른 글
문자와 문자열 관련 함수(21-5) 입출력 이외의 문자열 관련 함수 (0) | 2020.12.11 |
---|---|
문자와 문자열 관련 함수(21-4) 표준 입출력과 버퍼 (0) | 2020.12.11 |
문자와 문자열 관련 함수(21-2) 문자 단위 입출력 함수 (0) | 2020.12.10 |
문자와 문자열 관련 함수(21-1) 스트림과 데이터의 이동 (0) | 2020.12.10 |
함수 포인터와 void 포인터(19-2) main 함수로의 인자 전달 (0) | 2020.12.10 |