본문 바로가기
: ) 파일처리

[C언어_파일처리] 오프셋과 바이트 수를 이용해 파일에 있는 값 삭제하기 (delete)

by miiinn 2022. 4. 4.

OS : Linux 우분투 버전 18.04

컴파일러 : gcc 7.5

 

 

[명세]

이미 존재하는 파일에서 <오프셋(offset= 0, 1, 2, ...)>을 기준으로 왼쪽편 또는 오른쪽편에 존재하는 <바이트 수>의 절대값에 해당하는 크기의 데이터를 삭제한다. 만약 <바이트 수>가 양수이면 오른쪽편의 데이터를, 음수이면 왼쪽편의 데이터를 삭제한다. <바이트 수>가 0이면 데이터를 삭제할 필요가 없다. <바이트 수>의 절대값만큼의 데이터가 왼쪽 또는 오른쪽에 존재하지 않으면 존재하는 데이터만 삭제하면 된다. 예를 들면, <오프셋>이 10이고 <바이트 수>가 -5이면 오프셋 5부터 9까지 데이터를 삭제한다. 삭제 후 삭제 데이터를 기준으로 전후 데이터가 병합되어야 한다. 즉, 삭제 데이터만큼의 공간은 파일에서 사라져야 한다.
 
a.out <오프셋> <바이트 수> <파일명>

 

 

 

[소스 코드] - delete.c

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

int main(int argc, char *argv[]){
    int offset = atoi(argv[1]);
    int byte = atoi(argv[2]);
    FILE *fp = fopen(argv[3], "r+");

    if (byte==0){printf("바이트 수가 0 이므로 삭제할 필요가 없습니다.\n"); return 0;}

    int size;
    fseek(fp,0,SEEK_END);
    size = ftell(fp);

    fseek(fp, 0, SEEK_SET); // 다시 맨앞으로 이동

    char *buffer1 = (char *)malloc(sizeof(char *)*size);
    char *buffer2 = (char *)malloc(sizeof(char *)*size);
    memset(buffer1, 0, sizeof(buffer1));
    memset(buffer2, 0, sizeof(buffer2));

    int tmp = (size-1)-(offset+byte+1);

    if (byte>0) {
        //앞에꺼 복사
        fread(buffer1, sizeof(char), offset+1, fp); // 맨앞부터 offset까지 복사(offset은 0부터 시작하므로 offset까지 복사하려면 +1)
        // fp는 삭제할 데이터 시작에 위치
        fseek(fp, byte, SEEK_CUR); // 삭제할 만큼 뒤로 옮기기
        // fp는 현재 다시 쓸 뒷부분 시작에 위치

        fread(buffer2, sizeof(char), tmp ,fp); // 남은 뒷부분 읽어오기

        fclose(fp);
        FILE *rfp = fopen(argv[3], "w+"); // 파일 기존 내용 사라지게 다시 오픈
        fwrite(buffer1, sizeof(char), strlen(buffer1),rfp);
        fwrite(buffer2, sizeof(char), strlen(buffer2),rfp);

        fclose(rfp);
    }

    else if (byte < 0 ){
        //맨앞~offset까지 복사 - 만약 offset이 바이트보다 작으면 복사 안하기.
        
        if (offset > abs(byte)){ // offset이 더 크면 앞에 남은 내용 복사
            fread(buffer1, sizeof(char),(offset+byte), fp);
            // fp는 삭제할 데이터 시작에 위치
            fseek(fp, offset, SEEK_SET);
            //fp는 offset에 위치. 해당 offset부터 남은 뒷부분 복사
            fread(buffer2, sizeof(char), sizeof(buffer2), fp);

            fclose(fp);
            FILE *rfp = fopen(argv[3], "w+");
            fwrite(buffer1, sizeof(char), strlen(buffer1),rfp); // 있을 수도 있고 없을수도
            fwrite(buffer2, sizeof(char), strlen(buffer2),rfp);
            fclose(rfp);

        }

        else  {
            // offset==byte 거나 offset이 바이트보다 작으면 뒤에 내용만 복사
            
            fseek(fp, offset, SEEK_SET);
            //fp는 offset에 위치. 해당 offset부터 남은 뒷부분 복사
            //fread(buffer2, sizeof(char), (size-1)-offset, fp);
            fread(buffer2, sizeof(char), sizeof(buffer2), fp);

            fclose(fp);
            FILE *rfp = fopen(argv[3], "w+");
            fwrite(buffer2, sizeof(char), strlen(buffer2),rfp);
            fclose(rfp);
        }
    }

    return 0;
}