• ベストアンサー

構造体について(配列)

こんばんはです。 下記のように 例 typedef struct person{ char name[256]; char pass[256]; }mydata; mydata men[5]; と、言う具合にあったとします。 menには全て入力されていて、例えばmen[3].nameとpassを消去したいとします。 その際、strcpy(men[3].name,"")とかしてるのですが、結局は、men[3]にはNULLが入るだけで、クリアというわけにはいかないのです。 全部クリアはmemsetをつかってできるのですが、場所指定ではどのようにするのでしょうか? 最終的にはmen[2]をクリアしたら、men[3]以降をずらして格納したいと思ってます。 切り取ったりしたいですが、できるのでしょうか?その場合、配列数は減らないのでしょうか? 消去した場所にコピーという形でずらしていったらいいかもですが・・。 アドバイスいただけたらうれしいです。 よろしくおねがいいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • Sakito0
  • ベストアンサー率100% (2/2)
回答No.3

構造体の一つを消去した時、後ろがずれるようにしたいのですね。 ただし、この場合、要素の一つを削除しても配列数が減ることはありません。一度取得した領域は、基本的に勝手に変わらないと思った方が無難です。 以下のようにすることが出来ます。要はコピーでずらしています。 ------------------------------------------- mydata mem[5]; memcpy( mem[2], mem[3], (sizeof(mydata)*2) ); // [2]を消す(ずらしてコピーする) memset( mem[4], NULL, sizeof(mydata) ); // 空いた最終領域をつぶす ------------------------------------------- 大体のOSなら、上記の方法で動作すると思います。

yuki22
質問者

お礼

お返事ありがとうございます。 専門家の方もこの方法を使用していたのです?? これからも何かとご指導ください。 回答ありがとうございました^^

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

  • ham_kamo
  • ベストアンサー率55% (659/1197)
回答No.2

> 最終的にはmen[2]をクリアしたら、men[3]以降をずらして格納したいと思ってます。 そういうことをやりたい場合は、リスト構造を使った方がいいと思います。

参考URL:
http://www9.plala.or.jp/sgwr-t/c/sec15-5.html
yuki22
質問者

お礼

お返事ありがとうございます。 リスト構造・・・Arrayみたいなものなのでしょうか?? URLまでいただけてありがとうございます。 参考にさせていただきます^^

全文を見る
すると、全ての回答が全文表示されます。
  • Trick--o--
  • ベストアンサー率20% (413/2034)
回答No.1

> 最終的にはmen[2]をクリアしたら、men[3]以降をずらして格納したい そのようにmem[2]を消すときの動作を分解すると ・mem[2]にmem[3]をコピー ・mem[3]にmem[4]をコピー ・mem[4]を消去(strcpy/memsetを使う方法でいいでしょう) となります。 コピー部分は開始位置/終了位置に気をつけてforで回せますね。 構造体のコピーは、=で出来るはずです。 出来なければメンバ毎にstrcpyすれば良いでしょう。

yuki22
質問者

お礼

お返事ありがとうございます。 mensetって場所指定できたのでしたか^^; まだまだ勉強不足です。 回答ありがとうございました^^

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 構造体の配列について(2)

    前回「構造体の配列について」という質問タイトルで、質問させていただいたのですが、理解が完全ではないため同じようなプログラム内容ではありますが、疑問を書かせていただきます。よろしくお願いします。 ----------------------------------------------------------------------- #include<stdio.h> #include<string.h> struct person{ char name[1];    //// (1) //// int height; int weight; }; int main() { struct person dt[10]; strcpy(dt[0].name,"日本一郎"); strcpy(dt[2].name,"関東次郎"); strcpy(dt[9].name,"関西三郎"); dt[1].weight=99; dt[1].height=168; printf("%s %s %s %d %d \n",dt[0].name,dt[2].name,dt[9].name,dt[1].weight,dt[1].height); return 0; } ----------------------------------------------------------------------- 以上のプログラムの(1)の部分で、文字を1文字しか格納出来ないのに、 strcpy(dt[0].name,"日本一郎"); strcpy(dt[2].name,"関東次郎"); strcpy(dt[9].name,"関西三郎"); としても何故正しく実行できるのかわかりません。 前回いろいろとご回答いただいたのに、しっかりと理解できない者ですが、教えていただければ嬉しいです。

  • 構造体の配列について

    --------------------------------------------------- #include<stdio.h> #include<string.h> struct person{ char name[80]; int height; int weight; }; int main() { struct person dt[10]; strcpy(dt[1].name,"日本太郎");    //// (1) //// dt[1].weight=70; dt[1].height=180; dt[5]=dt[1];    //// (2) //// printf("%s %d %d \n",dt[1].name,dt[1].weight,dt[1].height); return 0; } ----------------------------------------------------- 以上のプログラムは参考書に記述されていたものですが、(1)の部分で、配列名dtに「"日本太郎"」を設定するならわかるのですが、配列の1つの要素「dt[1]」に「"日本太郎"」を設定しているというように見え、これはエラーが出ると感じたのですが出ません。 char dt[10]; strcpy(dt[1],"日本太郎"); 以上のようにしてしまっているというイメージがあります。 後、(2)の部分もよくイメージがわきません。 以上、どのような仕組みになっているのか教えていただければ嬉しいです。

  • メモリ動的確保について

    こんにちはです。 メモリの動的確保なのですが、 typedef struct DATA{ char name[256]; char pass[256]; int money; }BANK; void insert(BANK *p,int max); int main(){ int i; size_t st; BANK *person; person = (struct DATA *)malloc(sizeof(struct DATA)); //person = (struct DATA *)malloc(5); if(person == NULL){ printf("確保失敗\n"); exit(-1); } //memset(person,'\0',sizeof(struct DATA)); と、言う風に、記載ソースは途中ですがメモリをとりました。 mallocの後ろの部分ですが、sizeof(struct DATA)と5ではどうちがうのでしょう??2通りともコンパイルエラーはないです。 5は動的に最大5までとるって事はわかるのですが、struct DATAの方はいくつとるのです??いくつもで入力次第です? そして、動的したのにたいしてmemsetしたら実行エラー(コンパイルは通りました)おきました。動的にたいしてmemはダメなのでしょうか? アドバイスいただけたらありがたいです。宜しくお願いいたします。

  • 構造体についてです。

    typedef struct student{ int id; char name[20]; int kokugo; int sansu; int eigo; }STUDENT; と、 struct student{ int id; char name[20]; int kokugo; int sansu; int eigo; }; の違いはなんでしょう? 私は下記をよく使うのですが・・・。 typedefについて詳しく知りたいです。

  • 構造体のポインタにNULLが入らない

    typedef struct tag{ int number; char name[10]; struct tag *next; }DATA; という構造体があって、 DATA *p; と宣言し、 p->next == NULL; とすることはできないんですか? セグメンテーション違反になってしまうのですが。 pが指すnextにNULLを入れるにはどうしたらいいのでしょうか?

  • 構造体宣言したポインタ変数に値を代入するには?

    strcpy(p -> key ,name);と打ってp -> key に入力した名前を格納したいのですがうまくいきません。 ほかにもp -> key = nameなども試してみましたがコンパイルエラーが出現してダメでした。 うまく格納できるやり方があれば教えてください。よろしくお願いします。 #include<stdio.h> #include<string.h> #define WORD_LENGTH 50 /* 文字列の最大長 */ typedef struct cell{ char key[WORD_LENGTH]; struct cell *next; /* 次のセルへのポインタ */ } CELL; void main(void) { char name[WORD_LENGTH]; CELL *p; printf("名前入力\n"); scanf("%s\n", name); strcpy(p -> key ,name); printf("%s\n", p -> key); }

  • 構造体について

    typedef struct num{ char rv[1000]; struct number *next; struct number *prev; }Num; このような双方向のリスト構造に void aplist(Num **s,char ns[]){ Num *old, *new; if(*s==NULL){ *s = (Num *)malloc(sizeof(Num)*1); strcpy((*s)->rv,ns); (*s)->next = NULL; (*s)->ago = NULL; return;} old= (*s); while(old->next != NULL){ old = old->next;} new = (Num *)malloc(sizeof(Num)*1); strcpy(new->rv,ns); new->next = NULL; old->next = new; new->prev = old; 関数の中でこのようにnext,oldを指定していったのですが、これでよいでしょうか?また、このリストを逆方向(prevの方向)に表示していきたいのですがどのように書けばよいでしょうか?nsは1行の文字列で、各構造体に1行ずつ入れていっています。

  • 構造体の各メンバにfor文からアクセスする

    VC++2005で開発しています。 typedef struct { char test1[10]; char test2[5]; ・・・ char test10[5]; }Sample; Sample sample; char *x[] = {"あ", "い",・・・, "こ"}; strcpy(sample.test1, x[0]); strcpy(sample.test2 = x[2]); ・・・ strcpy(sample.tet10, x[9]); このstrcpyの部分をループ文でまわしたいのですが、 何か良い方法はありませんか? よろしくお願いします。

  • 入れ子になった構造体について

    以下のように定義した、2重に入れ子になった構造体があります。 これを、mallocを使ってエリアを確保した後、初期化しています。 例では、各構造体の項目数が少ないのですが、 項目が増えた場合、下記のような初期化方法だと面倒だと思います。 もっとよい方法があるのだろうと思っているのですが・・・。 下記は私の試行錯誤結果なので、「普通はこうやるんじゃないの?」という方法などがあればご教授願います。 /* -- 構造体定義 -- */ typedef struct {   char data[16] ; }D_TAG ; typedef struct {   char name[16];   D_TAG *d ; }F_TAG ; typedef struct {   char name[16] ;   F_TAG *f ; }T_TAG ; /* -- 変数定義 -- */ T_TAG *t ; /* -- エリア確保 -- */ t=(T_TAG*)malloc(sizeof(T_TAG)*10); for(i=0;i<10;i++) {   t[i].f=(F_TAG*)malloc(sizeof(F_TAG)*10);   for(j=0;j<10;j++) {     t[i].f[j].d = (D_TAG*)malloc(sizeof(D_TAG)*10);   } } /* -- 初期化 -- */ for(i=0;i<10;i++) {   memset(t[i].name , 0x00, sizeof(t[i].name));   for(j=0;j<10;j++) {     memset( t[i].f[j].d, 0x00, sizeof(D_TAG)*10);     memset( t[i].f[j].name , 0x00, sizeof(t[i].f[j].name));   } } よろしくお願いいたします。

  • 構造体の配列のアロケート等の方法

    基本的な事かもしれないのですが、 構造体の配列をダブルポインタで返すような関数を作成したいのですが、アロケートの仕方と、そもそも配列をダブルポインタで扱う方法が良く分かってないのかもしれません。 どなたかご教授頂けないでしょうか? Webで調べてもなかなか合ったものが見つからないため、こちらに質問させて頂きました。 イメージしているものを↓に途中まで作ってみました。これも合っていない部分があるかもですが。。。 要はアロケートして構造体の配列を作成する部分と、それをfor文で回して参照する方法が、分かっていない主なところです。 #include <stdio.h> #include <memory> typedef struct member{   int  id;   char*  name; } *member_t; int get_result(member_t *pobj) {   member_t* obj = NULL;   obj = (member_t*)malloc(sizeof(member_t));   memset(obj, 0x00, sizeof(member_t));   char* nm = NULL;   char cnmtmp[] = "nakayama";   nm = (char*)malloc(strlen(cnmtmp)+1);   memset(nm, 0x00, strlen(cnmtmp)+1);   memcpy(nm, cnmtmp, strlen(cnmtmp));   obj->id = 100;   obj->name = nm;   *pobj = obj;   return 0; } int get_resultList(member_t **ppobj) {   /*    * ココ    */   return 0; } void main() {   member_t* obj = NULL;   get_resultList(&obj);   for(int i = 0;;){     /*      * ココ      */     printf("[%d]\n",i+1);     printf("ID : %d\n", ->id);     printf("NAME : %s\n", ->name);     free( ->name);     free( );   }   free(obj); } 長々とすみません。