C言語関係掲示板

過去ログ

No.1334 ファイルの内容を2次元配列に格納するには

[戻る] [ホームページ]
No.18053

ファイルの内容を2次元配列に格納するには
投稿者---HTM(2004/11/13 14:02:04)


0 0 1
1 0 1
1 1 1
0 1 1
0 0 0
1 0 0 
1 1 0
0 1 0


のようなファイルabc.txtを2次元配列に格納すにはどうやったら
いいのでしょうか?以下のソースだとなにも格納されていない
ようなので、どなたかご教授下さい。
#include <stdio.h>

struct POINT{ 
  double x; 
  double y;
  double z;  
};

struct POINT v[8][3];

int main(int argc, char *argv[])
{
  int i,j;              /* ループ用変数 */
  FILE *fp;             /* ファイルポインタ */
  char filename[1024];  /* 読み込んだファイルを格納する配列*/
  char line[1024];

  if(argc != 2){
    printf("false\n");
    exit(0);
  }
  
  strcpy(filename, argv[1]);
  fp = fopen(filename, "r"); /* ファイルの読み込み */
  
  i=0;j=0;
  while(filename[1024] != EOF){
    fgets(line,1024,fp);
    if(strlen(line) <= 1){
      i=0;j=0;
    }else{
      sscanf(line,"%s %s %s",&v[i][j].x, &v[i][j].y, &v[i][j].z);
    }
    i++;j++;
  }
  
  
  for(i=0 ; i<9 ; i++){
    for(j=0 ; j<4 ; j++){
      printf("%s", v[i][j]);
    }
  }

  fclose(fp);
}     




No.18057

Re:ファイルの内容を2次元配列に格納するには
投稿者---RAPT(2004/11/13 15:08:24)


double型なのに、%s を使用しているのが致命傷。


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

struct POINT{
    double x;
    double y;
    double z;
};

struct POINT v[8][3] = {0};

int main(int argc, char *argv[])
{
    int i;                /* ループ用変数 */
    FILE *fp = NULL;      /* ファイルポインタ */
    char filename[1024];  /* 読み込んだファイルを格納する配列*/
    char line[1024];

    /* 浮動小数点ライブラリの暗黙的リンクを行なう */
    double nonused;
    nonused = 0;
    /* ここまで */

    if(argc != 2){
        printf("false\n");
        exit(0);
    }

    strcpy(filename, argv[1]);
    fp = fopen(filename, "r"); /* ファイルの読み込み */
    if(fp == NULL){
        printf("%sファイルが開けない.\n", filename);
        exit(0);
    }
    
    for(i = 0; i < 8; ++i){
        if(fgets(line, 1023, fp) == NULL){
            break;
        }
        if(3 != sscanf(line, " %lf %lf %lf", &v[i][0].x, &v[i][1].y, &v[i][2].z)){
            break;
        }
    }
    fclose(fp);

    for(i = 0; i < 8; ++i){
        printf("%f ", v[i][0]);
        printf("%f ", v[i][1]);
        printf("%f\n", v[i][2]);
    }

    return 0;
}



No.18060

Re:ファイルの内容を2次元配列に格納するには
投稿者---monkey(2004/11/13 15:30:36)


「2次元配列に格納する」のならRAPTさんのコードのようになるのでしょうが、
処理結果が期待されているものと一致するかどうかは微妙かもです。


No.18061

Re:ファイルの内容を2次元配列に格納するには
投稿者---HTM(2004/11/13 15:55:38)


ありがとうございました。
最後の出力部分は
 for(i = 0; i < 8; ++i){
        printf("%f ", v[i][0].x);
        printf("%f ", v[i][1].y);
        printf("%f\n", v[i][2].z);
    }

だと思います。

もう一つ質問があります。
もし、このようなdef.txtで、もう一つの構造体に格納したい場合は
どのようにすればいいのでしょうか?
0 0 1
1 0 1
1 1 1
0 1 1
0 0 0
1 0 0 
1 1 0
0 1 0

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


ソースは、
/*先ほどのものに付け足しました*/

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

struct POINT{
    double x;
    double y;
    double z;
};

struct LINE{   
  int begin;  
  int end;   
};

struct POINT v[8][3] = {0};
struct LINE e[12][2] = {0};

int main(int argc, char *argv[])
{
    int i;                /* ループ用変数 */
    FILE *fp = NULL;      /* ファイルポインタ */
    char filename[1024];  /* 読み込んだファイルを格納する配列*/
    char line[1024];
    int flg;

    /* 浮動小数点ライブラリの暗黙的リンクを行なう */
    double nonused;
    nonused = 0;
    /* ここまで */

    if(argc != 2){
        printf("false\n");
        exit(0);
    }

    strcpy(filename, argv[1]);
    fp = fopen(filename, "r"); /* ファイルの読み込み */
    if(fp == NULL){
        printf("%sファイルが開けない.\n", filename);
        exit(0);
    }
    
    for(i = 0; i < 8; ++i){
      if(fgets(line, 1023, fp) == NULL){
    break;
      }
      if(strlen(line) <= 1){
    flg=1;
      }else{
    if(flg==0){
      if(3 != sscanf(line, " %lf %lf %lf", &v[i][0].x, &v[i][1].y, &v[i][2].z)){
        break;
      }
    }else{
      sscanf(line,"%d %d",&e[i][0].begin, &e[i][0].end);
    }
      }
    }
    
    fclose(fp);
    
    for(i = 0; i < 8; ++i){
      printf("%f ", v[i][0].x);
      printf("%f ", v[i][1].y);
      printf("%f\n", v[i][2].z);
    }
    
    return 0;
}




No.18058

Re:ファイルの内容を2次元配列に格納するには
投稿者---あかま(2004/11/13 15:08:28)


>sscanf(line,"%s %s %s",&v[i][j].x, &v[i][j].y, &v[i][j].z);
double型に読み込むのだから%lfでしょう。



No.18059

Re:ファイルの内容を2次元配列に格納するには
投稿者---monkey(2004/11/13 15:14:11)


3個のデータ(1行)を構造体データ1個に格納するのだから、
二次元配列にする必要はないでしょう。

ファイルから1行読み込み
1行分の文字列を3つの数値に変換してPOINTデータ1個に格納する
ことを、行数分繰り返す
というロジックで書き直してみました。
ご参考にどうぞ。

#include <stdio.h>

struct POINT{
  double x;
  double y;
  double z;
};

struct POINT v[ 8 ]; // 2次元配列にする必要はなさそう

int main( int argc, char *argv[] )
{
    int i;    // ループカウンタ
    int n;    // 行数
    FILE *fp; // ファイルポインタ
    char line[1024];

    if( argc != 2 ){
        printf( "false\n" );
        return 1;
    }

    fp = fopen( argv[ 1 ], "r" );
    if( fp == NULL ){
        printf( "file open failure\n" );
        return 1;
    }

    for( i = 0; fgets( line, 1024, fp ); i++ ){
        sscanf( line, "%lf %lf %lf", &v[ i ].x, &v[ i ].y, &v[ i ].z );
    }
    fclose(fp);
    n = i; // 読み込んだ行数

    for( i = 0; i < n; i++ ){
        printf( "%f, %f, %f\n", v[ i ].x, v[ i ].y, v[ i ].z );
    }
    return 0;
}



No.18067

Re:ファイルの内容を2次元配列に格納するには
投稿者---HTM(2004/11/13 21:13:03)


テキストファイル↓
0 0 1
1 0 1
1 1 1
0 1 1
0 0 0
1 0 0 
1 1 0
0 1 0

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

先ほど投稿したソースを変更したのですが、うまくいきません。
12行2列の方がうまく格納されないのです。
どのようにしたら、うまくいきますか?
どなたかアドバイスを下さい。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct POINT{
    double x;
    double y;
    double z;
};

struct LINE{   
  int begin;  
  int end;   
};

struct POINT v[8][3] = {0};
struct LINE e[12][2] = {0};

int main(int argc, char *argv[])
{
    int i;                /* ループ用変数 */
    FILE *fp = NULL;      /* ファイルポインタ */
    char filename[1024];  /* 読み込んだファイルを格納する配列*/
    char line[1024];
    int flg;

    /* 浮動小数点ライブラリの暗黙的リンクを行なう */
    double nonused;
    nonused = 0;
    /* ここまで */

    if(argc != 2){
        printf("false\n");
        exit(0);
    }

    strcpy(filename, argv[1]);
    fp = fopen(filename, "r"); /* ファイルの読み込み */
    if(fp == NULL){
        printf("%sファイルが開けない.\n", filename);
        exit(0);
    }
    
    for(i = 0; i < 8; ++i){
        if(fgets(line, 1023, fp) == NULL){
            break;
        }
  
        if(3 != sscanf(line, "%lf %lf %lf", 
                       &v[i][0].x, &v[i][1].y, &v[i][2].z)){
            break;
        }
        else 
            sscanf(line,"%d %d",&e[i][0].begin, &e[i][0].end)){
        }
        
    }
    
    fclose(fp);
    
    for(i = 0; i < 8; ++i){
        printf("%f ", v[i][0].x);
        printf("%f ", v[i][1].y);
        printf("%f\n", v[i][2].z);
    }
    
     for(i = 0; i < 12; ++i){
       printf("%d ", e[i][0].begin);
       printf("%d\n", e[i][1].end);
    }
    return 0;
}





No.18073

Re:ファイルの内容を2次元配列に格納するには
投稿者---monkey(2004/11/13 23:08:44)


ファイルの構造からすれば、次のような処理にすべきでしょう。

// 8行を読む
for( i = 0; i < 8; ++ i )
{
    // ファイルから1行読み、文字列に変換する
    // 1行分の文字列を3個のデータに変換して配列vのi番目の要素に格納する
}

// 1行読み飛ばす

// 12行を読む
for( i = 0; i < 12; ++i )
{
    // ファイルから1行読み、文字列に変換する
    // 1行分の文字列を2個のデータに変換して配列eのi番目の要素に代入する
}

# v, eを2次元配列にする意義が私には理解できません。
# どなたかご教示下さいませ。



No.18074

Re:ファイルの内容を2次元配列に格納するには
投稿者---RAPT(2004/11/13 23:10:54)


monkeyさん、正解!(汗
何を寝ぼけてたんだ、私は。

HTMさんも、表示用for文は正しく書けていたんだから、それを読出しの方でも
考慮してあげればOKだったんですが。

えー、読出しでは、for文が8ループしかしないので、続きの12行分は
どうやっても読み出せません。

また、妙なフラグは不要です。どうせなら、int read_line; とか、
意味のある変数をつけたほうが良いです。int flg; だと何のフラグか
わからなくなるので。

それから、sscanf()の書式指定ですが、" の後に続くスペースを
削除してはいけません。このスペース指定で、読出し時に余計な空白文字
(スペース、タブ文字)や改行文字などを飛ばしているからです。


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

struct POINT{
    double x;
    double y;
    double z;
};

struct LINE{
    int begin;
    int end;
};

struct POINT v[8] = {0};
struct LINE e[12] = {0};

int main(int argc, char *argv[])
{
    int i;                  /* ループ用変数 */
    FILE *fp = NULL;        /* ファイルポインタ */
    char filename[1024];    /* 読み込んだファイルを格納する配列*/
    char line[1024];

    /* 浮動小数点ライブラリの暗黙的リンクを行なう */
    double nonused;
    nonused = 0;
    /* ここまで */

    if(argc != 2){
        printf("false\n");
        exit(0);
    }

    strcpy(filename, argv[1]);
    fp = fopen(filename, "r");  /* ファイルの読み込み */
    if(fp == NULL){
        printf("%sファイルが開けない.\n", filename);
        exit(0);
    }

    for(i = 0; i < 8; ++i){
        if(fgets(line, 1023, fp) == NULL){
            break;
        }

        if(3 != sscanf(line, " %lf %lf %lf", &v[i].x, &v[i].y, &v[i].z)){
            break;
        }
    }
    for(i = 0; i < 12; ++i){
        if(fgets(line, 1023, fp) == NULL){
            break;
        }
        if(strlen(line) <= 1){
            continue;
        }

        if(2 != sscanf(line," %d %d", &e[i].begin, &e[i].end)){
            break;
        }
    }
    fclose(fp);

    for(i = 0; i < 8; ++i){
        printf("%f %f %f\n", v[i].x, v[i].y, v[i].z);
    }

    for(i = 0; i < 12; ++i){
        printf("%d %d\n", e[i].begin, e[i].end);
    }
    return 0;
}