pgm-file I / O给了我一半的数据

时间:2015-12-04 12:48:31

标签: c io pgm

所以我为pgm文件写了一个I / O.我的程序读取pgm并将其数据写入新的pgm文件。 但不知怎的,它只写了一半的数据,我花了几个小时搜索错误,但无法找到它。

以下是代码:

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

typedef struct {
    int row;
    int col;
    int max_greyscale;
    int **pixel_matrix;
} PGMData;

int **mem_alloc(int row, int col) {
    int **ret;

    ret = malloc(sizeof(int *) * row);
    if (ret == NULL) {
        perror("Error while allocating memory (NULL)");
        exit(EXIT_FAILURE);
    }

    for (int i = 0; i < row; i++) {
        ret[i] = malloc(sizeof(int) * col);
        if (ret[i] == NULL) {
            perror("Error while allocating memory (NULL)");
            exit(EXIT_FAILURE);
        }
    }
    return ret;
}

void destroy(int **pixel_matrix, int row) {
    for (int i = 0; i < row; i++) {
        free(pixel_matrix[i]);
    }
    free(pixel_matrix);
}

void ignoreComments(FILE *fp) {
    int c;
    char line[100];

    while((c = fgetc(fp)) != EOF && isspace(c))
        ;
    if (c == '#') {
        fgets(line, sizeof(line), fp);
        ignoreComments(fp);
    } else {
        fseek(fp, -1, SEEK_CUR);
    }
}

PGMData* readFile(const char *filename, PGMData *data) {
    FILE *fp;
    char magic[3];

    fp = fopen(filename, "r");
    if (fp == NULL) {
        perror("Error while reading file (NULL)");
        exit(EXIT_FAILURE);
    }

    fgets(magic, sizeof(magic), fp);

    ignoreComments(fp);
    fscanf(fp, "%d", &data->col);

    ignoreComments(fp);
    fscanf(fp, "%d", &data->row);

    ignoreComments(fp);
    fscanf(fp, "%d", &data->max_greyscale);

    fgetc(fp);
    data->pixel_matrix = mem_alloc(data->row, data->col);

    // read
    for (int i = 0; i < data->row; i++) {
        for (int j = 0; j < data->col; j++) {
            data->pixel_matrix[i][j] = fgetc(fp);
        }
    }
    fclose(fp);
    return data;
}

void writeFile(const char *filename, const PGMData *data) {
    FILE *fp;

    fp = fopen(filename, "w");
    if (fp == NULL) {
        perror("Error while writing file (NULL)");
        exit(EXIT_FAILURE);
    }

    fprintf(fp, "P2\n");
    fprintf(fp, "%d %d\n", data->col, data->row);
    fprintf(fp, "%d\n", data->max_greyscale);

    for (int i = 0; i < data->row; i++) {
        for (int j = 0; j < data->col; j++) {
            fputc(data->pixel_matrix[i][j], fp);
        }
    }

    fclose(fp);
    destroy(data->pixel_matrix, data->row);
}


int main(int argc, char *argv[]) {
    printf("P1\n");

    const char * source_file = argv[1]; // source
    const char * destin_file = argv[2]; // destination

    PGMData pgm_pic;
    PGMData * data = &pgm_pic;

    data = readFile(source_file, data); // read source
    writeFile(destin_file, data);       // write to destination

    return 0;
}

它为我提供了这个PGM:

P2
# feep.ascii.pgm
24 7
15
0 0  0  0  0  0  0  0  0 0  0  0  0  0  0  0  0 0  0  0  0  0  0  0
0 3  3  3  3  0  0  7  7 7  7  0  0 11 11 11 11 0  0 15 15 15 15  0
0 3  0  0  0  0  0  7  0 0  0  0  0 11  0  0  0 0  0 15  0  0 15  0
0 3  3  3  0  0  0  7  7 7  0  0  0 11 11 11  0 0  0 15 15 15 15  0
0 3  0  0  0  0  0  7  0 0  0  0  0 11  0  0  0 0  0 15  0  0  0  0
0 3  0  0  0  0  0  7  7 7  7  0  0 11 11 11 11 0  0 15  0  0  0  0
0 0  0  0  0  0  0  0  0 0  0  0  0  0  0  0  0 0  0  0  0  0  0  0

此输出:

P2
24 7
15
0 0  0  0  0  0  0  0  0 0  0  0  0  0  0  0  0 0  0  0  0  0  0  0
0 3  3  3  3  0  0  7  7 7  7  0  0 11 11 11 11 0  0 15 15 15 15  0
0 3  0  0  0  0  0  7  0 0  0  0

1 个答案:

答案 0 :(得分:1)

但P2格式将像素存储为从0到255的空格分隔的ASCII十进制数,如输入和输出所示,而不是单字节二进制值。您需要使用fscanf将每个像素值读取为十进制数,并使用fprintf将每个像素值打印为十进制数。                      - Ian Abbott