86. 문자열 입출력 함수
1. 키워드
2. 문자열 입출력 함수 사용하기
stdio.h
헤더 파일에는 scanf
, printf
, fgets
, fputs
함수 이외에도 문자열 입출력 함수 gets_s
, puts
, fgetc
, putc
가 있다.
gets_s(버퍼, 버퍼크기);
성공하면 입력된 문자열을 반환, 실패하면 NULL을 반환
puts(문자열)
성공하면 음수가 아닌 값을 반환, 실패하면 EOF(-1)를 반환
#include <stdio.h>
int main()
{
char buffer[100];
gets_s(buffer, sizeof(buffer)); // 표준 입력에서 문자열을 입력받음
puts(buffer); // 문자열을 화면(표준 출력)에 출력
return 0;
}
// Hello (입력)
// Hello
gets_s
함수는 표준 입력에서 문자열을 입력받아서 배열이나 포인터에 저장한다.
- 엔터 키를 누르면 입력이 끝나며 개행 문자
\n
은 저장되지 않는다.
- 첫 번째 인수에는 버퍼로 사용할 배열이나 포인터를 넣어주고, 두 번째 인수에는 버퍼의 크기(배열의 크기, 포인터에 할당받은 메모리의 크기)를 넣어주면 된다.
puts
함수는 배열(포인터)에 들어있는 문자열을 화면에 출력한다.
- 여기서
gets_s
함수를 사용하는 이유는 gets
함수가 보안에 취약했기 때문이다.
- 즉, 다음과 같이
gets
함수는 버퍼만 넣어주면 끝이라서 버퍼의 크기를 넘어서는 입력도 받을 수가 있었다.
- 그러다 보니 지속적으로 버퍼 오버플로우 공격에 시달렸고, 결국 C99 표준에서는
gets
함수가 표준 라이브러리에서 삭제되어 버린다.
char buffer[100];
gets(buffer); // gets 함수는 버퍼만 넣어줌
- C11 표준(C99 이후에 나온 최신 C 표준)부터는 버퍼의 크기를 설정하는
gets_s
함수가 추가되었고 Visual Studio 2015에서도 gets_s
함수를 제공한다.
- GCC, Clang에서는 아직
gets
함수를 사용할 수는 있지만 위험하다는 경고를 출력하고 있으므로 가급적이면 사용하지 않는 것이 좋다.
- 문자열을 입력받을 때는
scanf
함수나 fgets
함수 사용을 권장한다.
fgetc
, fputc
함수는 파일에 문자를 읽고 쓴다.
fgetc(파일포인터);
성공하면 읽은 문자를 반환, 실패하면 EOF(-1)를 반환
fputc(문자, 파일포인터);
성공하면 쓴 문자를 반환, 실패하면 EOF(-1)를 반환
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
char buffer[100] = {
0,
};
int c1 = 0;
FILE *fp = fopen("hello.txt", "w+"); // 파일을 읽기/쓰기 모드로 열기
for (int i = 0; i < 10; i++) // 10번 반복하면서
fputc('a', fp); // 파일에 문자 a를 쓰기
rewind(fp); // 파일 포인터를 파일의 처음으로 이동시킴
while (1)
{
c1 = fgetc(fp); // 파일에서 문자를 읽음
if (feof(fp)) // 파일 포인터가 파일의 끝에 있으면
break; // 반복을 끝냄
putchar(c1); // 문자 출력
}
fclose(fp);
return 0;
}
// aaaaaaaaaa
fputc
함수는 파일에 문자 하나를 쓰고, 파일 포인터를 순방향으로 이동시킨다.
- 그리고
fgetc
함수는 파일에서 문자 하나를 읽어서 반환하고, 파일 포인터를 순방향으로 이동시킨다.
- 여기서는 무한 루프로 반복하면서
fgetc
로 문자를 계속 읽다가 feof
로 파일의 끝을 확인한 뒤 반복을 종료하도록 만들었다.
References