스트림
스트림에는 입력 스트림, 출력 스트림 2가지가 존재한다. 이 스트림은 운영체제가 제공하는 소프트웨어로 구현되어있는 것으로 파일 스트림 혹은 모니터에 출력하는 출력 스트림 등이 있다.
먼저 문자 단위 입출력 함수를 보자.
- int putchar(int c);
- int fputc(int c, File * stream);
- 함수 호출 성공 시 쓰인 문자 정보 반환, 실패 시 EOF 반환.
여기서 신경 쓸 점은 fputc함수의 경우 파일을 문자를 전송할 스트림을 지정할 수 있다. 즉 파일을 대상으로도 데이터를 전송 가능하다.
다음으로 문자 입력 함수를 보자.
- int getchar(void);
- int fgetc(File * stream);
- 파일의 끝에 도달하거나 함수호출 실패 시 EOF 반환
키보드로부터 하나의 문자를 입력 받는 함수라 할 수 있다. fgetc 함수도 하나의 문자를 입력받지만 fputc함수와 마찬가지로 입력받을 스트림을 지정할 수 있다. 즉 파일을 대상으로 입력이 가능하다.
위의 함수들을 보면 함수호출 실패 시 EOF를 반환한다는 것을 알 수 있다. EOF란 End Of File의 약자로써 파일의 끝이라는 의미이다. 파일의 끝은 존재하지만 키보드의 끝은 어떻게 알 수 있을까? 바로 ctrl + Z이다.(윈도우 기준) 이를 다음의 예시로 알아보자.
<소스코드>
1
2
3
4
5
6
7
8
9
10
11
12
|
#include <stdio.h>
int main(void) {
int ch;
while (1) {
ch = getchar();
if (ch == EOF)
break;
putchar(ch);
}
return 0;
}
|
cs |
<실행결과>
이번에는 문자열 입출력 함수에 대해서 알아보자.
- int puts(const char *s);
- int fputs(const char* s, FILE * stream);
- 성공시 음수가 아닌 값, 실패 시 EOF 반환
puts 함수의 경우 호출되면 자동으로 개행이 되지만 fputs함수의 경우 자동으로 개행이 되지 않는다.
- char * gets(char *s);
- char * fgets(char *s, int n, FILE * stream);
- 파일의 끝에 도달하거나 함수호출 실패 시 NULL 포인터 반환
표준 입출력 & 버퍼
버퍼링을 하는 이유는 데이터 전송의 효율성 때문이다. 1층에서 3층까지 책을 옮긴다고 했을때 책을 한권씩 나르는것 보다 가방에 20권씩 담아서 나르는것이 더 효율적이라는 예시를 생각해보면 이를 쉽게 이햐할 수 있다.
출력버퍼를 비우는 fflush함수
int fflush(FILE * stream);
이 함수는 인자로 전달된 스트림의 버퍼를 비우는 기능을 제공한다.
그렇다면 입력버퍼를 비워야할 경우가 있을까? 이를 다음의 예시를 통해 알아보자.
<소스코드>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
#include <stdio.h>
int main(void) {
char perID[7];
char name[10];
fputs("주민번호 앞 6자리 입력: ", stdout);
fgets(perID, sizeof(perID), stdin);
fputs("이름 입력: ", stdout);
fgets(name, sizeof(name), stdin);
printf("주민번호: %s \n", perID);
printf("이름: %s \n", name);
return 0;
}
|
cs |
<실행결과>
왜 이런 결과가 나타났을까? 우선 주민등록번호를 보면 999999 총 7글자이다.(엔터 포함) 그런데 sizeof(perID)가 7이므로 문자열을 입력받기 위해 널문자를 제외하고 총 6글자를 읽어지는 것이다. 즉 개행 이 입력 버퍼에 남으므로 fgets함수까지 남는다. fgets는 \n을 읽으면 종료하므로 입력버퍼에 남은 \n 만 읽고 종료해버리는 것이다.따라서 위와 같은 경우를 방지하기 위해 입력 버퍼를 비워야 한다. 그러면 어떻게 해야 할까?
바로 함수를 정의하는 것이다. 이를 다음의 예시로 보자.
<소스코드>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#include <stdio.h>
void ClearLineFromReadBuffer(void) {
while (getchar() != '\n');
}
int main(void) {
char perID[7];
char name[10];
fputs("주민번호 앞 6자리 입력: ", stdout);
fgets(perID, sizeof(perID), stdin);
ClearLineFromReadBuffer();
fputs("이름 입력: ", stdout);
fgets(name, sizeof(name), stdin);
printf("주민번호: %s \n", perID);
printf("이름: %s \n", name);
return 0;
}
|
cs |
<실행결과>
입력 버퍼를 비우니 정상적으로 동작하는것을 알 수 있다.
그 외의 함수들
문자열 길이 반환하는 함수 : strlen
문자열 복사 함수 : strcpy, strncpy
문자열 덧붙이는 함수 : strcat, strncat
문자열 비교 함수 : strcmp, strncmp
문자열의 내용 int로 변환 : atoi
문자열의 내용을 long으로 변환 : atol
문자열의 내용을 double로 변환 : atof
'C' 카테고리의 다른 글
12. 구조체와 사용자 정의 자료형 2 (0) | 2021.06.27 |
---|---|
11. 구조체와 사용자 정의 자료형 (0) | 2021.06.27 |
9. 함수 포인터 & void 포인터 (0) | 2021.06.26 |
8. 2차원 배열과 포인터 (0) | 2021.06.26 |
7. 이중 포인터 (0) | 2021.06.25 |