2016-04-01 73 views
0

您好,我有一個關於讀取pgm值的底部值的問題。我已經創建了一個2d的dyanmic數組,並且已經爲高度和寬度添加了2個額外的空間,以便能夠創建一個緩衝區當我試圖讀取第一個整數到寬度+ 1它不起作用。任何線索爲什麼代碼停在這裏?閱讀一個pgm文件

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-o\n"); 
        } 
    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;} 
     } 
+0

問題可能在任何地方。請閱讀如何提供[mcve]。 – user694733

+1

請注意,當'fopen()'返回NULL時,這意味着該文件無法打開,**不**該文件爲空。它可能不存在,或者程序可能沒有被授權訪問它,或者可能有其他一些問題。可以打開一個空文件,如果你通過'fopen()'成功完成,那麼它返回的指針是* not *'NULL'。 –

+0

定義「不起作用」。 –

回答

0

您似乎混淆指針的動態陣列(board指涉)與2D陣列。這些並不完全相同。請特別注意,您board分配內存,如下所示:

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

這下發的內存足以容納rows + 2指針int。 (請注意,演員是不必要的,許多人認爲風格差。)那麼如何是否有意義做到這一點...

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),則會引發更多未定義的行爲。請注意,即使board二維數組,每個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()調用。

+0

對不起,我對C不太熟悉,但是當我嘗試memset時,我試圖讓每個電路板的索引都等於0,然後我試着從索引1讀到行+1。 –

+0

@ What's_sarcasm,我也應該指出,你讀取和忽略的'pformat'字符串是重要的。這是文件的「幻數」,它告訴你文件寫入的格式。標準PGM的值爲「P5」。您讀取像素柵格的代碼似乎會呈現「普通」PGM格式,其幻數爲「P2」。如果你確實打算只支持後者,那麼你應該拒絕沒有正確幻數的文件。如果你打算同時支持,那麼你需要額外的P5代碼。 –