C 파일 I/O: 파일 생성, 열기, 읽기, 쓰기 및 닫기

⚡ 스마트 요약

C 언어에서 파일 처리는 stdio 라이브러리를 통해 디스크에 영구적인 데이터를 저장합니다. stdio 라이브러리는 fopen으로 파일을 열고, fputc, fputs 또는 fprintf로 파일을 쓰고, fgetc, fgets 또는 fscanf로 파일을 읽고, fclose를 사용하여 파일을 닫습니다.

  • 📁 파일 모드: fopen 함수에 전달되는 모드 문자열(r, w, a, r+, w+, a+)은 파일을 읽을지, 덮어쓸지, 추가할지를 결정합니다.
  • 데이터 쓰기: fputc는 한 문자를 쓰고, fputs는 문자열을 쓰고, fprintf는 형식화된 텍스트를 파일 포인터에 씁니다.
  • ???? 데이터 읽기: fgetc는 문자를 읽고, fgets는 한 줄을 버퍼로 읽어들이며, fscanf는 파일에서 형식화된 토큰을 파싱합니다.
  • 🔒 파일 닫기: fclose 함수는 버퍼링된 데이터를 비우고 파일을 해제하며, 성공 시 0을, 실패 시 EOF를 반환합니다.
  • 🔁 대화형 입출력: getc와 putc는 한 번에 한 문자씩 처리하며, 입력값을 파일로 바로 전송하고 다시 출력합니다.
  • 🤖 AI 지원: GitHub Copilot과 AI 비서는 fopen, fprintf, fgets 루틴을 구성하고 누락된 NULL 검사 또는 닫히지 않은 파일을 표시합니다.

C 파일 I/O

C 파일 관리

파일은 대용량의 영구 데이터를 저장하는 데 사용할 수 있습니다. 다른 많은 언어와 마찬가지로 'C' 언어는 다음과 같은 파일 관리 기능을 제공합니다. 기능,

  1. 파일 생성
  2. 파일 열기
  3. 파일 읽기
  4. 파일에 쓰기
  5. 파일 닫기

다음은 'C'에서 사용할 수 있는 가장 중요한 파일 관리 함수입니다.

기능 목적
열다 () 파일 생성 또는 기존 파일 열기
fclose () 파일 닫기
fprintf() 파일에 데이터 블록 쓰기
fscanf() 파일에서 블록 데이터 읽기
getc() 파일에서 단일 문자를 읽습니다.
푸치() 파일에 단일 문자를 씁니다.
getw () 파일에서 정수를 읽습니다.
푸우 () 파일에 정수 쓰기
fseek () 파일 포인터의 위치를 ​​지정된 위치로 설정합니다.
프텔() 파일 포인터의 현재 위치를 반환합니다.
되감기 () 파일 시작 부분에 파일 포인터를 설정합니다.

파일을 만드는 방법

파일 작업을 원할 때마다 첫 번째 단계는 파일을 만드는 것입니다. 파일은 데이터가 저장되는 메모리 공간일 뿐입니다.

'C' 프로그램에서 파일을 생성하려면 다음 구문을 사용합니다.

FILE *fp;
fp = fopen ("file_name", "mode");

위 구문에서 파일은 표준 라이브러리에 정의된 데이터 구조입니다.

fopen은 파일을 여는 데 사용되는 표준 함수입니다.

  • 파일이 시스템에 없으면 파일이 생성된 다음 열립니다.
  • 시스템에 이미 파일이 있는 경우 이 함수를 사용하여 해당 파일을 직접 엽니다.

fp는 파일입니다. 포인터 이는 형식 파일을 가리킵니다.

파일을 열거나 생성할 때마다 해당 파일로 무엇을 할 것인지 지정해야 합니다. 'C' 프로그래밍의 파일은 읽기/쓰기 목적으로 생성하거나 열 수 있습니다. 모드는 아래에 주어진 목적 중 하나를 위해 파일을 열 것인지 지정하는 데 사용됩니다. 다음은 파일 작업 중에 사용할 수 있는 'C' 프로그래밍의 다양한 유형의 모드입니다.

파일 모드 기술설명
r 읽을 파일을 엽니다. 파일이 읽기 모드인 경우 파일이 이미 시스템에 있으면 데이터가 삭제되지 않습니다.
w 쓰기 위해 파일을 엽니다. 파일이 쓰기 모드인 경우 파일이 전혀 존재하지 않으면 새 파일이 생성됩니다. 파일이 시스템에 이미 존재하는 경우 파일 내부의 모든 데이터가 잘리고 쓰기 목적으로 열립니다.
a 파일을 추가 모드로 엽니다. 파일이 추가 모드이면 파일이 열립니다. 파일 내부의 내용은 변경되지 않습니다.
r+ 처음부터 읽고 쓸 수 있도록 열려 있음
w+ 읽기 및 쓰기용으로 열림, 파일 덮어쓰기
a+ 읽기 및 쓰기용으로 열림, 파일에 추가

주어진 구문에서 파일 이름과 모드는 다음과 같이 지정됩니다. 문자열 따라서 항상 큰따옴표로 묶어야 합니다.

예 :

#include <stdio.h>
int main() {
FILE *fp;
fp  = fopen ("data.txt", "w");
}

출력:

파일은 코드를 저장한 폴더에 생성됩니다.

C 프로그램 출력에 파일을 생성합니다.

파일을 생성하려는 경로를 지정할 수 있습니다

#include <stdio.h>
int main() {
FILE *fp;
fp  = fopen ("D://data.txt", "w");
}

C 언어로 지정된 경로에 파일을 생성합니다.

파일을 닫는 방법

파일에 대한 작업이 끝나면 항상 파일을 닫아야 합니다. 즉, 파일의 내용과 링크가 종료됩니다. 이렇게 하면 파일이 실수로 손상되는 것을 방지할 수 있습니다.

'C'는 파일 닫기 작업을 수행하기 위한 fclose 함수를 제공합니다. fclose의 구문은 다음과 같습니다.

fclose (file_pointer);

예 :

FILE *fp;
fp  = fopen ("data.txt", "r");
fclose (fp);

`fclose` 함수는 파일 포인터를 인수로 받습니다. 이 함수는 해당 파일 포인터와 연결된 파일을 닫습니다. 파일 닫기가 성공하면 `0`을 반환하고, 파일 닫기 중 오류가 발생하면 `EOF`(파일 끝)를 반환합니다.

파일을 닫은 후 동일한 파일 포인터를 다른 파일에도 사용할 수 있습니다.

'C' 프로그래밍에서는 프로그램이 종료되면 파일이 자동으로 닫힙니다. fclose 함수를 작성하여 수동으로 파일을 닫는 것은 좋은 프로그래밍 습관입니다.

파일에 쓰기

C에서는 파일에 쓸 때 개행 문자 '\n'을 명시적으로 추가해야 합니다.

stdio 라이브러리는 파일에 쓰는 데 필요한 기능을 제공합니다.

  • fputc(char, file_pointer): file_pointer가 가리키는 파일에 문자를 씁니다.
  • fputs(str, file_pointer): file_pointer가 가리키는 파일에 문자열을 씁니다.
  • fprintf(file_pointer, str, variable_lists): file_pointer가 가리키는 파일에 문자열을 출력합니다. 문자열에는 선택적으로 형식 지정자와 변수 목록 variable_lists가 포함될 수 있습니다.

아래 프로그램은 파일 쓰기를 수행하는 방법을 보여줍니다.

fputc() 함수:

#include <stdio.h>
int main() {
        int i;
        FILE * fptr;
        char fn[50];
        char str[] = "Guru99 Rocks\n";
        fptr = fopen("fputc_test.txt", "w"); // "w" defines "writing mode"
        for (i = 0; str[i] != '\n'; i++) {
            /* write to file using fputc() function */
            fputc(str[i], fptr);
        }
        fclose(fptr);
        return 0;
    }

출력:

C 언어에서 fputc() 함수의 출력

위 프로그램은 배열의 각 문자를 하나씩 fputc_test.txt 파일에 기록합니다. 다음 줄의 문자("\n")가 나오면 문장이 성공적으로 기록된 것입니다. 이 과정은 배열의 각 문자를 가져와 파일에 쓰는 방식으로 진행됩니다.

fputc_test.txt 파일 내용이 C 언어로 작성되었습니다.

  1. 위 프로그램에서는 쓰기 모드에서 fputc_test.txt라는 파일을 생성하고 열고 파일에 기록될 문자열을 선언했습니다.
  2. for 루프를 사용하여 문자별로 쓰기 작업을 수행하고 "\n" 문자가 나올 때까지 각 문자를 파일에 넣은 다음 fclose 함수를 사용하여 파일을 닫습니다.

fputs() 함수:

#include <stdio.h>
int main() {
        FILE * fp;
        fp = fopen("fputs_test.txt", "w+");
        fputs("This is Guru99 Tutorial on fputs,", fp);
        fputs("We don't need to use for loop\n", fp);
        fputs("Easier than fputc function\n", fp);
        fclose(fp);
        return (0);
    }

출력:

C 언어에서 fputs() 함수의 출력

fputs_test.txt 파일 내용 (C 언어)

  1. 위 프로그램에서는 쓰기 모드로 fputs_test.txt라는 파일을 생성하고 오픈했습니다.
  2. fputs() 함수를 사용하여 서로 다른 세 문자열을 쓰는 쓰기 작업을 수행한 후
  3. 그런 다음 fclose 함수를 사용하여 파일을 닫습니다.

fprintf()함수:

#include <stdio.h>
    int main() {
        FILE *fptr;
        fptr = fopen("fprintf_test.txt", "w"); // "w" defines "writing mode"
        /* write to file */
        fprintf(fptr, "Learning C with Guru99\n");
        fclose(fptr);
        return 0;
    }

출력:

C 언어에서 fprintf() 함수의 출력 결과

fprintf_test.txt 파일 내용 (C 언어)

  1. 위 프로그램에서는 쓰기 모드에서 fprintf_test.txt라는 파일을 생성하고 열었습니다.
  2. fprintf() 함수를 사용하여 문자열을 쓰는 쓰기 작업이 수행된 후, fclose 함수를 사용하여 파일이 닫힙니다.

파일에서 데이터 읽기

파일에서 데이터를 읽는 데 사용되는 세 가지 기능이 있습니다.

  • fgetc(file_pointer): 파일 포인터가 가리키는 파일에서 다음 문자를 반환합니다. 파일의 끝에 도달하면 EOF를 반환합니다.
  • fgets(buffer, n, file_pointer): 파일에서 n-1개의 문자를 읽어 버퍼에 저장하는데, 이때 마지막 문자는 NULL 문자 '\0'이 추가됩니다.
  • fscanf(file_pointer, conversion_specifiers, variable_adresses): 이 함수는 데이터를 구문 분석하고 분석하는 데 사용됩니다. 파일에서 문자를 읽어 변환 지정자를 사용하여 입력값을 variable_adresses라는 변수 포인터 목록에 할당합니다. scanf와 마찬가지로 fscanf는 공백이나 줄 바꿈 문자를 만나면 문자열 읽기를 중지한다는 점에 유의하십시오.

다음 프로그램은 각각 fgets(), fscanf(), fgetc() 함수를 사용하여 fputs_test.txt 파일에서 읽는 방법을 보여줍니다.

#include <stdio.h>
int main() {
        FILE * file_pointer;
        char buffer[30], c;

        file_pointer = fopen("fprintf_test.txt", "r");
        printf("----read a line----\n");
        fgets(buffer, 50, file_pointer);
        printf("%s\n", buffer);

        printf("----read and parse data----\n");
        file_pointer = fopen("fprintf_test.txt", "r"); //reset the pointer
        char str1[10], str2[2], str3[20], str4[2];
        fscanf(file_pointer, "%s %s %s %s", str1, str2, str3, str4);
        printf("Read String1 |%s|\n", str1);
        printf("Read String2 |%s|\n", str2);
        printf("Read String3 |%s|\n", str3);
        printf("Read String4 |%s|\n", str4);

        printf("----read the entire file----\n");

        file_pointer = fopen("fprintf_test.txt", "r"); //reset the pointer
        while ((c = getc(file_pointer)) != EOF) printf("%c", c);

        fclose(file_pointer);
        return 0;
    }

결과 :

----read a line----
Learning C with Guru99

----read and parse data----
Read String1 |Learning|
Read String2 |C|
Read String3 |with|
Read String4 |Guru99|
----read the entire file----
Learning C with Guru99

C 언어에서 파일로부터 데이터를 읽는 출력

  1. 위 프로그램에서는 이전에 fprintf() 함수를 사용하여 작성된 "fprintf_test.txt"라는 파일을 열었으며, 이 파일에는 "Learning C with"라는 내용이 포함되어 있습니다. Guru"99"라는 문자열입니다. 우리는 fgets() 함수를 사용하여 이 문자열을 읽는데, 이 함수는 한 줄씩 읽으므로 버퍼 크기가 전체 줄을 처리할 수 있을 만큼 충분해야 합니다.
  2. 파일 포인터가 파일의 시작 부분을 가리키도록 파일을 다시 엽니다. 각 단어를 개별적으로 처리하기 위해 여러 문자열 변수를 생성합니다. 변수를 출력하여 내용을 확인합니다. fscanf() 함수는 주로 다음과 같은 용도로 사용됩니다.trac파일에서 데이터를 추출하고 파싱합니다.
  3. 파일의 시작 부분을 가리키도록 포인터 파일을 재설정하려면 파일을 다시 엽니다. EOF 문이 나타날 때까지 getc() 함수를 사용하여 파일에서 데이터를 한 문자씩 읽고 인쇄합니다.
  4. 다양한 변형을 사용하여 파일 읽기 작업을 수행한 뒤, fclose 함수를 사용하여 다시 파일을 닫았습니다.

getc 및 putc를 사용한 대화형 파일 읽기 및 쓰기

이것들은 가장 간단한 파일 작업입니다. Getc는 get character를 의미하고, putc는 put character를 의미합니다. 이 두 함수는 한 번에 하나의 문자만 처리하는 데 사용됩니다.

다음 프로그램은 'C' 프로그래밍에서의 파일 처리 기능을 보여줍니다.

#include <stdio.h>
int main() {
        FILE * fp;
        char c;
        printf("File Handling\n");
        //open a file
        fp = fopen("demo.txt", "w");
        //writing operation
        while ((c = getchar()) != EOF) {
            putc(c, fp);
        }
        //close file
        fclose(fp);
        printf("Data Entered:\n");
        //reading
        fp = fopen("demo.txt", "r");
        while ((c = getc(fp)) != EOF) {
            printf("%c", c);
        }
        fclose(fp);
        return 0;
    }

출력:

C 언어에서 대화형 파일 읽기 및 쓰기 출력

C 언어에서 getc와 putc를 사용하여 파일 출력을 처리하는 방법

  1. 위 프로그램에서는 쓰기 모드에서 데모라는 파일을 생성하고 열었습니다.
  2. 쓰기 작업이 수행된 후에는 fclose 함수를 사용하여 파일이 닫힙니다.
  3. 우리는 다시 읽기 모드에서 데이터를 포함하는 파일을 열었습니다. eof가 발견될 때까지 while 루프가 실행됩니다. 파일 끝이 발견되면 작업이 종료되고 printf 함수를 사용하여 데이터가 표시됩니다.
  4. 읽기 작업을 수행한 후에는 fclose 함수를 사용하여 파일을 다시 닫습니다.

자주 묻는 질문

텍스트 모드는 줄 바꿈 문자를 운영 체제에 맞게 변환하는 반면, "rb" 또는 "wb" 키로 여는 바이너리 모드는 바이트를 있는 그대로 기록합니다. 이미지, 오디오 또는 정확한 바이트 레이아웃을 유지해야 하는 모든 데이터에는 바이너리 모드를 사용하십시오.

fopen 함수는 파일이 없거나, 권한이 없거나, 디스크 용량이 부족한 경우와 같이 파일을 열 수 없을 때 NULL을 반환합니다. 읽기 또는 쓰기 작업을 수행하기 전에 반환된 포인터가 NULL인지 항상 확인해야 합니다. 그렇지 않으면 프로그램이 유효하지 않은 포인터를 사용하게 되어 일반적으로 오류가 발생합니다.

쓰기 모드 "w"는 기존 파일을 잘라내고 내용을 지운 후 다시 씁니다. 파일이 없으면 새로 생성합니다. 추가 모드 "a"는 기존 데이터를 유지하고 새 내용을 끝에 추가하므로 이미 저장된 내용은 손실되지 않습니다.

fseek 함수는 파일 포인터를 SEEK_SET, SEEK_CUR 또는 SEEK_END를 기준으로 측정된 바이트 오프셋만큼 이동시킵니다. ftell 함수는 포인터의 현재 바이트 위치를 반환하고, rewind 함수는 포인터를 파일의 시작 부분으로 되돌립니다. 이 두 함수를 함께 사용하면 순차적인 읽기 대신 임의 접근이 가능합니다.

fgets가 한 줄 전체를 읽으면 중지합니다.ping fscanf는 줄 바꿈 문자 또는 n-1 문자 후에 읽으므로 버퍼 크기를 준수합니다. fscanf는 공백으로 구분된 형식화된 토큰을 읽으며 짧은 배열에서는 오버플로가 발생할 수 있습니다. 전체 줄을 안전하게 읽으려면 fgets가 더 나은 선택입니다.

EOF는 파일의 끝을 나타내는 상수(일반적으로 -1)입니다. getc, fgetc, fscanf와 같은 읽기 함수는 더 이상 데이터가 남아 있지 않으면 EOF를 반환하므로, 반복문은 읽기를 중지하기 위해 결과를 EOF와 비교합니다.

네. AI 코딩 도우미는 일반적인 언어로 작성된 프롬프트에서 fopen, fprintf, fgets 루틴을 생성하고, 각 파일 모드를 설명하며, NULL 검사 누락이나 닫히지 않은 파일과 같은 버그를 찾아낼 수 있습니다. 하지만 AI가 제안한 코드를 신뢰하기 전에 항상 컴파일하고 테스트해야 합니다.

GitHub 부조종사 C 파일 처리 코드를 작성하며, 간단한 주석이나 함수 이름을 입력하면 fopen, fputs, fscanf 함수 블록 전체를 제안합니다. 또한, 해당 함수에 맞는 fclose 호출과 오류 검사까지 포함하는 경우가 많지만, 생성된 로직을 검토하는 것이 좋습니다.

이 게시물을 요약하면 다음과 같습니다.