用c语言编写一个程序,可以在命令行输入参数,完成指定文件的压缩解压 命令行参数如下 rle file1 –c(-d) file2 第一个参数为可执行程序名称,第二个参数为原始文件名,第三个参数为压缩或解压缩选项,第四个参数为新文件名
时间: 2024-02-18 15:05:45 浏览: 22
好的,下面是一个可以完成你所需功能的C语言程序:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <zlib.h>
#define CHUNK_SIZE 1024 // 每次读写的块大小
// 压缩函数
int compress_file(const char* source_filepath, const char* dest_filepath) {
FILE* source_file = fopen(source_filepath, "rb");
if (!source_file) {
fprintf(stderr, "Error: Failed to open source file %s: %s\n", source_filepath, strerror(errno));
return -1;
}
FILE* dest_file = fopen(dest_filepath, "wb");
if (!dest_file) {
fprintf(stderr, "Error: Failed to open destination file %s: %s\n", dest_filepath, strerror(errno));
fclose(source_file);
return -1;
}
// 初始化压缩器
z_stream zstream;
memset(&zstream, 0, sizeof(zstream));
if (deflateInit(&zstream, Z_DEFAULT_COMPRESSION) != Z_OK) {
fprintf(stderr, "Error: Failed to initialize zlib deflate\n");
fclose(source_file);
fclose(dest_file);
return -1;
}
// 读取并压缩数据
unsigned char inbuf[CHUNK_SIZE];
unsigned char outbuf[CHUNK_SIZE];
int ret = Z_OK;
while (!feof(source_file)) {
zstream.avail_in = fread(inbuf, 1, CHUNK_SIZE, source_file);
if (ferror(source_file)) {
fprintf(stderr, "Error: Failed to read source file %s\n", source_filepath);
ret = Z_ERRNO;
break;
}
zstream.next_in = inbuf;
do {
zstream.avail_out = CHUNK_SIZE;
zstream.next_out = outbuf;
ret = deflate(&zstream, feof(source_file) ? Z_FINISH : Z_NO_FLUSH);
if (ret != Z_OK && ret != Z_STREAM_END) {
fprintf(stderr, "Error: zlib deflate failed\n");
break;
}
fwrite(outbuf, 1, CHUNK_SIZE - zstream.avail_out, dest_file);
if (ferror(dest_file)) {
fprintf(stderr, "Error: Failed to write destination file %s\n", dest_filepath);
ret = Z_ERRNO;
break;
}
} while (zstream.avail_out == 0);
}
// 清理
deflateEnd(&zstream);
fclose(source_file);
fclose(dest_file);
return ret == Z_STREAM_END ? 0 : -1;
}
// 解压缩函数
int decompress_file(const char* source_filepath, const char* dest_filepath) {
FILE* source_file = fopen(source_filepath, "rb");
if (!source_file) {
fprintf(stderr, "Error: Failed to open source file %s: %s\n", source_filepath, strerror(errno));
return -1;
}
FILE* dest_file = fopen(dest_filepath, "wb");
if (!dest_file) {
fprintf(stderr, "Error: Failed to open destination file %s: %s\n", dest_filepath, strerror(errno));
fclose(source_file);
return -1;
}
// 初始化解压器
z_stream zstream;
memset(&zstream, 0, sizeof(zstream));
if (inflateInit(&zstream) != Z_OK) {
fprintf(stderr, "Error: Failed to initialize zlib inflate\n");
fclose(source_file);
fclose(dest_file);
return -1;
}
// 读取并解压数据
unsigned char inbuf[CHUNK_SIZE];
unsigned char outbuf[CHUNK_SIZE];
int ret = Z_OK;
while (!feof(source_file)) {
zstream.avail_in = fread(inbuf, 1, CHUNK_SIZE, source_file);
if (ferror(source_file)) {
fprintf(stderr, "Error: Failed to read source file %s\n", source_filepath);
ret = Z_ERRNO;
break;
}
zstream.next_in = inbuf;
do {
zstream.avail_out = CHUNK_SIZE;
zstream.next_out = outbuf;
ret = inflate(&zstream, feof(source_file) ? Z_FINISH : Z_NO_FLUSH);
if (ret != Z_OK && ret != Z_STREAM_END) {
fprintf(stderr, "Error: zlib inflate failed\n");
break;
}
fwrite(outbuf, 1, CHUNK_SIZE - zstream.avail_out, dest_file);
if (ferror(dest_file)) {
fprintf(stderr, "Error: Failed to write destination file %s\n", dest_filepath);
ret = Z_ERRNO;
break;
}
} while (zstream.avail_out == 0);
}
// 清理
inflateEnd(&zstream);
fclose(source_file);
fclose(dest_file);
return ret == Z_STREAM_END ? 0 : -1;
}
int main(int argc, char* argv[]) {
// 检查参数个数
if (argc != 5) {
fprintf(stderr, "Usage: %s source_filepath -c/-d dest_filepath\n", argv[0]);
return -1;
}
// 解析参数
const char* source_filepath = argv[1];
const char* dest_filepath = argv[4];
int is_compress = 0;
if (strcmp(argv[2], "-c") == 0) {
is_compress = 1;
} else if (strcmp(argv[2], "-d") == 0) {
is_compress = 0;
} else {
fprintf(stderr, "Error: Invalid option %s\n", argv[2]);
return -1;
}
// 执行压缩或解压缩
int ret = -1;
if (is_compress) {
ret = compress_file(source_filepath, dest_filepath);
if (ret == 0) {
printf("Compress %s -> %s succeeded\n", source_filepath, dest_filepath);
} else {
fprintf(stderr, "Error: Compress %s -> %s failed\n", source_filepath, dest_filepath);
}
} else {
ret = decompress_file(source_filepath, dest_filepath);
if (ret == 0) {
printf("Decompress %s -> %s succeeded\n", source_filepath, dest_filepath);
} else {
fprintf(stderr, "Error: Decompress %s -> %s failed\n", source_filepath, dest_filepath);
}
}
return ret;
}
```
这个程序的基本思路是先读取命令行参数,根据参数来判断是执行压缩还是解压缩操作,然后调用对应的压缩或解压缩函数,最后输出结果。其中压缩和解压缩函数使用了 zlib 库,实现了基本的 RLE 压缩算法。注意要在编译时链接 zlib 库。