【问题标题】:Exception thrown: write access violation. Variable was nullptr抛出异常:写入访问冲突。变量为 nullptr
【发布时间】:2022-12-20 09:18:25
【问题描述】:

我必须读取一个 .pgm 文件进行分配并解码每个字节中的最低有效位以获得一些隐藏文本。我有教授的读写代码,但是当我尝试读取文件颜色时,写入时出现问题。我想我知道如何真正取出隐藏的文本,但 I/O 总是给我带来麻烦。

在此先感谢您的帮助。

它不会让我添加 .pgm,所以我将它命名为 .png,所以如果你下载它,请确保将它重命名为 .pgm

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

typedef unsigned char uchar;

/****************************************/
/* Clear PGM (XV) comments.             */
/****************************************/
void pgmCommentClear(FILE* disk) {
    uchar  ch;
    fread(&ch, 1, 1, disk);
    if (ch != '#') {
        fseek(disk, -1, SEEK_CUR);
        return;
    }
    do {
        while (ch != '\n') fread(&ch, 1, 1, disk);
    } while (ch == '#');
    pgmCommentClear(disk);
}

/****************************************/
/* Read PGM formatted image (1D array). */
/****************************************/
uchar* PGM_FILE_READ_1D(char* FileName, int* Width, int* Height, int* color) {
    int   pmax;
    char  ch;
    char  type[3];
    uchar* Image;
    FILE* disk;
    if ((disk = fopen(FileName, "rb")) == NULL) {
        return NULL;
    }
    fscanf(disk, "%s", type);
    if (!strcmp(type, "P6")) *color = 1;
    else *color = 0;
    fread(&ch, 1, 1, disk);
    pgmCommentClear(disk);
    fscanf(disk, "%d", Width);
    fscanf(disk, "%d", Height);
    fscanf(disk, "%d", &pmax);
    fread(&ch, 1, 1, disk);
    if (*color == 1) {
        Image = (uchar*)calloc(*Height * *Width * 3, sizeof(uchar));
        fread(Image, 1, (*Height * *Width * 3), disk);
    }
    else {
        Image = (uchar*)calloc(*Height * *Width, sizeof(uchar));
        fread(Image, 1, (*Height * *Width), disk);
    }
    fclose(disk);
    return Image;
}

/****************************************/
/* Write PGM formatted image (1D array).*/
/****************************************/
void PGM_FILE_WRITE_1D(char* FileName, uchar* Image, int Width, int Height, int color) {
    FILE* disk;
    disk = fopen(FileName, "wb");
    if (color == 1) fprintf(disk, "P6\n");
    else fprintf(disk, "P5\n");
    fprintf(disk, "%d %d\n", Width, Height);
    fprintf(disk, "255\n");
    if (color == 1) {
        fwrite(Image, 1, (Height * Width * 3), disk);
    }
    else {
        fwrite(Image, 1, (Height * Width), disk);
    }
    fclose(disk);
}

int main(int argc, char const* argv[]) {


    // do command line args stuff for extra credit
    //if (argv == 2) { }

    // read the file
    //int width = 876
    //int height = 594
    
    uchar* image = PGM_FILE_READ_1D("./hw10.pgm", 876, 594, 0);

    printf("%c", *image);

}

【问题讨论】:

  • 该文件是二进制文件,在其上使用 scanf 是个坏主意。使用fread
  • 您需要将指针传递给 PGM_FILE_READ_ID 函数以获取高度、宽度和颜色。

标签: c image binary pgm


【解决方案1】:

很酷的任务,Ron Marsh ;-)

int main(int argc, char const* argv[]) {

    // do command line args stuff for extra credit
    //if (argv == 2) { }

    int width, height, color;
    
    // read the file
    uchar* image = PGM_FILE_READ_1D("./hw10.pgm", &width, &height, &color);
    printf("width = %d, height = %d, color = %d
", width, height, color);

    int size = width * height, bitCount = 8;
    uchar hiddenChar = 0;
    for (int i = 0; i < size; i++) {
        //shift least-significant bit left `bitCount` times and overlay onto `hidden`
        hiddenChar |= ((image[i] & 0x1) << --bitCount); 
        // After 8 bits we have the hidden byte
        if (bitCount == 0) {
            // If character is null terminator then we're done
            if (hiddenChar == 0) 
                break;
            // Print hidden character and reset
            printf("%c", hiddenChar);
            bitCount = 8;
            hiddenChar = 0;
        }
    }

    return 0;
}

【讨论】:

    【解决方案2】:

    解决方案非常简单。谢谢安东尼·凯利。

    改变了这一行:

    uchar* image = PGM_FILE_READ_1D("./hw10.pgm", 876, 594, 0);
    

    对此:

    int *width = 876;
    int *height = 594;
    int *color = 0;
    uchar* image = PGM_FILE_READ_1D("./hw10.pgm", &width, &height, &color);
    

    【讨论】:

    • 您将变量声明为指向整数的指针,但将它们视为普通整数。
    猜你喜欢
    • 1970-01-01
    • 2016-08-01
    • 2020-04-15
    • 1970-01-01
    • 1970-01-01
    • 2020-09-12
    • 2021-07-12
    • 2016-08-25
    • 2021-06-04
    相关资源
    最近更新 更多