我正在尝试读取一个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;
答案 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文件的标题。