90106


C言語で, 再帰を使わずに深さ優先探索を行うプログラムを作成しています.  
その過程で「任意のファイルの隣接行列を読み込み, int型の配列に格納させた後に表示する」ということを行いたいのですが,
どのようにプログラム書けば良いのかがわからないです. どなたか教えてくださると幸いです.  
配列を可変させるために, ファイルの行数を読み取るものまでは作成しました.  
また, テストとして, 要素数4,深さ3のtest.datを作成しました.  
以下, 実行方法, 理想の実行結果, ソースコードです.

実行方法:

[code]

    ./dfs.c test.dat
    
[/code]

理想の実行結果:

[code]

    このファイルは4行あります.
    0 1 1 0
    1 0 0 0
    1 0 0 1
    0 0 1 0
    
[/code]

ソースコード:  
dfs.c

[code]

    #include <stdio.h>
    #include <stdlib.h>
    
    int main(int argc, char *argv[]){
        FILE *fp;
        //int data;
        int c;
        int i,j;
        int line = 0;
    
        if(argc != 2){                            /* 引数は２つあるか */
        puts("Parameter Error");
            return 0;
        }
    
        if((fp = fopen(argv[1],"r")) == NULL){    /* ファイルは存在するか */
            puts("File Open Error"); 
            return 0;
        }
    
        while ((c = fgetc(fp)) != EOF) {
            if (c == '\n') line++;
        }
    
        printf("このファイルは%d行あります.\n", line);
    
        double data[line];
        int ret;
        char buf[line][line];
        int a[line][line];
    
    
        /*for(i = 0;i<line;i++){
            for(j = 0;j<line;j++){
                if(j == line - 1){
                    fscanf(fp, "%s\n", buf[i][j]);
                }else{
                    fscanf(fp, "%[^,]", buf[i][j]);
                }
            }
        }*/
    
    
        fclose(fp);
        return(0);
    }
    
[/code]

test.dat

[code]

    {0,1,1,0},
    {1,0,0,0},
    {1,0,0,1},
    {0,0,1,0},
    
    
[/code]


CC BY-SA 4.0
2022-07-19T14:43:36.140
90093
2022-07-23T02:50:22.130
50923
question
c array 行列
C言語でdatファイルから隣接行列を読み取り, 配列に格納させ表示させたい


いろんな仕様が不明（つまりはあなたがしなければならない詳細が不明）なので、まずは仕様策定から。たとえば

・データファイルには正方行列のデータが入っている  
・各行の行頭は `{` で、行末は `},` で、これは無視して良い (*1)  
・１行に並べているデータ個数と、行数は一致する（ので正方行列）  
・コメントだの空行だのが混ざることは決してない  
・ファイルの最後の行にも必ず改行コードがある  
といった内容は仕様以前の「要求」。そして

・要求を満たすとき、どう動くとよいか（何を読んでどこに格納する等）  
・要求を満たさないとき、どう動くとよいか（無視して継続するとかエラー終了とか）  
あたりは「仕様」

要求を出すほうと受けるほうで合意があれば要求は変えてもらってよいっス。先の (*1)
などは面倒なだけなので削除してもらえるなら、結局のところ「カンマで値が区切られたデータ」つまり CSV 形式とできて、別コメントにある通り CSV
入出力ライブラリなるものを使えて楽できるはず。

なぜこんなことを言い出しているかというと [c](/questions/tagged/c "'c' のタグが付いた質問を表示")
では読んでみないと長さがわからない可変長データってのは取り扱いにくいので、要求側にて個数を最初に与えてもらうと楽できるから。入力データの形式とかも自分で決めてよい案件なら、プログラムが簡単になるように要求（＝入力データの形式）を策定するとプログラムが簡単になり、完成までの手間もかからずバグも入りにくくて良い感じになるわけっス。

んで、現状のコードは `line`
の算出のためだけにファイルを一度全部読む必要があり、データ自体を読み取るにはファイルを再度読み直す必要があるという構造になっているわけっス。こんな面倒なデータ形式を採用せずにプログラムが簡単になるようなデータ形式を採用するほうが後々の手間が減るはずとオイラなんかは思うわけ。

まあこの構造を尊重するなら `line` の算出後に `rewind(fp);` するとよいっス（そのためには元データが真にファイルであって
`rewind` できなきゃならないってあたりがオイラ的には不合格。パイプでデータを与えることができなくなる）

とりあえずは `rewind()` を試してみよう、ってことで回答にしておくっス。


CC BY-SA 4.0
2022-07-20T07:28:27.110
90106
2022-07-20T07:28:27.110
8589
90093
answer


774RRさんのアドバイスの下, 以下のように修正した結果できました.

実行結果:

[code]

    このファイルは4行あります.
    0110
    1000
    1001
    0010
    
[/code]

ソース:

[code]

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    #include <ctype.h>
    
    int main(int argc, char *argv[]){
        FILE *fp;
        int c;
        int i,j,n;
        char data;
        int line = 0;
        int **matrix = NULL;
    
        if(argc != 2){                            /* 引数は２つあるか */
        puts("Parameter Error");
            return 0;
        }
    
        if((fp = fopen(argv[1],"r")) == NULL){    /* ファイルは存在するか */
            puts("File Open Error"); 
            return 0;
        }
    
        while ((c = fgetc(fp)) != EOF) {
            if (c == '\n') line++;
        }
        printf("このファイルは%d行あります.\n", line);
        rewind(fp);
    
        matrix = (int**)malloc(sizeof(int *) * line);
    
        if (matrix == NULL) {
            printf("malloc error\n");
            return -1;
        }
        
        for (i=0;i<line;i++) {
            matrix[i] = (int*)malloc(sizeof(int) * line);
            if(matrix[i] == NULL){
                return -1;
            }
        }
    
        i = j = n = 0;
    
        while( (data = fgetc(fp)) != EOF ){
            if(data=='0'){
                //printf("0が出てきた\n");
                matrix[i][j] = 0;
                j++;
            }
            if(data=='1'){
                //printf("1がでてきた\n");
                matrix[i][j] = 1;
                j++;
            }
            if(data=='\n'){
                i++;
                j=0;
            }
        }
    
        for(i = 0;i < line;i++){
            for(j = 0;j < line;j++){
                printf("%d", matrix[i][j]);
            }
            printf("\n");
        }
    
    
    
        fclose(fp);
        free(matrix);
        
        return(0);
    }
    
[/code]


CC BY-SA 4.0
2022-07-22T15:54:35.670
90151
2022-07-23T02:50:22.130
2022-07-23T02:50:22.130
50923
50923
90093
answer