C sscanf()在读取pgm文件时返回零

时间:2014-03-08 03:08:58

标签: c scanf pgm

我正在尝试读取一个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;

2 个答案:

答案 0 :(得分:2)

PGM file不以数字开头,使用文本编辑器打开文件以查找其格式。另一个问题是,如果你使用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;
}

答案 1 :(得分:2)

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

首先,你有一个缓冲区溢出。您在第二部分中使用了malloc *numCols个字节,但随后读入了*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] );

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

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

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

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

我猜你也许想在输入文件中“移动到下一行”。您目前没有任何代码可以执行此操作;您需要检测您的fgets是否到达输入行的末尾,如果没有,则读取直到您到达行尾并丢弃这些字符。

NB。我假设您在实际显示的代码之前还有一些代码,它会在读取图像数据之前读取PGM文件的标题。