C 언어에서 텍스트 파일 읽기/쓰기 예제

제공

C 언어는 파일 처리를 통해 데이터를 저장하고 불러올 수 있는 강력한 기능을 제공합니다. 이 기능을 제대로 이해하고 활용하는 것은 프로그래밍 실력 향상에 중요한 발걸음입니다. 이번 포스팅에서는 C 언어에서 텍스트 파일을 읽고 쓰는 방법에 대한 명확하고 간결한 설명과 함께 실제로 사용 가능한 예제 코드를 제공하여 여러분의 이해를 돕고자 합니다. 파일 열기와 닫기부터 시작하여 텍스트 파일 읽기, 텍스트 파일 쓰기, 그리고 마지막으로 실제 예제 코드까지, C 언어 파일 처리의 핵심적인 부분들을 단계별로 살펴보겠습니다. 이 글을 통해 텍스트 파일 다루는 방법을 마스터하고 프로그래밍 능력을 한 단계 더 발전시켜보세요!

 

 

파일 열기와 닫기

C 언어에서 파일을 다루는 것은 마치 레고 블록을 조립하는 것과 같습니다. 하나하나의 블록(함수)들이 모여 멋진 작품(프로그램)을 만들어내죠! 그 첫 번째 블록이 바로 파일을 열고 닫는 과정입니다. 이 과정을 제대로 이해하지 못하면? 다음 단계로 나아갈 수 없겠죠?! 자, 이제 파일을 여는 마법의 문을 열어보겠습니다!

`fopen()` 함수를 이용한 파일 열기

C에서는 fopen() 함수를 사용하여 파일을 엽니다. 마치 금고를 열려면 열쇠가 필요하듯, fopen() 함수에도 두 개의 중요한 “열쇠”가 필요합니다. 바로 파일 경로(파일 이름)와 파일 모드입니다. 파일 경로는 “C:\\my_document\\example.txt” 와 같이 파일이 어디에 있는지 알려주는 주소이고, 파일 모드는 파일을 어떻게 사용할 것인지(읽기, 쓰기, 추가 등)를 나타내는 문자열입니다. 예를 들어 “r”은 읽기 모드, “w”는 쓰기 모드, “a”는 추가 모드를 나타냅니다. “r+” 처럼 + 기호를 붙이면 읽기와 쓰기를 동시에 할 수 있고, “w+”는 파일을 쓰기 모드로 열면서, 동시에 읽기도 가능하게 합니다. “a+”는 파일의 끝에 데이터를 추가하는 모드이면서, 동시에 파일 읽기도 가능하게 합니다. 이 외에도 바이너리 모드로 파일을 열고 싶다면 “b”를 추가할 수 있습니다. 예를 들어 “rb”는 읽기 바이너리 모드, “wb”는 쓰기 바이너리 모드가 되는 것이죠! 마치 비밀번호를 입력하듯 정확하게 입력해야 원하는 결과를 얻을 수 있습니다.

fopen() 함수는 마치 마법사처럼 파일 포인터라는 것을 반환합니다. 파일 포인터는 열린 파일을 가리키는 일종의 지시봉과 같습니다. 이 지시봉을 이용해서 파일의 내용을 읽고 쓸 수 있습니다. 만약 파일을 여는 데 실패하면 fopen() 함수는 NULL 포인터를 반환합니다. 이는 마치 금고를 열려고 했는데 열쇠가 맞지 않아 열리지 않는 것과 같습니다. 따라서 항상 fopen() 함수의 반환 값을 확인하여 파일이 제대로 열렸는지 확인해야 합니다! 이 작은 확인 과정이 프로그램의 안정성을 크게 높여줍니다. 잊지 마세요!

`fclose()` 함수를 이용한 파일 닫기

파일을 다 사용하고 나면 fclose() 함수를 사용하여 파일을 닫아야 합니다. 마치 사용한 금고를 잠그는 것과 같죠. fclose() 함수는 파일 포인터를 인자로 받아 해당 파일을 닫습니다. 파일을 닫지 않으면 데이터 손실이나 시스템 오류가 발생할 수 있으므로, 항상 파일을 닫는 것을 잊지 않도록 주의해야 합니다! 파일을 제대로 닫지 않으면 마치 금고를 열어둔 채로 방치하는 것과 같습니다. 위험천만하죠?!

실제 코드 예시

자, 이제 실제 코드를 통해 파일 열기와 닫기를 살펴보겠습니다. 백문이 불여일견이라고 하죠? 실제 코드를 보면 이해가 더욱 쉬울 겁니다.

#include <stdio.h>

int main() {
    FILE *fp = NULL; // 파일 포인터 초기화. NULL로 초기화하는 것은 좋은 습관입니다!
    char file_name[] = "example.txt"; // 파일 이름 설정

    // 파일을 쓰기 모드로 열기. 만약 파일이 없으면 새로 생성합니다.
    fp = fopen(file_name, "w");

    // 파일 열기 성공 여부 확인.  이 부분 굉장히 중요합니다!!
    if (fp == NULL) {
        perror("파일 열기 실패!"); // 에러 메시지 출력. perror 함수는 errno 값을 기반으로 에러 메시지를 출력해주는 유용한 함수입니다.
        return 1; // 프로그램 종료. 에러 발생 시 0이 아닌 값을 반환하는 것이 일반적입니다.
    }

    // 여기에서 파일 쓰기 작업을 수행할 수 있습니다. (다음 섹션에서 자세히 다룹니다!)


    // 파일 닫기.  마무리가 중요합니다!
    if (fclose(fp) != 0) { // fclose 함수는 성공적으로 파일을 닫으면 0을 반환하고, 실패하면 EOF를 반환합니다.
        perror("파일 닫기 실패!");  // 만약 파일을 닫는 도중 에러가 발생한다면?!  꼭 확인해야겠죠?
        return 1; // 프로그램 종료
    }

    printf("파일 열기 및 닫기 성공!\n"); // 성공 메시지 출력.  작은 성공에도 기뻐하는 습관을 가져보세요!

    return 0; // 프로그램 정상 종료.
}

위 코드에서 fopen() 함수를 사용하여 “example.txt” 파일을 쓰기 모드(“w”)로 열고, 파일 포인터 fp에 저장합니다. 그리고 fclose() 함수를 사용하여 파일을 닫습니다. if (fp == NULL) 부분은 파일 열기 실패를 확인하는 중요한 부분입니다. 만약 파일을 열 수 없다면 에러 메시지를 출력하고 프로그램을 종료합니다. 파일을 닫을 때도 마찬가지로 에러 처리를 해주는 것이 좋습니다. 이처럼 작은 부분까지 신경 쓰는 것이 안정적인 프로그램을 만드는 비결입니다.

이제 파일 열기와 닫기에 대한 기본적인 이해를 마쳤습니다. 다음 단계에서는 파일에서 데이터를 읽고 쓰는 방법에 대해 알아보겠습니다. 기대되시죠?! 계속해서 C 언어의 세계를 탐험해 봅시다!

 

텍스트 파일 읽기

파일을 열었다면 이제 파일 안에 뭐가 들었는지 확인해야겠죠?! 마치 보물상자를 열었는데 안을 들여다봐야 보물인지, 아니면 꽝인지 알 수 있듯이 말이에요! 텍스트 파일 읽기는 프로그래밍에서 가장 기본적이면서도 중요한 작업 중 하나입니다. 데이터 분석, 설정 파일 로딩, 로그 파일 분석 등 수많은 응용 분야에서 텍스트 파일 읽기가 필수적이랍니다. 효율적이고 안전하게 파일을 읽는 방법, 지금부터 자세히 알려드릴게요!

C 언어에서는 fopen() 함수로 파일을 열 때, 파일 모드를 "r"로 지정하면 읽기 모드로 파일을 열 수 있어요. 파일 포인터가 파일의 시작 부분을 가리키게 되죠. 이 파일 포인터는 마치 책갈피처럼 현재 읽고 있는 위치를 표시한답니다. 읽기 작업을 진행할수록 이 파일 포인터는 파일의 끝을 향해 이동해요. 마치 책을 읽어 나가는 것과 같죠!

자, 이제 다양한 방법으로 파일 내용을 읽어 보겠습니다. 각 방법의 특징과 장단점을 살펴보고, 상황에 맞는 최적의 방법을 선택하는 것이 중요해요! 마치 요리 레시피처럼 말이죠. 상황에 따라 적절한 재료와 조리법을 선택해야 맛있는 요리가 완성되는 것처럼, 파일 읽기도 마찬가지랍니다.

1. `fgetc()` 함수: 한 글자씩 읽어오기

fgetc() 함수는 파일에서 한 글자씩 읽어오는 가장 기본적인 함수입니다. 파일 끝에 도달하거나 오류가 발생하면 EOF(End Of File)를 반환해요. 이 함수는 파일의 내용을 정밀하게 제어해야 할 때 유용하답니다. 예를 들어, 특정 문자를 찾거나, 파일의 형식을 검사할 때 fgetc() 함수가 빛을 발하죠! 하지만 파일 크기가 크다면, 한 글자씩 읽는 것은 시간이 오래 걸릴 수 있다는 단점이 있어요.🐌

2. `fgets()` 함수: 한 줄씩 읽어오기

fgets() 함수는 파일에서 한 줄씩 읽어오는 함수입니다. 지정한 크기만큼의 문자열을 읽어오고, 줄 바꿈 문자(\n)를 만나거나 파일 끝에 도달하면 읽기를 멈춥니다. 읽어온 문자열은 지정한 버퍼에 저장되고, 널 종료 문자(\0)가 자동으로 추가됩니다. 이 함수는 텍스트 파일을 줄 단위로 처리할 때 매우 편리해요! 예를 들어, 설정 파일이나 로그 파일을 읽을 때 fgets() 함수가 딱이죠! 👍

3. `fread()` 함수: 지정한 크기만큼 읽어오기

fread() 함수는 지정한 크기의 데이터 블록을 읽어오는 함수입니다. 이 함수는 이진 파일과 텍스트 파일 모두에서 사용할 수 있어요. 특히, 대용량 파일을 처리하거나, 구조체 데이터를 읽어올 때 매우 효율적입니다. fread() 함수는 파일 포인터를 기준으로 지정된 크기만큼 데이터를 읽어오고, 실제로 읽어온 바이트 수를 반환합니다. 파일 끝에 도달하거나 오류가 발생하면 읽어온 바이트 수가 지정된 크기보다 작을 수 있으니 주의해야 해요!⚠️

4. `fscanf()` 함수: 형식화된 데이터 읽어오기

fscanf() 함수는 scanf() 함수와 유사하게, 형식 지정자를 사용하여 파일에서 데이터를 읽어오는 함수입니다. 숫자, 문자열, 문자 등 다양한 형식의 데이터를 읽어올 수 있어요. 예를 들어, 콤마(,)로 구분된 데이터 파일을 읽어올 때 fscanf() 함수를 사용하면 편리하게 데이터를 추출할 수 있답니다. 하지만 파일 형식이 정확하게 일치하지 않으면 예상치 못한 결과가 발생할 수 있으므로 주의해야 해요!🧐

파일 읽기 성능 향상 팁! 🚀

  • 버퍼링 활용: setvbuf() 함수를 사용하여 버퍼 크기를 조절하면 파일 읽기 성능을 향상시킬 수 있습니다.
  • fread() 함수 활용: 대용량 파일을 읽을 때는 fread() 함수를 사용하여 블록 단위로 읽어오는 것이 효율적입니다.
  • 파일 포인터 이동 최소화: fseek() 함수를 사용하여 파일 포인터를 이동할 때는 최소한의 이동으로 작업을 수행하는 것이 좋습니다. 불필요한 파일 포인터 이동은 성능 저하를 야기할 수 있습니다.

자, 이제 텍스트 파일 읽기에 대한 다양한 방법과 팁들을 알아보았습니다. 상황에 맞는 적절한 함수와 팁들을 활용하여 효율적이고 안전하게 파일을 읽어보세요! 파일 읽기는 프로그래밍의 기본 중의 기본이니, 꼭 마스터하시길 바랍니다! 😄

 

텍스트 파일 쓰기

텍스트 파일 쓰기는 C 언어에서 데이터를 영구적으로 저장하거나 다른 프로그램과 정보를 교환하는 데 필수적인 작업입니다. 이 과정은 파일을 열고, 데이터를 쓰고, 파일을 닫는 세 단계로 이루어집니다. 각 단계는 정확하고 효율적인 파일 처리를 위해 세심한 주의가 필요합니다. 자, 이제 C 언어의 강력한 기능을 활용하여 텍스트 파일 쓰기의 세계를 탐험해 봅시다!

파일 열기

파일 쓰기는 fopen() 함수를 사용하여 시작하며, 이 함수는 파일을 쓰기 모드("w")로 엽니다. 만약 파일이 존재하지 않으면 새로 생성되고, 이미 존재하는 경우에는 내용이 덮어씌워지니 주의해야 합니다! 덮어쓰기를 방지하려면 추가 모드("a")를 사용하는 것이 좋습니다. 이 모드는 파일의 끝에 데이터를 추가합니다. fopen() 함수는 파일 포인터를 반환하는데, 이 포인터는 파일을 조작하는 데 사용되는 핵심 요소입니다. 마치 파일의 위치를 가리키는 나침반과 같죠. 파일 포인터가 NULL인 경우, 파일을 여는 데 실패했음을 의미하며, 이는 디스크 공간 부족, 파일 권한 문제 등 다양한 원인으로 발생할 수 있습니다. 따라서 항상 fopen() 함수의 반환 값을 확인하는 습관을 들이는 것이 중요합니다!

데이터 쓰기

데이터를 파일에 쓰는 방법은 크게 두 가지가 있습니다: fprintf() 함수와 fputs() 함수. fprintf() 함수는 서식화된 출력을 지원하며, printf() 함수와 유사하게 작동합니다. 예를 들어, 정수형 변수 num의 값을 파일에 쓰려면 fprintf(fp, "%d", num);와 같이 사용할 수 있습니다. 여기서 fp는 파일 포인터입니다. fputs() 함수는 문자열을 파일에 쓰는 데 사용되며, fprintf() 함수보다 간단하고 빠릅니다. 문자열 “Hello, world!”를 파일에 쓰려면 fputs("Hello, world!\n", fp);와 같이 사용하면 됩니다. 개행 문자(\n)를 추가하여 다음 출력이 새로운 줄에 시작되도록 하는 것을 잊지 마세요!

이진 데이터 쓰기

fwrite() 함수는 이진 데이터를 파일에 쓰는 데 사용됩니다. 이 함수는 데이터의 크기와 개수를 지정할 수 있어 효율적인 이진 데이터 처리가 가능합니다. 예를 들어, 100개의 float형 데이터를 담은 배열 data를 파일에 쓰려면 fwrite(data, sizeof(float), 100, fp);와 같이 사용할 수 있습니다. fwrite() 함수는 실제로 파일에 쓰인 데이터의 개수를 반환하므로, 이 값을 확인하여 쓰기 작업이 성공적으로 완료되었는지 확인하는 것이 좋습니다. 만약 반환 값이 예상보다 작다면, 디스크 공간 부족이나 다른 오류가 발생했을 가능성이 있습니다.

파일 닫기

파일을 닫는 것은 fclose() 함수를 사용하여 수행됩니다. 이 함수는 파일 포인터를 해제하고, 버퍼에 남아있는 데이터를 파일에 씁니다. 파일을 닫지 않으면 데이터 손실이나 파일 손상이 발생할 수 있으므로, 항상 fclose() 함수를 호출하여 파일을 닫는 것이 중요합니다. fclose() 함수는 성공적으로 파일을 닫으면 0을 반환하고, 오류가 발생하면 EOF를 반환합니다. EOF는 End-Of-File의 약자로, 일반적으로 -1로 정의됩니다. 따라서 fclose() 함수의 반환 값을 확인하여 파일 닫기 작업이 성공적으로 완료되었는지 확인하는 것이 좋습니다.

파일 처리 시 주의 사항

파일을 다루는 작업은 운영체제의 자원을 사용하기 때문에, 항상 주의를 기울여야 합니다. 파일을 열었으면 반드시 닫아야 하고, 오류 처리를 철저히 해야 합니다. 또한, 대용량 파일을 처리할 때는 메모리 사용량을 최소화하기 위해 버퍼링 기법을 적절히 활용해야 합니다. setvbuf() 함수를 사용하면 버퍼의 크기와 동작 방식을 설정할 수 있습니다. 예를 들어, setvbuf(fp, NULL, _IOFBF, BUFSIZ);fp가 가리키는 파일에 대해 완전 버퍼링을 사용하도록 설정합니다. BUFSIZ는 표준 버퍼 크기로, 일반적으로 512바이트 또는 4096바이트입니다.

결론

텍스트 파일 쓰기는 데이터를 저장하고 공유하는 데 필수적인 기술입니다. C 언어는 다양한 함수와 기능을 제공하여 텍스트 파일을 효율적으로 다룰 수 있도록 지원합니다. fopen(), fprintf(), fputs(), fwrite(), fclose(), setvbuf() 등의 함수를 적절히 사용하여 안전하고 효율적인 파일 처리를 구현하세요! 이러한 함수들을 잘 이해하고 활용한다면, C 언어를 통해 더욱 강력하고 효율적인 프로그램을 개발할 수 있을 것입니다.

 

실제 예제 코드

드디어! C 언어로 텍스트 파일을 읽고 쓰는 실제 예제 코드를 살펴볼 시간입니다. 앞서 설명드린 파일 열기, 닫기, 읽기, 쓰기 함수들을 활용하여 실질적인 코드 작성법을 알아보겠습니다. 이 예제에서는 “example.txt”라는 파일을 생성하고, 데이터를 쓰고, 다시 읽어오는 과정을 보여드리겠습니다. 자, 시작해 볼까요?

1. 파일 쓰기 예제 (example_write.c)

#include <stdio.h>

int main() {
    FILE *fp = fopen("example.txt", "w"); // "w" 모드로 파일 열기 (쓰기 모드)

    if (fp == NULL) { // 파일 열기 실패 시 에러 처리
        perror("파일 열기 실패!: example.txt"); // perror 함수를 사용하여 에러 메시지 출력
        return 1; // 1을 반환하여 에러 발생을 알림
    }

    fprintf(fp, "안녕하세요! C 언어 파일 쓰기 예제입니다.\n"); // 파일에 문자열 쓰기
    fprintf(fp, "이 예제는 파일 쓰기 함수(fprintf)를 사용합니다.\n");
    fprintf(fp, "숫자도 쓸 수 있습니다: %d, %f\n", 123, 3.141592); // 숫자 데이터 쓰기

    int result = fclose(fp); // 파일 닫기 (중요!)
    if (result == EOF) { // 파일 닫기 실패 시 에러 처리 (EOF: End Of File)
        perror("파일 닫기 실패!: example.txt");
        return 1; // 에러 발생 시 1 반환
    }

    printf("파일 쓰기 완료!\n"); // 성공 메시지 출력

    return 0; // 정상 종료 시 0 반환
}

이 코드에서는 fopen() 함수를 사용하여 “example.txt” 파일을 “w” 모드(쓰기 모드)로 열고 있습니다. 만약 파일 열기에 실패하면 perror() 함수를 이용해 에러 메시지를 출력하고 프로그램을 종료합니다. 파일이 정상적으로 열리면, fprintf() 함수를 사용하여 파일에 문자열과 숫자 데이터를 씁니다. 마지막으로 fclose() 함수로 파일을 닫는 것을 잊지 마세요! 파일을 닫지 않으면 데이터 손실이나 시스템 오류가 발생할 수 있습니다. fclose() 함수의 반환 값을 확인하여 파일 닫기 성공 여부도 체크하는 꼼꼼함까지 갖춘다면 더욱 좋겠죠?

2. 파일 읽기 예제 (example_read.c)

#include <stdio.h>

int main() {
    FILE *fp = fopen("example.txt", "r"); // "r" 모드로 파일 열기 (읽기 모드)

    if (fp == NULL) {
        perror("파일 열기 실패!: example.txt");
        return 1;
    }

    char buffer[256]; // 파일 내용을 저장할 버퍼 (256바이트)

    while (fgets(buffer, sizeof(buffer), fp) != NULL) { // 파일 끝까지 한 줄씩 읽기
        printf("%s", buffer); // 읽어온 내용 출력
    }

    fclose(fp); // 파일 닫기

    printf("파일 읽기 완료!\n");

    return 0;
}

이 코드에서는 fopen() 함수를 사용하여 “example.txt” 파일을 “r” 모드(읽기 모드)로 엽니다. 파일 열기에 실패하면 역시 perror() 함수로 에러 메시지를 출력하고 프로그램을 종료합니다. 파일이 정상적으로 열리면, fgets() 함수를 사용하여 파일에서 한 줄씩 데이터를 읽어와 buffer에 저장합니다. fgets() 함수는 파일의 끝에 도달하거나 오류가 발생하면 NULL을 반환하므로, 이를 이용하여 반복문을 종료합니다. 읽어온 데이터는 printf() 함수로 출력합니다. 마지막으로 fclose() 함수로 파일을 닫습니다. 파일 닫기는 필수! 잊지 마세요!

3. 파일 읽기/쓰기 통합 예제 (example_integrated.c)

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

int main() {
    char filename[] = "integrated.txt";
    char write_data[] = "C 언어 파일 읽기/쓰기 통합 예제입니다!\n";
    char read_data[256];

    // 파일 쓰기
    FILE *fw = fopen(filename, "w");
    if (fw == NULL) { perror("파일 열기 실패"); return 1; }
    fwrite(write_data, strlen(write_data), 1, fw);
    fclose(fw);

    // 파일 읽기
    FILE *fr = fopen(filename, "r");
    if (fr == NULL) { perror("파일 열기 실패"); return 1; }
    if (fgets(read_data, sizeof(read_data), fr) != NULL) {
        printf("파일 내용: %s", read_data);
    }
    fclose(fr);

    // 파일 추가 쓰기 (append)
    FILE *fa = fopen(filename, "a");
    if (fa == NULL) { perror("파일 열기 실패"); return 1; }
    fprintf(fa, "데이터 추가 완료!\n");
    fclose(fa);

    printf("파일 작업 완료!\n");
    return 0;
}

이 예제는 파일 쓰기, 읽기, 추가 쓰기(append)까지 모두 포함한 통합 예제입니다. “integrated.txt”라는 파일을 생성하고, 데이터를 쓴 후, 다시 읽어옵니다. 그리고 “a” 모드를 사용하여 파일에 데이터를 추가하는 방법까지 보여줍니다. 실행 후 파일 내용을 확인해 보세요! 놀라운 결과를 볼 수 있을 겁니다!

이처럼 C 언어에서는 fopen(), fclose(), fprintf(), fgets(), fwrite() 등의 함수를 사용하여 텍스트 파일을 효율적으로 다룰 수 있습니다. 다양한 파일 모드(“r”, “w”, “a” 등)를 활용하여 파일을 읽고, 쓰고, 수정하는 작업을 자유자재로 수행할 수 있으니, 여러분도 직접 코드를 작성하고 실행해 보면서 C 언어 파일 처리의 세계를 경험해 보시길 바랍니다!

 

지금까지 C 언어를 통해 텍스트 파일을 읽고 쓰는 다양한 방법에 대해 살펴보았습니다. 파일을 열고 닫는 기본적인 과정부터, fgetsfputs 함수를 사용한 읽기와 쓰기, 그리고 fprintf를 활용한 서식 있는 데이터 저장까지, 실제 코드 예제와 함께 각 기능을 명확하게 이해하셨기를 바랍니다. 이러한 기본적인 파일 입출력 기능은 C 언어 프로그래밍에서 데이터를 다루는 데에 필수적인 요소입니다. 다양한 응용 프로그램 개발에 활용될 수 있는 강력한 도구이므로, 익숙해질 때까지 여러 번 연습해 보는 것이 좋습니다. 더 나아가 파일의 존재 여부 확인, 오류 처리와 같은 고급 주제들을 탐구하여 더욱 견고한 프로그램을 만들어 보세요. 이를 통해 여러분의 C 프로그래밍 실력이 한층 더 향상될 것입니다.


코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다