二次元配列追加後の処理について

[戻る]
けんじ 2003/09/04(木) 12:09:33
いつもお世話になっております。
先日は有難うございました。今回もご教授お願いしたいです。
あまりうまく表現できるか分かりませんが、一生懸命表現したつもりです。
宜しくお願いします。
二次元配列aの後ろにbをくっつけそれをcの配列としてcountの回数だけ更新させたaと
bをまた同様にcとして一列に並べて出力したいのです。しかしエラーが出たりしてうま
くいきません。
その配列cを更新した後で取り出したいのですがどうしたらいいかが分かりません。
何回も試していますがどうも思ったように行かないです。
たびたびで申し訳ございませんが、ご教授していただけるでしょうか?
a
b
上記の並びがcです。aとbが更新されるとこの並びでcの中身(ab)も更新されます。
これをcountの数だけ行った結果を
c一回目
c更新
c更新
と、一列で出力したいです。しかし、・・・・本当に分かりません。ご教授ください。



#include <stdio.h>        /* printf */
#include <string.h>  
int main()
{
    int a[2][3]={{1,2,3},{4,5,6}}; 
    int b[2][3]={{7,8,9},{10,11,12}};
    int c[12];
    int i,j;
    int count;
    for( count = 0; count < 5; count++ ){
        for( i = 0; i < 2; i++ ){
            for(j = 0; j < 3; j++){
            a[count * 2 + i][count * 3 + j] = a[count * 2 + i][count * 3 + j] 
+ 1;//aの更新
             b[count * 2 + i][count * 3 + j] = b[count * 2 + i][count * 3 + j]
+2;//bの更新
            //aの表示
            printf("%d\n", a[count * 2 + i][count * 3 + j] );
        a[(count+1 )* 2 + i][(count+1) * 3 + j]= a[count * 2 + i][count * 3 + 
j];//
          
            //bの表示
         printf("%d\n", b[count * 2 + i][count * 3 + j] );
        b[(count+1) * 2 + i][(count+1) * 3 + j] = b[count * 2 + i]
[count * 3 + j]+2;

            //aの後ろにbをおいたものをcとする。
        memcpy(c, a, sizeof(double)*2*3);
        memcpy(c+(2*3), b, sizeof(double)*2*3);//aの配列の後ろにbを置く
        for ( i = 0; i < 12; i++ ){
            printf("%d\n", c[i] );
}
            }//for j
        }//for i
    }//for count 

    printf("*** countループ外 ***\n");

    //ここで画面に表示された更新履歴がすべて残っているcを取り出したいです。
       for ( i = 0; i < 12; i++ ){
            printf("%d\n", c[i] );//更新後のc
}

    return 0;
}

けんじ 2003/09/04(木) 12:22:47
追加
 
            //bの表示
         printf("%d\n", b[count * 2 + i][count * 3 + j] );
        b[(count+1) * 2 + i][(count+1) * 3 + j] = b[count * 2 + i]
[count * 3 + j]+2;//この部分は+2が必要ありませんので以下のようにしました。


   //bの表示
      printf("%d\n", b[count * 2 + i][count * 3 + j] );
      b[(count+1) * 2 + i][(count+1) * 3 + j] = b[count * 2 + i][count * 3 + j]

こん! [E-Mail] 2003/09/04(木) 12:36:22
前回の件からもそうですが、処理の流れを設計しようとする努力が乏しい様です。
C/C++の構文に悩む前にフローチャートを書かれてはいかがですか?

昔は、キーボードからいきなりプログラムを打ち込む前に、紙の上に鉛筆でフローチャートを書
けと教わったものですが。

2003/09/04(木) 12:38:57
aやbの要素指定に、count*2 やらcount*3やらが入っているのはなぜ?
これらのせいで配列の要素外にアクセスしてしまっています、とってください。

また
> memcpy(c, a, sizeof(double)*2*3);
> memcpy(c+(2*3), b, sizeof(double)*2*3);

a,b,cはそれぞれintの配列なので
memcpy(c, a, sizeof(int)*2*3);
memcpy(c+(2*3), b, sizeof(int)*2*3);
としないと、これまた要素外へアクセスしてしまいます。

とりあえず、配列の扱いについて一度復習なされたほうがよいと思います。

こん! [E-Mail] 2003/09/04(木) 12:54:50
aやbの要素指定に、count*2 やらcount*3やらが入っているのはなぜ?
これらのせいで配列の要素外にアクセスしてしまっています、とってください。

これはきっと私のせいです。m(__)m
ここの
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200309/03090007.txt

参考例で履歴を残す為に余分にバッファを確保しておきcount分ずつずらしていったのですがそ
の履歴を残す為のバッファを確保していないようです。

結局分かってくれていなかったということです。

けんじ 2003/09/04(木) 13:34:57
こん!さん
memcpy(c, a, sizeof(int)*2*3);
memcpy(c+(2*3), b, sizeof(int)*2*3);
の使用によりできたCは更新できないのか?
こん!さんの教えてくださったものはaやbでは実行できましたが、cでは無理でした。
もう少しソースを訂正し、示したいと思います。
皆さん、助言有難うございました。

けんじ 2003/09/04(木) 13:59:09
たびたび、失礼します。
ソースを書き直し、チャレンジしていますがやはり一向によくなりません。
どうしたらCをとりだせるでしょうか?
こん!さん理解力(応用力)がなくてすいません。
#include <stdio.h>        /* printf */
#include <string.h>  
int main()
{
    int a[2][3]={{1,2,3},{4,5,6}}; 
    int b[2][3]={{7,8,9},{10,11,12}};
    int c[12];
    int i,j;
    int count;
     
    FILE *stream;
    
    FILE *fp1;
    char fname1[100];
    sprintf(fname1,"c.txt");
    if((fp1=fopen(fname1,"w"))==NULL){
        printf("cannot open file1.");
        return 0;
    }
    
        
    
    for( count = 0; count < 5; count++ ){
        for( i = 0; i < 2; i++ ){
            for(j = 0; j < 3; j++){
        
        
            a[i][j] = a[i][j]+1;//aの更新
         //aの表示
            printf("%d\n", a[i][j] );
                }//for j
        }//for i
        
        for( i = 0; i < 2; i++ ){
         for(j = 0; j < 3; j++){
            b[i][j] = b[i][j]+2;//bの更新
        //bの表示
            printf("%d\n", b[i][j] );
            }//for j
        }//for i
             printf("\n");//改行(分かりやすくc毎の表示)
//***************ここまででaとbがつづけて表示できる。これをcとしたい。以下cに
するための表示*********
     
        //aの後ろにbをおいたものをcとする。これをcountの回数だけ表示したい。
        memcpy(c, a, sizeof(int)*2*3);
        memcpy(c+(2*3), b, sizeof(int)*2*3);//aの配列の後ろにbを置く
        //cの表示
***************************************************************
        for ( i = 0; i < 12; i++ ){
            fprintf(fp1,"%d\n", c[i] );
        }
    //ここまではできているみたいです。
*************************************************
    
        
    // a[(count+1 )* 2 + i][(count+1) * 3 + j]= a[count * 2 + i][count * 
3 + j];
        
    //b[(count+1) * 2 + i][(count+1) * 3 + j] = b[count * 2 + i][count * 
3 + j];
    
    }//for count 

    printf("*** countループ外 ***\n");

    //ここで画面に表示された更新履歴がすべて残っているcを取り出したいです。
***********************************************
       for ( i = 0; i < 12; i++ ){
            //printf("%d\n", c[i] );//更新後のc
    }

    return 0;
    fclose(fp1);
}

n [E-Mail] 2003/09/04(木) 14:01:38
共用体を使うといいのでしょうか。

#include<stdio.h>

int main()
{
 //共用体
 union {
  struct {
   int a[2][3];
   int b[2][3];
  };
  int c[12];
 } x;

 //cに変更を加えると、
 int i,j;
 for(i=0;i<12;++i)
 {
  x.c[i]=i;
 }

 //aもbも変更されている
 for(j=0;j<2;++j)
 {
  for(i=0;i<3;++i)
  {
   printf("x.a[%d][%d]==%d\n",j,i,x.a[j][i]);
  }
 }

 for(j=0;j<2;++j)
 {
  for(i=0;i<3;++i)
  {
   printf("x.b[%d][%d]==%d\n",j,i,x.b[j][i]);
  }
 }

 return 0;
}

こん! [E-Mail] 2003/09/04(木) 14:23:44
実は共用体でも駄目なんです。

けんじさんが言っているのは最終結果ではなく更新履歴を全て残したいとの事なので

a[2][3]の分で6
カウント5回×6=30
b[2][3]の分で6
カウント5回×6=30

それをcの配列に保持するのであれば[60]必要なのです。

ソースをアップしても前回の二の舞でしょうから、まずはフローを考えて下さい。

tib 2003/09/04(木) 14:31:42
すいません、最初の質問文のここを明らかにさせて下さい。

> 二次元配列aの後ろにbをくっつけ
ここで、aは

> int a[2][3]; 
というように「2x3=6個のintを格納できる箱」として宣言されているわけですが、そのa
の後ろに「b(これも2x3=6個のintを格納している箱)をくっつける」とは、結局「aに4x3=
12個のintを格納させる」という事をイメージしていらっしゃいますか?

けんじ 2003/09/04(木) 14:38:15
>結局「aに4x3=12個のintを格納させる」という事をイメージしていらっしゃいますか?
そうです。おっしゃるとおりです。
ソースを書き直したものを走らせていただくとご理解していただけるのではないかと思
います。

けんじ 2003/09/04(木) 14:42:38
現在、以下のところまで進んでいます。
しかし、cがとりだせません。
>ソースをアップしても前回の二の舞でしょうから、まずはフローを考えて下さい。
恥ずかしながらフローをかいて作業はしています。


#include <stdio.h>        /* printf */
#include <string.h>  
int main()
{
    int a[2][3]={{1,2,3},{4,5,6}}; 
    int b[2][3]={{7,8,9},{10,11,12}};
    int c[60];
    int i,j;
    int count;
     
    FILE *stream;
    
    FILE *fp1;
    char fname1[100];
    sprintf(fname1,"c.txt");
    if((fp1=fopen(fname1,"w"))==NULL){
        printf("cannot open file1.");
        return 0;
    }
    
        
    
    for( count = 0; count < 5; count++ ){
        for( i = 0; i < 2; i++ ){
            for(j = 0; j < 3; j++){
        
        
            a[i][j] = a[i][j]+1;//aの更新
         //aの表示
            printf("%d\n", a[i][j] );
                }//for j
        }//for i
        
        for( i = 0; i < 2; i++ ){
         for(j = 0; j < 3; j++){
            b[i][j] = b[i][j]+2;//bの更新
        //bの表示
            printf("%d\n", b[i][j] );
            }//for j
        }//for i
             printf("\n");//改行(分かりやすくc毎の表示)
//***************ここまででaとbがつづけて表示できる。これをcとしたい。以下cに
するための表示*********
     
        //aの後ろにbをおいたものをcとする。これをcountの回数だけ表示したい。
        memcpy(c, a, sizeof(int)*2*3);
        memcpy(c+(2*3), b, sizeof(int)*2*3);//aの配列の後ろにbを置く
        //cの表示
***************************************************************
        for ( i = 0; i < 12; i++ ){
            fprintf(fp1,"%d\n", c[count*12+i] );
        
            c[(count+1)*12+i]=c[count*12+i];
        }
    //ここまではできているみたいです。
*************************************************
    
        
    // a[(count+1 )* 2 + i][(count+1) * 3 + j]= a[count * 2 + i][count * 
3 + j];
        
    //b[(count+1) * 2 + i][(count+1) * 3 + j] = b[count * 2 + i][count * 
3 + j];
    
    }//for count 

    printf("*** countループ外 ***\n");

    //ここで画面に表示された更新履歴がすべて残っているcを取り出したいです。
***********************************************
       for ( i = 0; i < 60; i++ ){
            printf("%d\n", c[i] );//更新後のc
    }

    return 0;
    fclose(fp1);
}

tib 2003/09/04(木) 14:59:03
>>結局「aに4x3=12個のintを格納させる」という事をイメージしていらっしゃいますか?
>そうです。おっしゃるとおりです。

ならば、aのサイズを変えなくてはなりません。「メモリの動的割り当て」という技が必
要になります。具体的にはrealloc()などを使います。

どうもあなたの「やりたいこと」と「やっていること」がかみ合ってないように思えま
す。フローを書くことも大事ですが、変数の意味をしっかり捉えて「a, b, c」のような
抽象的な名前を使わず、「なぜ2次元配列なのか」「なぜ2次元配列を1次元配列で参照し
たいのか」という根本的な問題を見つめ直した方がいいと思います。

変数の意味が分かれば、動的割り当てがいいのか、2次元配列よりも構造体の配列の方が
いいのか、共用体を使うのがいいのか、などの「方針」が見えてくると思います。ただや
みくもにソースをいじり倒すより遠回りに思えるかも知れませんが、結果的にはずっと近
道ですよ。

こん! [E-Mail] 2003/09/04(木) 15:17:39
> 恥ずかしながらフローをかいて作業はしています。

そうですか。
こういう事でいいのですか?
少々分かりやすいように吐き出すデータに行番等を追加してあります。
消して下さい。

int main( void )
{
    int a[2][3] = {{1,2,3},{ 4, 5, 6}}; 
    int b[2][3] = {{7,8,9},{10,11,12}};
    int c[60];
    int i, j, count;
     
    FILE *fp1;

    if( ( fp1 = fopen( "C:\\c.txt", "w" ) ) == NULL )
    {
        printf( "cannot open file1." );
        return 0;
    }

    int    offset;

    for( count = 0; count < 5; count++ )
    {
        offset = count * 12;

        for( i = 0; i < 2; i++ )
        {
            for( j = 0; j < 3; j++ )
            {
                c[offset + i * 3 + j] = ++a[i][j];    //aの更新
                printf( "a: %d\n", a[i][j] );            //aの表示
            }       //for j
        }           //for i

        for( i = 0; i < 2; i++ )
        {
            for( j = 0; j < 3; j++ )
            {
                c[offset + 6 + i * 3 + j] = b[i][j] += 2; //bの更新
                printf( "b: %d\n", b[i][j] );  //bの表示
            }    //for j
        }        //for i
        printf("\n");    //改行(分かりやすくc毎の表示)

        // ここまででaとbがつづけて表示できる。これをcとしたい。
        // 以下cにするための表示
    }

    for ( i = 0; i < 60; i++ )
    {
        fprintf( fp1, "%2d : %d\n", i + 1, c[i] );
    }
    
    fclose(fp1);
    return 0;
}

傍観 2003/09/04(木) 15:20:21
こんなのはとは違うかな?
#include <stdio.h>
#define cnt 2   //更新回数
#define bufer  10
int main()
{
    int a[2][3];
    int b[2][3];
    int c[bufer][12];  //バッファログ
    int* posi[bufer];  //ログ見出し
    int* p;
    int i,j,k;

    for(i=0; i<cnt; ++i){
        posi[i] = &c[i][0];
        p = posi[i];
        for(j=0; j<2; ++j){
            for(k=0; k<3; ++k,++p){
                printf("a[%d][%d] = ",j,k); scanf("%d",&a
[j][k]);
                printf("b[%d][%d] = ",j,k); scanf("%d",&b
[j][k]);
                *p      = a[j][k];
                *(p+6)  = b[j][k];  //6はa[2][3]からの算出
            }
        }
        
    }
    j = 1;
    for(i=cnt; i>0; --i){
        p = posi[i-1];
        printf("c %d回目 :",j++);
        for(k=0; k<12; ++k){
            printf("%d ",*p++);
        }
        puts("");
    }
    return 0;
}

傍観 2003/09/04(木) 15:26:17
あ、回数表現変だった。

けんじ 2003/09/04(木) 15:29:35
こん!さん
有難うございます。おっしゃるとおり、私のやりたいことでした。
前回も助けられ、本当に感謝しています。
ここ最近、本当に、3ヶ月前くらいですか、それくらい前からc言語を始め、
私の中ではいろいろなことを行っているつもりです。
ここに書かれている皆様とは多少レベルの差を感じますが、楽しく勉強させていただい
ております。そのため、こん!さんのアドバイスが難しく、理解に追いつかないのが現
状です。このサンプルソースを参考にもっと勉強してきます。
今回のように前回からこん!さんのアドバイスを元にこのソースにあるようなことをや
りたかったのですが全く、どのようなコマンドを使っていいか分からなかったです。

また、分からないことが出てくるかもしれませんが、お手柔らかにお願いいたします。
もっと(もう少し)勉強してから掲示させていただきます。

けんじ 2003/09/04(木) 15:29:47
[[解決]]
解決です

けんじ 2003/09/04(木) 15:31:38
協力していただいた皆様も有難うございました。

tib 2003/09/04(木) 15:48:11
一応、こんな方法もあるよ、ということで。

#define    sizeX_c    2
#define    sizeY_c    3
typedef    struct
{
    int    A[sizeX_c][sizeY_c];
    int    B[sizeX_c][sizeY_c];
}    tib_t;

int main()
{
    const int    count_c    = 5;
    tib_t        history[count_c];
    tib_t        base    = {{{ 1, 2, 3}, { 4, 5, 6}},
                   {{ 7, 8, 9}, {10,11,12}}};
    int        ii, jj, nCount;

    for( nCount=0; nCount<count_c; nCount++ )
    {
        for( ii=0; ii<sizeX_c; ii++ )
        {
            for( jj=0; jj<sizeY_c; jj++ )
            {
                base.A[ii][jj]    +=    1;
                base.B[ii][jj]    +=    2;
            }
        }
        history[nCount]    =    base;
    }
    for( nCount=0; nCount<count_c; nCount++ )
    {
        PrintTibt( &(history[nCount]) );
    }
}

int PrintTibt(tib_t *pTib)
{
    return printf(
        "{ {%d,%d,%d}, {%d,%d,%d} }  { {%d,%d,%d}, {%d,%d,%d} }\n",
        pTib->A[0][0], pTib->A[0][1], pTib->A[0][2],
        pTib->A[1][0], pTib->A[1][1], pTib->A[1][2],
        pTib->B[0][0], pTib->B[0][1], pTib->B[0][2],
        pTib->B[1][0], pTib->B[1][1], pTib->B[1][2]        );
}

古いスレッドには追加発言できません。