70.2 서식을 지정하여 파일에서 문자열 읽기

이제 앞에서 생성한 hello.txt 파일의 내용을 읽어보겠습니다. 파일을 읽을 때도 fopen 함수로 파일을 열어서 파일 포인터를 얻은 뒤 fscanf 함수로 서식을 지정하여 파일의 내용을 읽습니다(stdio.h 헤더 파일에 선언되어 있습니다).

  • fscanf(파일포인터, 서식, 변수의주소1, 변수의주소2, …);
    • int fscanf(FILE * const _Stream, char const * const _Format, ...);
    • 성공하면 읽어온 값의 개수를 반환, 실패하면 EOF(-1)를 반환

다음 내용을 소스 코드 편집 창에 입력한 뒤 Ctrl+F5 키를 눌러서 실행해보세요.

file_read_format.c

#define _CRT_SECURE_NO_WARNINGS    // fopen 보안 경고로 인한 컴파일 에러 방지
#include <stdio.h>     // fopen, fscanf, fclose 함수가 선언된 헤더 파일

int main()
{
    char s1[10];
    int num1;

    FILE *fp = fopen("hello.txt", "r");    // hello.txt 파일을 읽기 모드(r)로 열기.
                                           // 파일 포인터를 반환

    fscanf(fp, "%s %d", s1, &num1);   // 서식을 지정하여 파일에서 문자열 읽기

    printf("%s %d\n", s1, num1);      // Hello 100: 파일에서 읽은 값을 출력

    fclose(fp);    // 파일 포인터 닫기

    return 0;
}

실행 결과

Hello 100

먼저 fopen 함수를 사용하여 hello.txt 파일을 읽기 모드(r)로 엽니다.

FILE *fp = fopen("hello.txt", "r");    // hello.txt 파일을 읽기 모드(r)로 열기.
                                       // 파일 포인터를 반환

fscanf 함수는 파일 포인터를 넣는다는 점 말고는 scanf 함수와 사용법이 같습니다. 즉, 파일에서 문자열을 읽은 뒤 서식에 맞추어서 값을 변수에 저장합니다. 여기서는 서식을 "%s %d"로 지정했으므로 "Hello" 부분은 문자 배열 s1에 저장되고, 100 부분은 정수형 변수 num1에 저장됩니다.

fscanf(fp, "%s %d", s1, &num1);    // 서식을 지정하여 파일에서 문자열 읽기

printf로 s1과 num1의 값을 출력해보면 "Hello"와 100이 나옵니다.

printf("%s %d\n", s1, num1);       // Hello 100: 파일에서 읽은 값을 출력

마찬가지로 파일 읽기 작업이 끝났다면 fclose 함수로 파일 포인터를 닫아줍니다.

fclose(fp);   // 파일 포인터 닫기

서식을 지정하여 파일에서 문자열을 읽는 과정을 그림으로 나타내면 다음과 같습니다.

▼ 그림 70‑2 서식을 지정하여 파일에서 문자열 읽기

fprintf 함수는 stdout 매크로를 활용해서 화면에 문자열을 출력했는데 fscanf도 비슷한 사용 방법이 있지 않을까요? fscanf 함수는 stdin 매크로를 활용하면 사용자가 입력한 값을 변수에 저장할 수 있습니다.

char s1[10];
int num1;
fscanf(stdin, "%s %d", s1, &num1);    // 서식을 지정하여 표준 입력(stdin)에서 문자열 읽기

즉, fscanf(stdin, ...);은 scanf 함수와 동작이 같습니다.

참고 | 파일 스트림

fprintf, fscanf 등의 함수의 매개변수에서 파일 포인터 부분을 보면 FILE* const _Stream와 같이 스트림(stream)이라고 되어 있습니다. 보통 파일 포인터를 파일 스트림이라고도 하는데 스트림은 물 등의 액체가 흐르는 것을 뜻합니다. 파이프 속에 물이 계속 흘러다니는 것처럼 파일 스트림도 파일의 데이터를 연속적으로 처리한다고 해서 스트림입니다.

즉, 파일에서 데이터를 처리할 때마다 매번 파일을 여는 것이 아니라 파일 스트림을 한 번 생성해서 계속 데이터를 쓰거나 가져오는 방식이죠. 여기서 fopen으로 파일을 읽기 전용으로 열면 입력 스트림, 쓰기 전용으로 열면 출력 스트림, 읽기/쓰기로 열면 입출력 스트림입니다. 파일 모드에 따라 단방향, 양방향이 되죠. 마찬가지로 stdin은 입력 스트림, stdout, stderr는 출력 스트림입니다.