涉及知识点:文件读写、位操作、内存管理、结构体定义、RLE算法、命令行参数
要求:编写一个程序,可以在命令行输入参数,完成指定文件的压缩解压命令行参数如下 [rle file1 c(-d) file2] 第一个参数为可执行程序名称,第二个参数为原始文件名,第三个参数为压缩或解压缩选项,第四个参数为新文件名
思路:
一,压缩函数,包括文件读取,压缩,文件编写保存
二,解压函数,包括文件读取,解压,文件编写保存
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
struct RleHeader
{
unsigned int originalSize;
unsigned int compressedSize;
};
void compressRle(const string &inputFile, const string &outputFile)
{
ifstream input(inputFile, ios::binary);
ofstream output(outputFile, ios::binary);
vector<char> buffer;
vector<char> tempData;
char currentChar;
char prevChar;
int count = 0;
int temp = 0;
while (input.get(currentChar))
{
if (count > 127)
{
buffer.push_back(127 | 0x80);
buffer.push_back(prevChar);
count -= 127;
}
if (currentChar == prevChar)
{
count++;
}
else
{
if (count >= 3)
{
if (temp == 0)
{
buffer.push_back(count | 0x80);
buffer.push_back(prevChar);
count = 1;
}
else
{
buffer.push_back(temp);
buffer.insert(buffer.end(), tempData.begin(), tempData.end());
tempData.clear();
temp = 0;
buffer.push_back(count | 0x80);
buffer.push_back(prevChar);
count = 1;
}
}
else
{
temp += count;
if (temp > 127)
{
temp -= count;
buffer.push_back(temp);
temp -= 127;
buffer.insert(buffer.end(), tempData.begin(), tempData.end());
tempData.clear();
temp += count;
}
while (count > 0)
{
tempData.push_back(prevChar);
count--;
}
count = 1;
}
}
prevChar = currentChar;
}
if (temp > 0)
{
buffer.push_back(temp);
buffer.insert(buffer.end(), tempData.begin(), tempData.end());
}
if (count > 0)
{
buffer.push_back(count | 0x80);
buffer.push_back(prevChar);
}
RleHeader header;
header.originalSize = static_cast<unsigned int>(input.tellg());
header.compressedSize = static_cast<unsigned int>(buffer.size());
output.write(reinterpret_cast<const char *>(&header), sizeof(RleHeader));
output.write(buffer.data(), buffer.size());
cout << "Compression completed." << endl;
}
void decompressRle(const string &inputFile, const string &outputFile)
{
ifstream input(inputFile, ios::binary);
ofstream output(outputFile, ios::binary);
RleHeader header;
input.read(reinterpret_cast<char *>(&header), sizeof(RleHeader));
vector<char> buffer(header.compressedSize);
input.read(buffer.data(), header.compressedSize);
for (size_t i = 0; i < buffer.size();)
{
char count = buffer[i];
if (count & 0x80) // 如果最高位为1,表示连续重复部分
{
char value = buffer[i + 1];
count &= 0x7F; // 清除最高位的标记位
for (int j = 0; j < count; j++)
{
output.put(value);
}
i += 2;
}
else // 连续非重复部分
{
while (count > 0)
{
char value = buffer[i + 1];
output.put(value);
i++;
count -= 1;
}
i++;
}
}
cout << "Decompression completed." << endl;
}
int main(int argc, char *argv[])
{
string inputFile = argv[1];
string option = argv[2];
string outputFile = argv[3];
if (option == "-c")
{
compressRle(inputFile, outputFile);
}
else if (option == "-d")
{
decompressRle(inputFile, outputFile);
}
return 0;
}
仅供参考