본문 바로가기
c언어

c언어 텍스트 파일 읽는 법과 쓰는 법 알아보기

by 개발자 L 2023. 2. 16.
반응형

c언어 텍스트 파일 읽는 법과 쓰는 법 알아보기

네 안녕하세요, 이번 포스팅에서는 텍스트 파일 읽기와 쓰기에 대하여 알아보도록 하겠습니다.

우리가 일단 텍스트 파일을 열었다면 무언가를 작성을 해야 하죠?
그래서 이번에는 그러한 것을 어떻게 하는지 알려드리도록 하겠습니다.

 

1. 파일 입출력 함수

일단 우리가 텍스트 파일을 열었다면 글을 쓰고 그걸 출력해야 합니다.

그래서 그 때 쓰는 함수들이 존재합니다.

아래 보이는 표에 정리를 해뒀습니다.

종류 입력 함수 출력 함수
문자 단위 int fgetc(FILE *fp) int fputc(int c, FILE *fp)
문자열 단위 char *fgets(char *buf, int n, FILE *fp) int fputs(const char *buf, FILE *fp)
서식화된 입출력 int fscanf(FILE *fp, ...) int fprintf(FILE *fp, ...)
이진 데이터 size_t, fread(char *buffer, int size, int count, FILE *fp) size_t, fwrite(char buffer, int size, int count, FILE *fp)

이러한 것들이 있습니다.

그럼 각각에 대하여 간단히 알아보도록 하겠습니다.

 

1 - 1. 문자 단위, 문자열 단위 입출력 함수의 특징

문자 단위와 문자열 단위 입출력은 입출력의 단위가 문자 또는 문자열입니다.

보통 이들은 텍스트 형태로 데이터를 저장하며, 일반적으로 성공적으로 읽은 항목의 개수를 반환을 합니다.

그래서 반환이 되는 값이 0이라면 입출력을 하는 데 실패했다는 것을 의미합니다.

보통 에러가 나는 경우는 말 그대로 파일 입출력을 하는 과정에서 에러가 났다던가,

파일이 끝났을 수 있습니다.

그래서 그러한 오류들을 자세히 알기 위해서 feof(), 또는 ferror() 함수를 호출하여 디버깅을 합니다.

 

1 - 2. 서식화된 입출력 함수의 특징

서식화가 되어있는 입출력을 할 때는 fprinf()나 fscanf() 함수를 사용합니다.

예를 드어서 정수를 텍스트로 변환하여 저장한다던지,

그 반대의 경우일 때 쓰며, 텍스트 파일에서 사용을 합니다.

이진 데이터 관련 함수는 이진 파일을 다룰 때 좀 더 자세히 알아보도록 하겠습니다.

 

2. 문자 단위 입출력 해보기

이번에는 직접 문자 단위 입출력 함수를 써서 직접 텍스트 파일에 무언가 작성을 해보도록 하겠습니다.

제일 먼저 써 볼 함수는 fputc() 함수입니다.

#include <stdio.h>

int main()
{
    FILE *fp = NULL;
    fp = fopen("sample.txt", "w");

    if(fp == NULL)
    {
        printf("파일 열기 실패\n");
    }

    else
    {
        printf("파일 열기 성공\n");
    }

    fputc('a', fp);
    fputc('b', fp);
    fputc('c', fp);

    fclose(fp);

    return 0;
}

이렇게 작성을 했습니다.

그럼 결과를 보도록 하겠습니다.

파일 열기 성공

우선 파일 열기를 성공했습니다.

그럼 제가 생성한 txt 파일에 무엇이 적혀있나 보도록 하겠습니다.

이렇게 abc라고 잘 적혀있는 걸 볼 수 있습니다.

그러면 이어서 fgetc() 함수를 써서 파일 처리를 해보도록 하겠습니다.

#include <stdio.h>

int main()
{
    FILE *fp = NULL;
    int c;

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

    if(fp == NULL)
    {
        printf("파일 열기 실패\n");
    }

    else
    {
        printf("파일 열기 성공\n");
    }

    while((c = fgetc(fp)) != EOF)
    {
        putchar(c);
    }

    fclose(fp);

    printf("\n");

    return 0;
}

이렇게 작성을 해봤습니다.

그럼 이제 출력 결과가 어떻게 되어있는지 확인해 보도록 하겠습니다.

파일 열기 성공
abc

이번에는 내용물까지 한 번에 터미널에서 출력이 된 것을 확인할 수 있습니다.

반응형

 

3. 문자열 단위 입출력 해보기

이번에는 문자열 단위로 입출력을 직접 해보도록 하겠습니다.

문자열 입출력 함수를 이용해서 텍스트 파일을 복사해 보도록 하겠습니다.

복사를 할 때는 fgets() 함수와 fputs() 함수를 이용할 것입니다.

그리고 여기서 문자열 입출력 함수를 사용하기 때문에 텍스트 파일만 복사가 됩니다.

#include <stdio.h>
#include <stdlib.h>

int main()
{
    FILE *fp1, *fp2;
    char file1[100], file2[100];
    char buffer[100];

    printf("원본 파일 이름 : ");
    scanf("%s", file1);

    printf("복사 파일 이름 : ");
    scanf("%s", file2);

    // 첫 번째 파일을 읽기 모드로 오픈
    if((fp1 = fopen(file1, "r")) == NULL)
    {
        fprintf(stderr, "원본 파일 %s 를 열 수 없습니다.\n", file1);

        exit(1);
    }

    // 두 번째 파일을 쓰기 모드로 오픈
    if((fp2 = fopen(file2, "w")) == NULL)
    {
        fprintf(stderr, "복사 파일 %s 를 열 수 없습니다.\n", file2);

        exit(1);
    }

    while(fgets(buffer, 100, fp1) != NULL)
    {
        fputs(buffer, fp2);
    }

    fclose(fp1);
    fclose(fp2);

    return 0;
}

이렇게 한 번 작성을 해봤습니다.

그럼 결과는 어떻게 나왔는지 보도록 하겠습니다.

원본 파일 이름 : a.txt
복사 파일 이름 : b.txt

이렇게 터미널에서 복사가 된 것을 확인했습니다.

그럼 파일도 실제로 복사가 되었는지 보도록 하겠습니다.

이렇게 텍스트 파일이 잘 복사된 것을 볼 수 있습니다.

그리고 여기서 주의를 하셔야 할 사항은 원본 파일이 일단 존재해야 복사를 할 수 있습니다.

원본 파일이 존재하지 않으면 처리 시 에러가 나니까 주의하셔야 합니다.

 

4. 형식화된 입출력 하기

이번에는 형식화된 입출력을 해보도록 하겠습니다.

이를테면 일반적인 텍스트 처리가 아니라 텍스트를 정수형으로 바꾼다거나,

그 반대의 경우에 쓰는 방법입니다.

이를테면 이런 것이죠.

정수 10은 화면에 문자열 10으로 출력이 되죠?
그렇듯이 파일에도 문자열 10으로 저장을 시킵니다.

이런 식으로 개발자가 특정 형식을 지정해서 입출력하는 것을 형식화된 입출력을 처리한다고 합니다.

그럼 바로 보여드리도록 하겠습니다.

#include <stdio.h>
#include <stdlib.h>

int main()
{
    FILE *fp;
    char fname[100];
    int number, count = 0;
    char name[20];
    float score, total = 0.0;

    printf("성적 파일 이름을 입력하세요 : ");
    scanf("%s", fname);

    // 성적 파일 쓰기 모드로 오픈
    if((fp = fopen(fname, "w")) == NULL)
    {
        fprintf(stderr, "성적 파일 %s 를 열 수 없습니다.\n", fname);

        exit(1);
    }

    while(1)
    {
        printf("학번, 이름, 성적을 입력하세요 : (음수이면 종료)");
        scanf("%d", &number);

        if(number < 0)
        {
            break;
        }

        scanf("%s %f", name, &score);

        fprintf(fp, "%d %s %f", number, name, score);
    }

    fclose(fp);

    // 성적 파일을 읽기 모드로 오픈
    if((fp = fopen(fname, "r")) == NULL)
    {
        fprintf(stderr, "성적 파일 %s 를 열 수 없습니다.\n", fname);

        exit(1);
    }

    while(!feof(fp))
    {
        fscanf(fp, "%d %s %f", &number, name, &score);

        total += score;
        count++;
    }

    printf("평균은 %f 입니다.\n", total/count);

    fclose(fp);

    return 0;
}

이렇게 작성을 해봤고, 이제 결과를 보여드리도록 하겠습니다.

성적 파일 이름을 입력하세요 : scores.txt
학번, 이름, 성적을 입력하세요 : (음수이면 종료)1 KIM 10.0
학번, 이름, 성적을 입력하세요 : (음수이면 종료)2 PARK 20.0
학번, 이름, 성적을 입력하세요 : (음수이면 종료)3 LEE 30.0
학번, 이름, 성적을 입력하세요 : (음수이면 종료)-1
평균은 20.000000 입니다.

이렇게 쓰기 모드가 종료가 되고, 읽기 모드로 다시 열린 후에 계산이 된 평균값이 출력이 된 것을 볼 수 있습니다.

 

여기까지 텍스트 파일을 읽고 쓰는 법에 대하여 알아보았는데요,

다음 포스팅에서는 이진 파일을 읽고 쓰는 법에 대하여 알아보도록 하겠습니다.

긴 글 읽어주신 독자분들께 진심으로 감사드립니다~

반응형

댓글