[C언어] 파일 압축/해제 프로그램 만들기
프로그램 설명
data.txt 라는 파일이 주어집니다.
이 파일을 압축해서 새로운 압축 파일을 생성합니다.
압축파일의 크기가 원래 파일보다 크기가 작다는 것을 보여줍니다.
압축파일을 해제하여 복구파일을 만들어냅니다.
이 복구 파일이 원본 파일과 동일하다는 것을 보여줍니다.
요구 사항
프로그램은 압축하는 것, 해제하는 것, 2개를 작성해야 합니다.
압축률: 기존 파일 크기 대비 80%보다는 작아야 합니다.
예를 들어, 기존 파일크기가 100이면, 압축파일 크기는 80보다 작아야 합니다.
전체 코드
https://github.com/gayeonP/C-file-zip-unzip
GitHub - gayeonP/C-file-zip-unzip: c언어 파일 압축/해체 배치 프로그램
c언어 파일 압축/해체 배치 프로그램. Contribute to gayeonP/C-file-zip-unzip development by creating an account on GitHub.
github.com
코드 설명
main.c 에 전부 구현했습니다.
main 함수
int main(int argc, char* argv[]) {
FILE* fp = NULL; // open
FILE* fw = NULL; // write
// 0 입력: 압축
// 1 입력: 압축 해제
int a = 0;
printf("압축: 0\n압축해제: 1\n입력: ");
int res = scanf("%d", &a);
if (a) res = unzip(fp, fw);
else res = zip(fp, fw);
if (res == 0) printf("성공\n");
else printf("실패\n");
return 0;
}
먼저 파일 읽기와 쓰기를 해줄 FILE 포인터를 선언합니다.
배치 프로그램을 돋보이게 하기 위해 나름 GUI도 만들었습니다.
0을 누르면 압축. 1을 누르면 압축 해제가 되도록 해줍니다. 0 -> 1 순서대로 입력해야 정상 작동입니다.
물론 정상적으로 작동하지 않을 경우를 대비해 예외 처리를 해줍니다. zip과 unzip 함수의 return 값이 0이어야 정상적으로 작동된 것입니다. 그렇지 않을 경우에는 실패라고 판단합니다.
사용자가 0 또는 1이 아닌 수를 입력했을 때 예외처리는 완벽하지 않습니다. 그 경우는 없는걸로 가정했습니다.
다만 압축을 하지 않고 바로 해제를 할 경우는 실패라는 문구가 보이도록 했습니다.
zip 함수
int zip(FILE* fp, FILE* fw) {
char str[MAX_SIZE + 1];
if ((fp = fopen("data.txt", "rt")) == NULL) { // file open & error checking
printf("unable to open file\n");
return -1;
}
if ((fw = fopen("datazip.txt", "wt")) == NULL) { // file write & error checking
printf("unable to write file\n");
return -1;
}
int cnt = 0; // count var
char ch = 0; // checking var
while (fgets(str, sizeof(str), fp) != NULL) {
ch = str[0];
for (unsigned int i = 0; i < strlen(str); i++) {
if (ch == str[i]) {
cnt++;
// 파일의 끝이 마지막인것을 검사
if ((strlen(str) != MAX_SIZE) && (i == strlen(str) - 1)) {
fprintf(fw, "%c%d", ch, cnt);
ch = str[i];
cnt = 1;
}
}
else {
fprintf(fw, "%c%d", ch, cnt);
ch = str[i];
cnt = 1;
}
}
}
fclose(fp);
fclose(fw);
return 0;
}
먼저, 어떻게 압축을 할 것인가? 에 대한 답은 data.txt 파일을 보시면 알 수 있습니다.
JJJJJJJJJJJJJJJJJJJJJJJJJJttttttt
이런식으로 같은 알파벳이 반복되어 나타납니다. 그렇다면 J26t7 이런 형식으로 압축 파일을 만들어 줄 겁니다.
반복된 알파벳을 쓰고 그다음에 몇 번 반복되었는지 기록하는 식입니다.
1. 열고자 하는 파일이 있는지 검사
2. 파일을 쓸 수 있는지 검사
3. 10000개씩 datazip.txt 파일에 작성
3-1. 만일 파일의 끝이라면 while 문을 탈출해 적을 수 없음으로 파일에 쓰는 코드를 한 번 더 넣어줌
4. 스트림 닫기
5. 정상적으로 끝남을 알리는 0 리턴
unzip 함수
int unzip(FILE* fp, FILE* fw) {
if ((fp = fopen("datazip.txt", "rt")) == NULL) { // file open & error checking
printf("unable to open file\n");
return -1;
}
if ((fw = fopen("datanew.txt", "wt")) == NULL) { // file write & error checking
printf("unable to write file\n");
return -1;
}
char c = 0; // 알파벳을 담을 변수
int d = 0; // count, 숫자를 담을 변수
while (fscanf(fp, "%c%d", &c, &d) != EOF) {
for (int i = 0; i < d; i++) {
fputc(c, fw);
}
}
fclose(fp);
fclose(fw);
return 0;
}
압축을 푸는 것은 쉽습니다. 알파벳과 숫자를 읽고 그 숫자만큼 알파벳을 반복적으로 쓰면 됩니다.
1. datazip 파일이 존재하는 검사
2. 파일을 쓸 수 있는지 검사
3. datazip 파일 끝까지 돌면서 파일 쓰기
4. 스트림 닫기
5. 정상적으로 끝남을 알리는 0 리턴
결과
153KB -> 26KB 로 감소하였습니다. 원본 크기에 비해 16.9%로 감소했습니다.
과제할 때 동영상도 찍었어야 했는데요.. 첨부합니다..
https://www.youtube.com/watch?v=5Zq5m7uRJi0
학교 C언어프로그래밍 과제였습니다.
안녕히계세요뿅