2015-05-22 19 views
0

我正在编写用于将文件从PPM格式转换为ASCII art的程序。通过计算红色绿色和蓝色值((红色+绿色+蓝色)/ 3)的平均值,将输入图像的每个像素转换为灰度。基本版本的升级是,我计算了大小为n * n的窗口中RGB的平均值,这将减小图像的大小。输入文件由三行组成:第一个是我们想要转换的文件的名称,第二个是我们想要将转换后的图像写入的文件的名称,第三个是该窗口的大小(n)程序必须通过将图像转换为ASCII art来使用。我认为我在程序中实现了所有应用程序,并且它可以编译,但是当我测试它时,我会遇到分段错误。请问Anyoune请问问题出在哪里?用于ASCII艺术转换的c代码中的分割错误

下面是代码:

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

// convert the calculated greyscale to a character based on brightness 
char method_of_conversion(int greyscale){ 
    if(greyscale >= 230){ 
     return ' '; 
    }else if(greyscale >= 200 && greyscale < 230){ 
     return '.'; 
    }else if(greyscale >= 180 && greyscale < 200){ 
     return '\''; 
    }else if(greyscale >= 160 && greyscale < 180){ 
     return ':'; 
    }else if(greyscale >= 130 && greyscale < 160){ 
     return 'o'; 
    }else if(greyscale >= 100 && greyscale < 130){ 
     return '&'; 
    }else if(greyscale >= 70 && greyscale < 100){ 
     return '8'; 
    }else if(greyscale >= 50 && greyscale < 70){ 
     return '#'; 
    }else if(greyscale < 50){ 
     return '@'; 
    } 
} 

int main(){ 
    char ppmFile[100]; 
    char outputFile[100]; 

    int n; 

    scanf("%s", &ppmFile); //read the name of input file 
    scanf("%s", &outputFile); //read the name of output file 
    // the size of a window of pixels you have to convert to ascii art character 
    scanf("%d", &n); 

    FILE *input = fopen(ppmFile, "rb"); 
    FILE *output = fopen(outputFile, "w"); 


    char header[5]; //header = P6 
    fscanf(input, "%s\n", header); 
    int width, height, maxPixel; // max pixel is always 255 
    // read the header from the ppm file 
    fscanf(input, "%d %d %d\n", &width, &height, &maxPixel); 

    // allocate place for array[width][length][3] 
    int ***array; 
    array = malloc(width*sizeof(int **)); 
    array[0] = malloc(height*sizeof(int *)); 
    array[0][0] = malloc(3*sizeof(int)); 

    int x, y; 
    for (x = 0; x < width; x++){ 
     for(y=0; y < height; y++){ 
      array[x][y][0] = fgetc(input); //red 
      array[x][y][1] = fgetc(input); //green 
      array[x][y][2] = fgetc(input); //blue 

      int greyscale; 
      int i, j; 
      // convert blocks of pixels to a character and write it into output file 
      for(i = 0; i < width; i+=n){ 
       for(j=0; j < height; j+=n){ 
        // greyscale = (red + green +blue)/3; 
        greyscale = (array[x][y][0] + array[x][y][1] +array[x][y][2])/(3*n*n); 
        char c = method_of_conversion(greyscale); 
        fprintf(output,"%c",c); // write the ASCII art directly in the output file 
       } 
      } 
     }fprintf(output,"\n"); // dont forget to go into a new line 
    } 

    free(array); 
    fclose(input); 
    fclose(output); 

    return 0; 
} 
+0

你永远不会检查'fopen'的结果。或者任何其他文件IO功能。所以如果你的文件格式与你期望的有些不同,它会失败并崩溃。 –

回答

2
array = malloc(width*sizeof(int **)); 
array[0] = malloc(height*sizeof(int *)); 
array[0][0] = malloc(3*sizeof(int)); 

这里只array[0][0]分配,对于所有其他指标无分配情况。接下来的循环会尝试写入没有分配内存的索引,从而导致分段错误。

+0

所以......这意味着我应该添加for循环,对吧? – confused

+0

是的,您可以添加额外的循环来分配所有需要的内存。或者,您可以在已有的循环中对其进行分配,然后在读取值之前为每个数组索引分配内存。 – sth