입력의 출처는 어디?
int c;
c = getchar();
while(c != EOF){
putchar(c);
c = getchar();
}
ctrl + z
, 유닉스(리눅스) ctrl + d
)getchar()
int getchar(void)
int
형 char
형은 부호가 있을 수도 있고 없을 수도 있기 때문에 int
형을 반환해야만 한다.하나씩 읽는 것 보다 한 줄씩 읽는 게 빠름
한 데이터씩 읽어오는 것과 같이 사용하면 유용하다. (안전하게 사용가능)
한 줄을 읽어오면 저장할 공간을 함수가 할당해주지 않는다.
gets()
char* gets(char* str);
콘솔에서 \n
또는 EOF
를 만날 때까지 계속 문자들을 읽어서 str 배열에 저장 (개행문자는 저장안함 대신 \0
저장)
마지막 문자 뒤에 \0
문자 넣어줌
성공시, str
실패시 NULL 포인터
매우 위험한 함수, 그냥 사용안하면 됨 (C11 부터 사라짐)
위험한 이유는 버퍼 사이즈 이상의 입력이 들어오면 버퍼오버플로우 발생, 이를 통제할 방법이 없다.
버퍼오버플로우
stdin --> str (stdin사이즈가 더 크면 str 뒤쪽메모리까지...)
버퍼로 잡아놓은 사이즈를 초과해서 다른 메모리를 키보드 입력으로 덮어씌워버린다.
함수 내부에 다른 용도로 잡아놓은 메모리주소(매개변수, 돌아갈 함수 주소, 베이스 포인터)에 값이 변경되어 버릴수 있다!
이를 악용한 보안 공격도 가능(버퍼오버플로우 어택)
fgets()
char* fgets(char* str, int count, FILE* stream);
stdin
을 스트림에 넣어주면됨.#define LINE_LENGTH(10);
char line[LENGTH];
while(fgets(line, LINE_LENGTH, stdin) != NULL){
printf("%s", line);
}
콘솔 입력으로부터 읽음
int scanf(const char* format ...)
파일 스트림으로부터 읽음
int fscanf(FILE* stream, const char* format ...)
C스타일 문자열로부터 읽음
int sscanf(const char* buffer, const char* format ...)
scanf()
fgets()와 sscanf()를 같이 사용하면 좋다.
#define LINE_LEGNTH(1024);
int sum = 0;
int num;
char line[LINE_LENGTH];
while(TRUE){
if(fgets(line, LINE_LENGTH, stdin) == NULL){
clearerr(stdin);
break;
}
if (sscanf(line, "%d", &num) == 1){
sum += num;
}
}
이진 데이터를 읽는 방법
size_t fread(void* buffer, size_t size, size_t count, FILE* stream);
size
바이트짜리 데이터를 총 count
개수만큼 읽어서 buffer
에 저장
EOF
를 만나면 멈춤
int nums[64];
size_t num_read;
FILE* fstream; // 파일 스트림
num_read = fread(nums, sizeof(nums[0]), 64, fstream);
fwrite(nums, sizeof(nums[0]), 64, fstream);
파일입출력
C언어에서 파일다루기
파일열기
FILE* fopen(const char* filename, const char* mode);
파일을 열고 꼭 닫아줘야한다.
파일열기에 실패하면 리턴값은 NULL포인터
파일닫기
int fclose(FILE* stream);
모든 프로그램은 실행될 때 3개의 스트림이 생성된다. (stdin
stdout
stderr
)
키보드 입력을 파일에서, 콘솔 출력을 파일로 (소스변경없이, fopen이런거 없이!)
C언어의 기능이 아니라 커맨드라인, shell의 기능
파일을 다 읽으면 EOF가 자동으로 추가
리디렉션 != fopen()
> a.exe < input.txt > output.txt 2> error.txt
stdin : <
사용( input.txt에 있는 데이터를 키보드입력처럼 사용하기 )
stdout : >
사용 (콘솔출력을 output.txt에 기록하기)
stderr : 2>
사용 (콘솔출력을 error.txt에 기록하기)