HOWTO · C
C에서 fscanf를 사용하여 한 줄씩 파일 읽기
이 기사는 C에서 fscanf를 사용하여 한 줄씩 파일을 읽는 방법을 보여줍니다.
이 페이지의 내용
fscanf는 FILE 스트림에서 형식에 맞는 입력을 읽습니다. scanset을 사용하면 줄바꿈 전까지 문자를 모을 수 있지만, 전용 줄 읽기 함수와 달리 빈 줄과 버퍼 크기에 맞춘 청크를 명시적으로 처리해야 합니다. 일반 텍스트 파일에서는 보통 fgets가 더 간단합니다. 입력 형식에 맞춰 변환해야 할 때 fscanf를 사용하세요.
C에서 fscanf로 파일을 한 줄씩 읽기
이 전체 예제는 임시 파일을 만들고 샘플 줄 두 개를 쓴 다음, 16바이트 대상 버퍼에 맞춰 제한한 scanset으로 스트림을 읽습니다. 프로그램은 임시 스트림에 샘플 줄 두 개를 쓰고, 읽으면서 출력합니다. 코드와 출력 블록에 표시되는 문자열은 원문 그대로 영어입니다.
#include <stdio.h>
int main(void) {
FILE *file = tmpfile();
char line[16];
if (file == NULL) {
return 1;
}
if (fputs("First line.\nSecond line.\n", file) == EOF || ferror(file)) {
fclose(file);
return 1;
}
if (fflush(file) == EOF || ferror(file)) {
fclose(file);
return 1;
}
rewind(file);
for (;;) {
int result = fscanf(file, "%15[^\n]", line);
if (result == 1) {
int ch;
puts(line);
ch = fgetc(file);
if (ch == '\n') {
continue;
}
if (ch == EOF) {
break;
}
ungetc(ch, file);
while ((ch = fgetc(file)) != '\n' && ch != EOF) {
}
if (ch == EOF) {
break;
}
continue;
}
if (result == EOF) {
break;
}
if (fgetc(file) == '\n') {
puts("");
}
}
fclose(file);
return 0;
}
너비를 15로 지정하면 line에서 끝의 널 문자가 들어갈 공간이 남습니다. scanset 변환이 성공할 때마다 프로그램은 줄바꿈 문자를 확인합니다. 한 줄이 버퍼보다 길면 다음 줄을 읽기 전에 나머지 부분을 버립니다. 이렇게 하면 메모리 사용량은 제한되지만 긴 줄 전체를 보존하지는 않습니다. 줄바꿈 위치에서 scanset이 문자를 하나도 읽지 못하면 루프는 줄바꿈 문자를 소비하고, 진행 없이 다시 시도하는 대신 빈 줄을 출력합니다. 실제 코드에서는 입력이 끝난 뒤 ferror(file)도 확인해야 읽기 오류와 정상적인 파일 끝을 구분할 수 있습니다.
fscanf로 공백으로 구분된 토큰 읽기
토큰을 읽을 때 %255s는 공백이 아닌 토큰 하나를 char token[256] 버퍼에 저장합니다. 너비를 지정해 배열 범위를 넘겨 쓰지 않도록 하며, %s는 앞쪽 공백을 건너뛰고 다음 공백 문자에서 멈춥니다. 반복문은 fscanf(file, "%255s", token) == 1인 동안에만 계속해야 합니다. 입력을 소비하지 않은 채 변환에 실패할 수 있으므로 EOF 여부만 확인하면 반복문이 끝없이 반복될 수 있습니다. 이 방식에서는 공백, 탭, 줄바꿈이 모두 구분자로 처리되므로 원래 줄 경계는 보존되지 않습니다. 숫자 필드에는 알맞은 변환 지정자를 사용하고 성공적으로 대입된 항목의 수도 확인하세요.
안정적으로 한 줄씩 읽으려면 fgets 사용
각 레코드가 한 줄인 텍스트를 읽을 때는 일반적으로 fgets(buffer, sizeof buffer, file)가 동작을 파악하기 쉽습니다. 버퍼 용량보다 최대 한 글자 적게 읽으며, 들어갈 공간이 있으면 줄바꿈 문자도 버퍼에 남깁니다. 버퍼를 사용하기 전에 반환값을 확인하세요. 줄바꿈 문자 없이 버퍼가 가득 차면 논리적으로 같은 줄의 나머지 부분이 스트림에 남아 있습니다. 작업에 따라 추가 청크를 읽거나 나머지를 버리면 됩니다. 마지막 줄은 줄바꿈 문자 없이 파일 끝에서 끝날 수 있습니다. 빈 줄은 줄바꿈 문자만 든 버퍼로 반환될 수 있어 자연스럽게 처리됩니다.
형식이 지정된 필드나 공백으로 구분된 토큰이 필요하면 fscanf를 선택하세요. 줄 경계를 보존해야 한다면 fgets로 읽고, 필요에 따라 얻은 문자열을 별도로 파싱하세요. fopen의 성공 여부와 변환 결과를 확인하고, 사용한 뒤에는 스트림을 닫으세요.