C 파일 포인터 부분적으로읽기쓰기 - sonkoni/Koni-Wiki GitHub Wiki

파일 포인터 옮겨 부분적으로 읽고 쓰기

부분적으로 읽기

  1. 진행 방향만큼 버퍼에 담는다.
  2. 이 만큼만 처리한다. (출력 등등)
  3. 버퍼를 초기화화 한 후 1로 돌아간다.
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) {
    char buffer[10] = {0,};
    FILE *fp = fopen("Hello.txt", "rt");

    fseek(fp, 2, SEEK_SET);
    fread(buffer, 3, 1, fp); // 3바이트만큼 1번 읽어옴
    printf("%s\n", buffer);

    memset(buffer, 0, 10); // 버퍼 초기화

    fseek(fp, 3, SEEK_CUR); // 현재 위치에서
    fread(buffer, 4, 1, fp); // 4바이트만큼 1번 읽어옴
    printf("%s\n", buffer);

    fclose(fp);
    return 0;
}
// llo
// orld
                  ┌fseek(fp, 2, SEEK_SET);
          ▼-------▼           ┌fread(buffer, 3, 1, fp);
                  └---------▷ ▼
          0───1───2───3───4───5───6───7───8───9───10──11──12──13
Hello.txt │ H │ e │ l │ l │ o │ , │   │ W │ o │ r │ l │ d │ ! │
          └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
                    l   l   o

                                          ┌fseek(fp, 3, SEEK_CUR);
                              ▼-----------▼               ┌fread(buffer, 4, 1, fp);
                                          └-------------▷ ▼
          0───1───2───3───4───5───6───7───8───9───10──11──12──13
Hello.txt │ H │ e │ l │ l │ o │ , │   │ W │ o │ r │ l │ d │ ! │
          └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
                                            o   r   l   d

부분적으로 쓰기

  1. 쓰고자 하는 포지션으로 파일포인터를 옮긴다.
  2. 쓰기를 시작(덮어쓴다)
  3. 처음으로 파일포인터를 옮긴다.
  4. 모두 읽어본다.
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) {
    char *str = "abcd";
    char buffer[20] = {0,};
    
    FILE *fp = fopen("Hello.txt", "r+t");
    
    fseek(fp, 3, SEEK_SET);
    fwrite(str, strlen(str), 1, fp);  // == fputs(str, fp);
    printf("pos: %ld\n", ftell(fp));
    
    rewind(fp);
    fread(buffer, 20, 1, fp); // == fgets(buffer, 20, fp);
    
    printf("(%ld)=> %s\n", ftell(fp), buffer);
    
    fclose(fp);
    return 0;
}
// pos: 7
// => HelabcdWorld!
r+ 로 열림: 파일이 존재해야 함. 해당 pos 에 덮어쓰기로 진행됨.
          ▼
          0───1───2───3───4───5───6───7───8───9───10──11──12──13
Hello.txt │ H │ e │ l │ l │ o │ , │   │ W │ o │ r │ l │ d │ ! │
          └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘

                      ┌ fseek(fp, 3, SEEK_SET);
                      ▼
          0───1───2───3───4───5───6───7───8───9───10──11──12──13
Hello.txt │ H │ e │ l │ l │ o │ , │   │ W │ o │ r │ l │ d │ ! │
          └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
                        a   b   c   d
                        └ fwrite(str, strlen(str), 1, fp);

                                      ▼
          0───1───2───3───4───5───6───7───8───9───10──11──12──13
Hello.txt │ H │ e │ l │ a │ b │ c │ d │ W │ o │ r │ l │ d │ ! │
          └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘

제한된 버퍼로 전페 파일 읽기

파일의 크기가 작으면 그냥 그 크가만큼 버퍼를 생성해서 한꺼번에 읽으면 된다. 하지만 파일의 크기가 크다면 파일 크기만큼 큰 버퍼를 생성하기에는 어려움이 있다. 이럴 때는 부분적으로 버퍼에 담아 파일 끝까지 진행한다.

  1. 루프로 파일 끝이 아닌 경우 계속 돌게 한다.(feof 활용)
    1. 루프 내에서 버퍼 크기만큼 읽어온다.
    2. 이를 처리한다 (출력 등등)
    3. 버퍼를 초기화하고 다시 루프 돈다.
  2. 파일이 끝일 경우 루프를 나와서 종료한다.
int  feof(파일포인터);       // 파일의 끝이면 1, 끝이 아니면 0 반환.
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) {
    char buffer[5] = {0,};
    int count = 0;
    int total = 0;
    
    FILE *fp = fopen("Hello.txt", "rt");
    
    while (feof(fp) == 0) {
        count = fread(buffer, sizeof(char), 4, fp);  // 1바이트씩 총 4번 읽기. 즉 4바이트 읽기
        printf("%s\n", buffer); // 읽어서 버퍼에 저장한 내용을 출력
        memset(buffer, 0, 5);   // 버퍼를 0으로 초기화
        total += count;         // 읽은 카운트 누적
    }
    
    printf("\ntotal: %d\n", total);
    fclose(fp);
    
    return 0;
}
// HelabcdWorld!
// total: 13
          0───1───2───3───4───5───6───7───8───9───10──11──12──13--+---+---+
Hello.txt │ H │ e │ l │ a │ b │ c │ d │ W │ o │ r │ l │ d │ ! │   ·   ·   ·
          └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘---+---+---+
          ▲               ▲               ▲               ▲   ▲ EOF 에서는 파일포인터가 더 진행하지 않는다. ftell 로 확인하면 여기 있다.
          |-fread-4bytes--|-fread-4bytes--|-fread-4bytes--|-fread-4bytes--|
⚠️ **GitHub.com Fallback** ⚠️