본문 바로가기
개념/혼자 공부하는 C언어

chapter 18) 버퍼를 공유함으로 인해 발생하는 문제

by kiseno 2024. 10. 11.
728x90
반응형
SMALL
#include <stdio.h>

int main(void){
    FILE *fp;
    int age;
    char name[20];

    fp = fopen("a.txt", "r");

    fscanf(fp, "%d", &age);
    fgets(name, sizeof(name), fp); // 오류 발생

    printf("age : %d, name : %s", age, name);
    fclose(fp);

    return 0;
}

### 파일 열기

- `FILE *fp;`는 파일 포인터 `fp`를 선언합니다. 이 포인터는 파일을 다루는 데 사용됩니다.
- `fp = fopen("a.txt", "r");`를 통해 "a.txt" 파일을 읽기 모드로 엽니다. 파일이 성공적으로 열리면 `fp`는 열린 파일을 가리키게 됩니다.

### 파일로부터 데이터 읽기

- `fscanf(fp, "%d", &age);`는 파일에서 정수 형태의 데이터를 읽어서 `age` 변수에 저장합니다. 이때, 읽히는 데이터는 나이를 나타냅니다.
- `fgets(name, sizeof(name), fp);`는 파일에서 문자열을 읽어서 `name` 배열에 저장합니다. `fgets` 함수는 `sizeof(name)` 길이만큼 또는 줄 바꿈 문자를 만날 때까지 데이터를 읽습니다. 이때, `fscanf`로 데이터를 읽고 남은 개행 문자(`\n`)로 인해 예상치 못한 동작이 발생할 수 있습니다.

### 데이터 출력

- `printf("age : %d, name : %s", age, name);`는 읽은 나이와 이름을 출력합니다.

### 파일 닫기

- `fclose(fp);`는 열린 파일을 닫습니다. 파일을 사용한 후에는 반드시 닫아주어야 합니다.

### 문제점과 해결

문제는 `fscanf` 후 남은 개행 문자가 `fgets`의 동작에 영향을 준다는 점입니다. `fscanf`로 나이를 읽은 후, 파일 포인터는 개행 문자 바로 앞에 위치하게 됩니다. `fgets`가 호출될 때, 바로 개행 문자를 만나면서 빈 문자열을 `name`에 저장하고 반환합니다. 이를 해결하기 위해 `fscanf` 사용 후 남은 개행 문자를 처리해주거나, 파일 읽기 방식을 조정할 필요가 있습니다.

 

#include <stdio.h>

int main(void){
    FILE *fp;
    int age;
    char name[20];

    fp = fopen("a.txt", "r");
    if (fp == NULL) {
        printf("File cannot be opened.\n");
        return 1;
    }

    fscanf(fp, "%d ", &age); // 나이 읽기 후 공백 문자를 포함해 개행 문자까지 읽도록 함

    // 이름 읽기 전에 남은 개행 문자를 소비할 필요가 없어짐
    fgets(name, sizeof(name), fp); // 이제 정상적으로 이름을 읽을 수 있음

    printf("age : %d, name : %s", age, name);
    fclose(fp);

    return 0;
}


이 코드는 파일 입출력을 다루는 기본적인 방법을 보여주며, 특히 파일로부터 데이터를 읽는 방법에 초점을 맞춥니다. 파일에서 데이터를 읽고, 그 데이터를 가공하여 사용하는 프로그램을 작성할 때 유용한 패턴입니다.

728x90
반응형
LIST