当前,我正在编写LZ77算法。当我尝试运行代码时,由于某种原因,我遇到了ZSH分段错误。我搜索了一些主题,但是找不到在哪里修复我的代码。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
/*#define pencereBoyutu 60
#define bufferBoyutu 40*/
typedef enum { false, true } bool;
// ============================================================================
int ortakBul(unsigned char window[], unsigned char str[], int strLen) {
int j, k, yer = -1;
int pencereBoyutu = 60;
for (int i = 0; i <= pencereBoyutu - strLen; i++) {
yer = k = i;
for (j = 0; j < strLen; j++) {
if (str[j] == window[k])
k++;
else
break;
}
if (j == strLen)
return yer;
}
return -1;
}
// ============================================================================
int compress(char* inputPath) {
FILE *fileInput;
FILE *fileOutput;
bool last = false;
int girisUzunlugu = 0;
int cikisUzunlugu = 0;
int setSonu = 0;
int yer = -1;
int i, size, shift, c_in;
size_t bytesRead = (size_t) -1;
int arrayBoyutu = 100;
int pencereBoyutu = 60;
int bufferBoyutu = 40;
unsigned char c;
unsigned char array[arrayBoyutu];
unsigned char window[pencereBoyutu];
unsigned char buffer[bufferBoyutu];
unsigned char bufferYukle[bufferBoyutu];
unsigned char str[bufferBoyutu];
// input out açmak
char path[30] = "";
strcat(path, inputPath);
fileInput = fopen(path, "rb");
fileOutput = fopen("output/output.lz77", "wb");
// mümkün değilse error ver
if (!fileInput) {
fprintf(stderr, "fileInput acilamiyor. %s", inputPath);
return 0;
}
// fileinput uzunluğunu çek
fseek(fileInput, 0, SEEK_END);
girisUzunlugu = ftell(fileInput);
fseek(fileInput, 0, SEEK_SET);
fprintf(stdout, "Giris dosyasi boyutu: %d byte", girisUzunlugu);
// dosya boşsa hata ver
if (girisUzunlugu == 0)
return 3;
// eğer dosya boyutu arrayboyutundan düşükse hata ver
if (girisUzunlugu < arrayBoyutu)
return 2;
// arrayı byte olarak oku
fread(array, 1, arrayBoyutu, fileInput);
fwrite(array, 1, pencereBoyutu, fileOutput);
// LZ77 mantığı
while (true) {
if ((c_in = fgetc(fileInput)) == EOF)
last = true;
else
c = (unsigned char) c_in;
for (int k = 0; k < pencereBoyutu; k++)
window[k] = array[k];
for (int k = pencereBoyutu, j = 0; k < arrayBoyutu; k++, j++) {
buffer[j] = array[k];
str[j] = array[k];
}
// en uzun ortak kelimeyi bulmak
if (setSonu != 0) {
size = bufferBoyutu - setSonu;
if (setSonu == bufferBoyutu)
break;
}
else {
size = bufferBoyutu;
}
yer = -1;
for (i = size; i > 0; i--) {
yer = ortakBul(window, str, i);
if (yer != -1)
break;
}
// hiç ortak bulunmaması halinde
if (yer == -1) {
fputc(255, fileOutput);
fputc(buffer[0], fileOutput);
shift = 1;
}
// ortak bulunması halinde
else {
fputc(pencereBoyutu - yer, fileOutput);
fputc(i, fileOutput);
if (i == bufferBoyutu) {
shift = bufferBoyutu + 1;
if (!last)
fputc(c, fileOutput);
else
setSonu = 1;
}
else {
if (i + setSonu != bufferBoyutu)
fputc(buffer[i], fileOutput);
else
break;
shift = i + 1;
}
}
// Shift buffer
for (int j = 0; j < arrayBoyutu - shift; j++)
array[j] = array[j + shift];
if (!last)
array[arrayBoyutu - shift] = c;
if (shift == 1 && last)
setSonu++;
if (shift != 1) {
// yeni bitler oku
bytesRead = fread(bufferYukle, 1, (size_t) shift - 1, fileInput);
// yeni bitleri arraya yükle
for (int k = 0, l = arrayBoyutu - shift + 1; k < shift - 1; k++, l++)
array[l] = bufferYukle[k];
if (last) {
setSonu += shift;
continue;
}
if (bytesRead < shift - 1)
setSonu = shift - 1 - bytesRead;
}
}
// fileoutput uzunluğunu çek
fseek(fileOutput, 0, SEEK_END);
cikisUzunlugu = ftell(fileOutput);
fseek(fileOutput, 0, SEEK_SET);
fprintf(stdout, "\nCikis dosya boyutu: %d byte\n", cikisUzunlugu);
// I/O dosyaları kapanması
fclose(fileInput);
fclose(fileOutput);
return 1;
}
// ============================================================================
// Decompress
int decompress() {
FILE *fileInput;
FILE *fileOutput;
int shift, denge, ortak, c_in;
bool done = false;
int pencereBoyutu = 60;
int bufferBoyutu = 40;
int arrayBoyutu = pencereBoyutu + bufferBoyutu;
unsigned char c;
unsigned char window[pencereBoyutu];
unsigned char writeBuffer[pencereBoyutu];
unsigned char readBuffer[2];
// i/o dosyalarin acilmasi
fileInput = fopen("output/output.lz77", "rb");
fileOutput = fopen("output/file", "wb");
if (!fileInput) {
fprintf(stderr, "fileInput açılamıyor. %s", "output.lz77");
return 0;
}
fread(window, 1, pencereBoyutu, fileInput);
fwrite(window, 1, pencereBoyutu, fileOutput);
// decompress mantığı
while (true) {
size_t bytesRead = fread(readBuffer, 1, 2, fileInput);
if (bytesRead >= 2) {
denge = (int) readBuffer[0];
ortak = (int) readBuffer[1];
if (denge == 255) {
denge = 0;
c = (unsigned char) ortak;
ortak = 0;
shift = ortak + 1;
}
else {
shift = ortak + 1;
c_in = fgetc(fileInput);
if (c_in == EOF)
done = true;
else
c = (unsigned char) c_in;
}
for (int i = 0, j = pencereBoyutu - denge; i < ortak; i++, j++)
writeBuffer[i] = window[j];
fwrite(writeBuffer, 1, (size_t) ortak, fileOutput);
if (!done)
fputc(c, fileOutput);
// Shift window
for (int i = 0; i < pencereBoyutu - shift; i++)
window[i] = window[i + shift];
for (int i = 0, j = pencereBoyutu - shift; i < ortak; i++, j++)
window[j] = writeBuffer[i];
window[pencereBoyutu - 1] = c;
}
else {
break;
}
}
// dosyaları kapat
fclose(fileInput);
fclose(fileOutput);
return 1;
}
// ============================================================================
int main(int argc, char* argv[]) {
clock_t begin = clock();
if (argc < 2) {
printf("2 argüman gerekiyor: [-c|-d] [dosya_yolu]");
} else {
// decompress
if (strcmp(argv[1], "-d") == 0) {
int result = decompress();
if (result == 0) {
fprintf(stderr, "\nSikistirma islemi HATALI");
} else if (result == 1) {
printf("\nSikistirma islemi OK");
}
}
// compress
else if (strcmp(argv[1], "-c") == 0) {
int result = compress(argv[2]);
if (result == 0) {
fprintf(stderr, "\nSikistirma islemi HATALI\n");
} else if (result == 1) {
printf("\nSikistirma islemi OK");
} else if (result == 2) {
fprintf(stderr, "\nDosya cok kucuk.\n");
} else if (result == 3) {
fprintf(stderr, "\nDosya bos.\n");
}
} else {
printf("Gecersiz argumanlar.");
}
}
// calistirma zamanını bastırmak
clock_t end = clock();
printf("\n\nCalistirma zamani: ");
printf("%f", ((double) (end - begin) / CLOCKS_PER_SEC));
printf(" [saniye]");
return 0;
}
// ============================================================================
编译后,您必须提供运行参数:
当我尝试使用上面包含100个字符的输入来运行我的应用程序时,这给我带来了分段错误。经过一些研究后,我找不到任何原因。如果有人可以帮助,我会很高兴。