0

我正在尝试读取一个 pgm 文件并将其放入一个数组中以进行分配,然后我将它放在可以将每一行放入一个字符串的位置,然后我尝试对每一行进行 sscanf 以获取值,但它总是将零放入对于 num 不管它是什么。它可能与 pgm 文件有关,每列之间有 1 或 2 个空格,但我不确定`

int **image = (int**) malloc(*numCols * sizeof(int*));
int i;
for(i = 0; i < *numCols; i++)
{
    image[i] = (int *) malloc(*numRows * sizeof(int));
}


int r,c;
int num = 0;
char *line = (char *) malloc(*numCols * sizeof(char));
for(r = 0; r < *numRows; r++)
{
    int number = (*numCols * sizeof(int));
    fgets(line, number, in);

    for(c = 0; c < *numCols; c++)
    {
        sscanf(line,"%d",&num);
        printf("%d",num);
        image[r][c] = num;
    }
    sscanf(line,"%*[\n]");
    printf("\n");
}
return image;
4

2 回答 2

2

PGM 文件不以数字开头,请使用文本编辑器打开文件以查找其格式。另一个问题是,如果你sscanf()这样使用,你只会永久读取第一个数字,也许你需要strtok()代替或像这样:

int offset = 0, readCount;
for(c = 0; c < *numCols; c++)
{
    sscanf(line + offset,"%d%n",&num, &readCount);
    printf("%d",num);
    image[r][c] = num;
    offset += readCount;
}
于 2014-03-08T03:35:57.977 回答
2

这里有很多问题。存在内存分配问题以及逻辑问题。

首先,你有一个缓冲区溢出。*numCols您在第二部分malloc字节,然后以*numCols * sizeof(int)字节为单位读取。实际上,行的长度至少需要与 PGM 文件中最长的行一样长。这与此无关sizeof(int)- 以文本形式编写的数字最多可以占用 10 个字符(如果是 64 位 int,则为 20 个)。然后是数字之间的空格。

其次,你的行和列的方式错误,你的分配应该是:

int **image = malloc( *numRows * sizeof *image );
for (int i = 0; i < *numRows; ++i)
    image[i] = malloc( *numCols * sizeof *image[i] );

(请注意我的 malloc 没有充满疣)。

第三,你应该检查的结果sscanf。也许正在发生的事情是读取失败(即那里没有任何数字),因此num保留其先前的值。当且仅当它成功时sscanf才会返回。1

即使成功了,你也会经历一个循环并sscanf(line,"%d",&num)一遍又一遍地调用。这只会一遍又一遍地阅读该行的第一项。如果您想读取该行的第二个数字,则必须从刚刚读取的数字之后开始,而不是每次都从该行的开头开始。实际上这并不简单,所以我建议您使用strtol而不是读取数字sscanf

最后,sscanf(line,"%*[\n]");一点效果都没有。似乎您认为line每次调用都会消耗掉sscanf,但实际上并没有发生;line不是输入流,它是一个字符数组。

我猜您可能还想在输入文件中“移至下一行”。您目前没有任何代码可以做到这一点;您需要检测是否fgets到达了输入行的末尾,如果没有,则继续阅读,直到您到达行尾并丢弃这些字符。

注意。我假设您在实际显示的代码之前还有一些代码,用于读取 PGM 文件的标题,然后再开始读取图像数据。

于 2014-03-08T03:43:25.223 回答