c-读取pgm文件



你好,我有一个关于读取pgm值底部值的问题。我制作了一个二维dyanmic数组,并为高度和宽度添加了2个额外的空间,以便能够创建缓冲区,但当我尝试读取宽度+1的第一个整数时,它不起作用。有线索表明代码为什么停在这里吗?

FILE *pfile; //pointer to file
pfile=fopen(input_pgm,"r");
int columns,rows,value,line_of_numbers;
char pformat[50];
    if (pfile==NULL){
        printf("File is empty lame-on");
                    }
    else{                                 //Read from file
        fscanf(pfile,"%s",pformat);     //Things like P2,P5
        fscanf(pfile,"%d",&columns);     //Number of columns ,M, Need & or it will store it into address
        fscanf(pfile,"%d",&rows);        //Number of rows , N
        fscanf(pfile,"%d",&value);       //Number of value, W
        //Allocating 2D array to store M numbers
        //printf("Test");
        int **board;
        board = (int **)malloc((rows + 2) * sizeof(int *));
        for (i=0;i<rows+2;i++){
            board[i]=(int*)malloc((columns+2)*sizeof(int));
             }
        //printf("Test2");
        //INITILIZING TO 0
        board=memset(board,0,((columns+2)*(rows+2)));
        //printf("Test");
        //reading in numbers on to board from 1->/rows/columns+1
        for(i=1;i<=rows+1;i++){
            for(j=1;j<=columns+1;j++){
                //printf("Test3");   /*does not work after this*/
                int scanned_num;
                fscanf(pfile,"%d",&scanned_num);
                board[i][j]=scanned_num;}
        }

您似乎将指针的动态数组(,即board的引用)与2D数组混淆了。这些根本不是一回事。请特别注意,您为board分配内存,如下所示:

board = (int **)malloc((rows + 2) * sizeof(int *));

这分配了足够的内存来保存指向introws + 2指针。(请注意,演员阵容是不必要的,许多人认为这是糟糕的风格。)那么这样做怎么有意义呢。。。

board=memset(board,0,((columns+2)*(rows+2)));

除了将结果分配给board是无用的这一事实之外,是什么让你认为空间——rows + 2指向int的指针的大小——必须至少是((columns+2)*(rows+2))字节除非columns很小,否则您将超出*board的界限,从而产生未定义的行为

此外,还会覆盖刚刚在*board中记录的所有行指针,破坏它们,从而泄漏为行内容分配的所有内存如果您的程序在这一点上没有崩溃,而是继续根据C语义执行其余代码,那么当您试图在读取循环(board[i][j]=scanned_num)中取消引用这些指针时,您随后会调用更多未定义的行为。还要注意,即使board2D阵列,您设置的字节数也不会正确,因为每个int都大于一个字节。

将光栅分配为一个大块是有意义的,而且更容易。如果您至少使用C99,那么最简单的方法是通过可变长度阵列:

int board[rows + 2][columns + 2];
memset(board, 0, sizeof(board));

然后,您甚至不需要在之后解除分配,尽管出于同样的原因,数组无法在函数执行结束后幸存下来。

如果你需要一些可以从函数返回的东西,那么你可以这样做:

int (*board)[columns + 2];
board = calloc(rows + 2, sizeof(*board));

在这种情况下,calloc()会自动将分配的空间初始化为全零,因此您不需要自己进行初始化。

无论哪种方式,它都会获取所需的空间并用零填充;不需要做任何其他事情来准备它接收数据。还要注意的是,正如在第二种情况下只使用一个calloc()调用一样,在完成动态分配的空间时,应该使用一个相应的free()调用。

最新更新