2013-10-28 36 views
1

我想使用函數從文本文檔動態地構造C中的矩陣。 我使用calloc製作矩陣時遇到了問題,可能在給矩陣元素賦值時,我找不到任何東西。我可以處理一個矢量。我有問題,使用calloc來處理矩陣的功能

代碼在這裏:

#include <stdio.h> 
#include <stdlib.h> 

void beolvas_ellista(int *, int *, int *, int *, int ***, char *); 

int main() 
{ 
    int ir, suly, csom, el, i, **ellista; 

    //The following commented code works 
    /*FILE * f; 
    f=fopen("be.txt","r"); 

    fscanf(f,"%d",&ir); 
    fscanf(f,"%d",&suly); 
    fscanf(f,"%d",&csom); 
    fscanf(f,"%d",&el); 

    ellista=(int **)calloc(2,sizeof(int *)); 
    for(i=0;i<el;++i) 
    { 
     ellista[i]=(int *)calloc(el,sizeof(int)); 
    } 
    i=0; 
    while(!feof(f)) 
    { 
     fscanf(f,"%d",&ellista[0][i]); 
     fscanf(f,"%d",&ellista[1][i]); 
     ++i; 
    } 

    for(i=0;i<el;++i) 
     printf("%d %d\n",ellista[0][i],ellista[1][i]); 

    fclose(f);*/ 

    beolvas_ellista(&ir, &suly, &csom, &el, &ellista, "be.txt"); 

    for(i=0;i<el;++i) 
     printf("%d %d\n",ellista[0][i],ellista[1][i]); 

    return 0; 
} 

void beolvas_ellista(int *ir, int *suly, int *csom, int *el, int ***ellista, char *allomany) 
{ 
    int i; 
    FILE * f; 
    f=fopen(allomany,"r"); 

    fscanf(f,"%d",ir); 
    fscanf(f,"%d",suly); 
    fscanf(f,"%d",csom); 
    fscanf(f,"%d",el); 

    *ellista=(int **)calloc(2,sizeof(int *)); 
    for(i=0;i<*el;++i) 
    { 
     *ellista[i]=(int *)calloc(*el,sizeof(int)); 
    } 

    i=0; 
    while(!feof(f)) 
    { 
     fscanf(f,"%d",ellista[0][i]); 
     fscanf(f,"%d",ellista[1][i]); 
     ++i; 
    } 

    fclose(f); 
} 

這裏是文本文件:

be.txt

0 0 
7 8 
1 2 
1 3 
2 3 
3 4 
4 5 
4 6 
5 7 
6 7 

而且,這裏是我用來收集信息的代碼:

void beolvas(int*pn, int**pa, char*allomany) 
{ 
int i;FILE*f; 
f=fopen(allomany,"r"); 
fscanf(f,"%d",pn); 
*pa=(int*)malloc((*pn)*sizeof(int)); 
for(i=0; i<*pn; i++) 
fscanf(f,"%d",(*pa)+i); 
fclose(f); 
} 
main() 
{ 
int n, *a; 
beolvas(&n, &a, "be.txt"); 
... 
} 
+0

'INT ***'是的,你正在做的事情非常,非常* *錯誤的符號。 – 2013-10-28 20:00:18

+0

@ H2CO3如果還有更好的方法可以,請給我舉個例子,我只知道這種類型的透射二維矩陣是一個點。 – Miklosflame

+0

我建議你使用一個真正的二維數組(或至少一個指向其第一個元素的指針):int(* arr)[COLS] = malloc格式化您的代碼(使用縮進,空格)並使用英文函數和變量名稱,以便代碼更易於閱讀。 – 2013-10-29 05:16:06

回答

0

以下項目符號列表錯在你的函數的項目。

  • 你沒有正確地使用feof()爲您while循環的中斷狀態。 See this question獲取更多信息。

  • 您忽略了fscanf()的返回結果,因此無法保證所有參數解析成功與否。 See the documentation of fscanf()

  • 您的代碼不適合文件內容的模型。根據您的代碼,文件應分別將ir,sulycsomel設置爲值00,78。然後您分配空間準確地兩個指針到int,保存結果在ellista,然後繼續索引到*ellista達到el項目,這顯然是而不是2。既不完全清楚也不明顯,你需要一個2×N矩陣或一個N×2矩陣,並且寫入的代碼確實沒有。

  • 文體,但有幫助:你應該設置你的外部參數成功你的功能,而不是在初始入口或解析。例如:根據函數的成功,您的ellista地址參數應該設置爲最後的操作,而不是第一個操作。聲明本地int** local;臨時變量,運行你的算法填充,並在成功設置出參數。

所有的說,我覺得想要一個2×N個矩陣,如果是的話,下面的代碼將這樣做。請注意,這是而不是檢查malloc和calloc調用的結果,我留給你。此功能將失敗成功返回零(0),非零:

int beolvas_ellista(int *ir, int *suly, int *csom, int *el, int ***ellista, const char *allomany) 
{ 
    FILE * f = fopen(allomany,"r"); 
    int ** local = NULL; 
    int i, res = -1; 

    if (f == NULL) 
     return res; 

    if (fscanf(f,"%d",ir) == 1 && 
     fscanf(f, "%d",suly) == 1 && 
     fscanf(f,"%d",csom) == 1 && 
     fscanf(f,"%d",el) == 1) 
    { 
     // allocate two pointers, then in those two pointers, allocate 
     // space for *el integers. 
     local = malloc(2 * sizeof(*local)); 
     local[0] = calloc(*el, sizeof(*(local[0]))); 
     local[1] = calloc(*el, sizeof(*(local[0]))); 

     for (i=0; i<*el; ++i) 
     { 
      if (fscanf(f, "%d", local[0]+i) != 1 || 
       fscanf(f, "%d", local[1]+i) != 1) 
       break; 
     } 

     // only if i == *el did we finish the above 
     if (i == *el) 
     { 
      *ellista = local; 
      res = 0; 
     } 
     else 
     { // failed to read file content. free up memory 
      // and return error state. 
      free(local[0]); 
      free(local[1]); 
      free(local); 
     } 
    } 
    fclose(f); 
    return res; 
} 
0

您的輸入文件不符合代碼。你在你的輸入文件中說* el = 8。在你的代碼中,你把這個作爲行計數,但實際上只在你的第一個calloc調用中花費2行到矩陣中...

P.S.試試這個:

編輯:錯誤分析我。你的實際問題是一個先行者。您需要取消引用您的*與設置,像這樣括號中的正確方法:

void beolvas_ellista(int *ir, int *suly, int *csom, int *el, int ***ellista, char *allomany) 
{ 
    int i; 
    FILE * f; 
    f=fopen(allomany,"r"); 

    fscanf(f,"%d",ir); 
    fscanf(f,"%d",suly); 
    fscanf(f,"%d",csom); 
    fscanf(f,"%d",el); 


    *ellista=(int **)calloc(2,sizeof(int *)); 
    for(i=0;i<*el;++i) 
    { 
     (*ellista)[i]=(int *)calloc(*el,sizeof(int)); 

    } 



    i=0; 

    while(!feof(f)) 
    { 
     fscanf(f,"%d",&((*ellista)[0][i])); 
     fscanf(f,"%d",&((*ellista)[1][i])); 
     ++i; 
    } 

    fclose(f); 
} 
+0

矩陣是2 * 8,我測試了代碼,它的工作原理,我在函數內部分配空間或者給出數值時有一些問題,我不能計算出來 – Miklosflame

+0

@Miklosflame「我測試了代碼並且它的作品「不,它不。你的while循環中檢查'feof'是錯誤的。讀取的最後一行不會建立'feof';它將在*之後的第一次讀取嘗試*上建立。並且您正在使用的讀取嘗試「fscanf()」完全沒有檢查有效性。換句話說,假設大小調整是正確的,你會超出你分配的矩陣大小,並直接進入**未定義的行爲**。 [看到這個問題](http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong)。 – WhozCraig

+0

請看看我的編輯,尤其是在calloc中的位置,fscanf調用了在解引用「ellista」時如何設置括號。我的第一個分析是錯誤的,對此抱歉。 – user2927610