산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Industrial programming >> C 언어

C 파일 입출력 완벽 가이드: 열기, 읽기, 쓰기, 위치 제어, 바이너리 처리

파일 I/O는 데이터를 영구 저장하고 불러오는 핵심 기능입니다. C 표준 라이브러리의 FILE* 스트림 기반 고수준 함수와 주요 패턴을 실무 중심으로 정리합니다.

파일 열기: fopen

FILE *fopen(const char *pathname, const char *mode);

모드 문자열 상세

모드읽기쓰기생성잘림위치바이너리
rOXXX시작rb
wXOOO시작wb
aXOOX끝ab
r+OOXX시작rb+, r+b
w+OOOO시작wb+, w+b
a+OOOX끝ab+, a+b

팁: 텍스트 모드에서 윈도우는 \n ↔ \r\n 변환, 바이너리 모드(b)는 변환 없음.

파일 닫기: fclose

int fclose(FILE *stream);

텍스트 파일 읽기/쓰기

문자 단위

int fgetc(FILE *stream);      // 문자 읽기, EOF(-1) 반환 가능
int fputc(int c, FILE *stream); // 문자 쓰기

행 단위 (권장)

char *fgets(char *buf, int n, FILE *stream);  // n-1자 또는 개행까지
int fputs(const char *s, FILE *stream);       // 문자열 쓰기 (개행 안 함)

포맷 단위

int fprintf(FILE *stream, const char *format, ...);
int fscanf(FILE *stream, const char *format, ...);

예제: 설정 파일 파싱

// config.txt
// host=localhost
// port=8080
// debug=true

FILE *fp = fopen("config.txt", "r");
char line[256];
char key[64], value[128];

while (fgets(line, sizeof(line), fp)) {
    if (line[0] == '#' || line[0] == '\n') continue; // 주석/빈줄 스킵
    if (sscanf(line, "%63[^=]=%127[^\n]", key, value) == 2) {
        printf("설정: %s = %s\n", key, value);
    }
}
fclose(fp);

바이너리 파일 읽기/쓰기

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

예제: 구조체 배열 저장/로드

#define MAX_RECORDS 1000

struct Record {
    int id;
    char name[32];
    double score;
};

int save_records(const char *path, struct Record *recs, int count) {
    FILE *fp = fopen(path, "wb");
    if (!fp) return -1;
    size_t written = fwrite(recs, sizeof(struct Record), count, fp);
    fclose(fp);
    return (written == count) ? 0 : -1;
}

int load_records(const char *path, struct Record *recs, int max_count) {
    FILE *fp = fopen(path, "rb");
    if (!fp) return -1;
    size_t read = fread(recs, sizeof(struct Record), max_count, fp);
    fclose(fp);
    return (int)read;
}

파일 위치 제어 (Random Access)

fseek 기준점 (whence)

예제: 파일 크기 구하기

long file_size(FILE *fp) {
    long cur = ftell(fp);
    fseek(fp, 0, SEEK_END);
    long size = ftell(fp);
    fseek(fp, cur, SEEK_SET);
    return size;
}

// 또는 (C11)
#include <stdio.h>
long size = 0;
fseek(fp, 0, SEEK_END);
size = ftell(fp);

예제: 고정 레코드 랜덤 액세스

struct Record read_record(FILE *fp, long index) {
    struct Record rec;
    fseek(fp, index * sizeof(struct Record), SEEK_SET);
    fread(&rec, sizeof(rec), 1, fp);
    return rec;
}

에러 처리와 상태 확인

함수원형설명
ftelllong ftell(FILE *stream)현재 위치 반환 (바이트 오프셋)
fseekint fseek(FILE *stream, long offset, int whence)위치 이동
rewindvoid rewind(FILE *stream)시작으로 이동 + 에러 클리어
fgetposint fgetpos(FILE *stream, fpos_t *pos)이식성 좋은 위치 저장
fsetposint fsetpos(FILE *stream, const fpos_t *pos)저장된 위치로 복원

올바른 EOF 검사 패턴

// 잘못: feof()로 루프 제어
while (!feof(fp)) {  // 마지막 읽기 후 feof 설정 전 루프 한 번 더 돔
    fgets(buf, sizeof(buf), fp);
}

// 올바름: 읽기 함수 반환값으로 제어
while (fgets(buf, sizeof(buf), fp)) {
    // 처리
}
if (ferror(fp)) {
    perror("읽기 오류");
}

임시 파일

FILE *tmp = tmpfile();  // 자동 삭제되는 임시 파일 (wb+ 모드)
char tmpl[] = "/tmp/myprefixXXXXXX";
int fd = mkstemp(tmpl);  // 안전한 임시 파일 생성 (POSIX)
FILE *fp = fdopen(fd, "w+b");

버퍼링 제어

void setbuf(FILE *stream, char *buf);      // 버퍼 지정 (NULL=무버퍼)
int setvbuf(FILE *stream, char *buf, int mode, size_t size);
// mode: _IOFBF(완전버퍼), _IOLBF(줄버퍼), _IONBF(무버퍼)

모범 사례 체크리스트

C 언어

  1. C 입출력(I/O) 마스터: scanf()와 printf() 완전 정복
  2. C 파일 입출력: fopen, fprintf, fread, fseek 마스터하기
  3. Python 파일 입출력: 파일 연산, 읽기, 쓰기, 관리 마스터하기
  4. Axiomtek IPS960-511-PoE: 산업용 검사를 위한 올인원 러기드 비전 컨트롤러
  5. 아씨드(acceed) EDAM-4200 시리즈: 확장 가능하고 신뢰성 높은 데이터 통신을 위한 통합 I/O 모듈
  6. C 함수 마스터: 선언, 정의, 호출, 인자 전달(값/참조), 재귀
  7. C 헤더 파일 이해: 유형, 사용법, 모범 사례
  8. I/O 카드 설명: 작동 원리와 중요성
  9. MATLAB 데이터 내보내기: 파일 형식과 기법 총정리
  10. C# 파일 입출력 마스터하기: 스트림, 읽기/쓰기, 고급 파일 작업
함수/매크로용도
ferror(fp)에러 플래그 확인 (0 아님 = 에러)
feof(fp)EOF 플래그 확인 (읽기 시도 후 EOF 도달 시 설정)
clearerr(fp)에러/EOF 플래그 초기화
perror(msg)errno 기반 에러 메시지 출력