• 締切済み

[C言語]ソート関数の作成

現在受け取った構造体を受け取ってソートしてポインタで書き換える関数を作成しています。 構造体の配列 typedef struct{ char name[50]; int age; }member; member seito[10] strcpy(seito[0].name,"yamada") seito[0].age = 15; strcpy(seito[2].name,"ito") seito[2].age = 17; strcpy(seito[3].name,"saito") seito[3].age = 19; こちらの構造体は例です。 seito[2]の情報を[1]に seito[3]の情報を[2]に移動させたいのですが、上手くいきません。 構造体配列を、1引いてあげれば良いと思ったのですが、そうすると[0]までマイナスしてしまい上手く判定が出来ません。 どうかアドバイスお願いいたします。

みんなの回答

回答No.6

構造体のコピーで悩んでいるのでしょうか? seito[2]をseito[1]にコピーしたいなら、 seito[1]=setito[2]; ですみますが・・・ 入れ替えしたいのなら、 member temp; temp=seito[1]; seito[1]=seito[2]; seito[2]=temp; はずしてたらすいません。

  • Interest
  • ベストアンサー率31% (207/659)
回答No.5

> 期待していた結果は、他の関数で[0][1][2][3]と入っていた配列が > [0][2][3]と書き換えられ(削除されその削除された[1]を埋めるために > [2]のデータを[1]として入れるという結果でした。 ソート関係ないやん! と突っ込んでみました。 これって「リスト」とか「リンクリスト」と呼ばれるデータ構造で対応すべき話ですよね。「アルゴリズムとデータ構造」をキーワードにググってみてください。 例 http://www.geocities.jp/ky_webid/algorithm/010.html http://tdweb.cssa.chs.nihon-u.ac.jp/ds/ds06.html http://ja.wikipedia.org/wiki/%E9%80%A3%E7%B5%90%E3%83%AA%E3%82%B9%E3%83%88

  • Interest
  • ベストアンサー率31% (207/659)
回答No.4

1.上手くいかない、というのは具体的にはどうなってしまうのでしょうか? 2.そのソートする関数では、受け取った構造体の配列を「何の順に」ソートするのですか? (年齢? 名前?) 参考までに、年齢の若い順に並べ替える例を書いておきます。 /**  sort_member_by_age  member構造体の配列を年齢の若い順に並べ替える。  引数 [in/out] mem    member構造体配列の先頭アドレス  引数 [in]   mem_count member構造体配列の要素数  戻り値    -1     並べ替え失敗         0      並べ替え成功  備考:もっとも簡単なバブルソートの例です。 */ int sort_member_by_age(member mem[], int mem_count) {  int i, j;  /* 入力引数に対するエラー処理 */  memがNULLなら return -1;  みたいな感じで。  /* mem年齢の順に並べ替える。 */  バブルソートそのもの。  for(i=0; i<mem_count-1; i++){   for(j=mem_count-1; j<i; j--){    mem[j]とmem[j-1]のageを比較して、mem[j].ageの方が小さかったら中身を入れかえる;   }  }  return 0; /* 成功 */ } 中身を入れ替える方法は次の通りです。 入れ替える要素の番号を仮に a, b とします。  member  swap; /* 一時退避用 */  swap = mem[a];  strcpy( swap.name, mem[a].name );  mem[a] = mem[b];  strcpy( mem[a].name, mem[b].name );  mem[b] = swap;  strcpy( mem[b].name, swap.name );  // aとbの入れ替え完了。 位置合わせをするために全角スペースを入れてありますので、このままコピーしてもコンパイルが通りませんのでご注意ください。

回答No.3

 どういう環境で、どういう結果を期待して、どういう作業をしたら、 どううまくいかなかったのか書かないと。   >seito[2]の情報を[1]に >seito[3]の情報を[2]に移動させたい seito[1] = seito[2]; seito[2] = seito[3];

sinkosan
質問者

お礼

説明不足で申し訳ありません。 環境はボーランドのbcc32 ***.cでコンパイラしています。 エディタはサクラエディタです。 期待していた結果は、他の関数で[0][1][2][3] と入っていた配列が[0][2][3]と書き換えられ(削除され その削除された[1]を埋めるために[2]のデータを[1]として入れるという結果でした。 失敗した結果は[1]を表示させようとしてもnameは無表示 ageは0と出てしまいました。

  • asuncion
  • ベストアンサー率33% (2126/6286)
回答No.2

> 構造体を受け取ってソートして 例題の場合、なにでソートしようとしていますか? 名前ですか?年齢ですか? > ポインタで書き換える おっしゃっている意味がよくわかりません。 > 構造体配列を、1引いてあげれば良いと思った ソートとは関連性がない話です。

  • Tasuke22
  • ベストアンサー率33% (1799/5383)
回答No.1

まずソートのアルゴリズムを整理して、 プログラミング方法はその後です。 色々な方法がありますが、初心者に分かり易いのは、 まず、配列要素のポインタの作業配列を作り、 最小値を検索し、その要素を別の配列に先頭から ポインタを入れていけばいいでしょう。 使ったポインタはNULLを入れます。 出来上がった配列を返す仕組みですね。 説明が自分でもヘタとは思いますが、分かるでしょう か?

関連するQ&A

  • C言語について教えてください。

    名前、身長、体重をメンバとする構造体オブジェクトを要素とする配列を宣言・定義する。 (1)名前、身長、体重を構造体オブジェクトのメンバに格納する関数 (2)平均身長を計算する関数 (3)平均体重を計算する関数 をそれぞれ定義し、その関数の機能を確認するプログラムを作成する。 構造体オブジェクトの各メンバは以下の値をもつとする。 Name Height(cm) Weight(kg) Tom 174.2 72.3 Jerry 152.3 49.2 Spike 168.6 84.8 ただし、平均身長と平均体重は呼び出し元の関数(関数main())で表示する。 また(2)(3)については、生徒の人数が変更されても処理できる関数を作成する。 [実行結果の例] 平均身長:165.0cm 平均体重: 68.0kg [ヒント] 構造体の配列でまとめられたデータから平均身長あるいは平均体重を計算する関数 <返却値型><関数名>(構造体の配列の受け渡しに対応した仮引数の宣言、生徒の人数) この問題について教えてください。 下のプログラムは自分でつかりかけたプログラムです。 #include <stdio.h> #include <string.h> struct student { char name[6]; double height; double weight; }; struct student set_student(char *n, double h, double w) { struct student ss; strcpy(&ss.name[0], n); ss.height = h; ss.weight = w; return ss; } int main(void) { struct student seito[3]; seito[0] = set_student("Tom", 174.2, 72.3); seito[1] = set_student("Jerry", 152.3, 49.2); seito[2] = set_student("Spike", 168.6, 84.8); return 0; } (2)(3)計算の計算する関数を定義し、表示させる方法がよく分かりません。具体的に教えてもらえませんか。よろしくお願いします。

  • C言語の構造体

    組込み系でマイコンにソフトをプログラミングの仕事をしています。 C言語は初心者です。 http://www9.plala.or.jp/sgwr-t/c/sec15.html のページの冒頭に、 「構造体は幾つかの異なる型のデータをまとめて 1つのデータ型として扱うものなのです。」と書かれています。 1つのデータ型として扱うとどのようなメリットがあるのでしょうか? 例えば、 struct seiseki seito1; のように対象が1つ(seito1)なら int seito1_no; char  seito1_name[20]; double seito1_average; と変数を確保すれば済むのに、 何故、構造体で宣言するのでしょうか? 例えば、 struct seiseki seito2[20]; のように、似たものが複数ある場合は(seito2が20人分なるなら、) 構造体で宣言する意味があるとはなんとなくわかります。 後ページの http://www9.plala.or.jp/sgwr-t/c/sec15-4.html では、関数でのやり取りが書かれています。 関数で引数や返値で扱うときに構造体にしておいた方が良いからでしょうか? 構造体のメリットというのが今一わかりません。 対象が1つでも構造体で書いた方がいろんな意味で良いのでしょうか? 如何せん、初心者なので質問がうまく書けませんがご了承ください。 ※上から目線的な回答はご遠慮願います。

  • C言語_関数_構造体です!教えて下さい!!

    <C言語です> 新しく関数を宣言した中で構造体を使用したいのですが, 上手くいきません。 ご指導宜しくお願い致します!! /*data.csv*/ ------------ 鈴木,21 田中,22 佐藤,23 ------------ 以下プログラム ------------ #include <stdio.h> /*構造体の宣言*/ typedef struct list{ char name[80]; int age; }list1; /*関数の宣言*/ void kiroku(FILE *fo,int ki1){ if(ki1==1) fprintf(fo,"%sの歳は%dです。",data[ki1].name,data[ki1].age); else if(ki==2) fprintf(fo,"%sの歳は%dです。",data[ki2].name,data[ki2].age); else fprintf(fo,"%sの歳は%dです。",data[2].name,data[2].age); } int main(){ char *fin="data.csv"; char *fnmo="kiroku.txt"; FILE *fi,*fo; list1 data[10]; int i,k,r; char ss[80]; //open files. fi=fopen(fin,"r"); fo=fopen(fnmo,"w"); //read r=0; while(fscanf(fi,"%[^,],%d",ss,&k)!=EOF){ strcpy(data[r].name,ss); data[r].age=k; r++; } i=1; /*関数の実行*/ kiroku(fo,i); // close files. fclose(fi); fclose(fo); return 0; }

  • 構造体について

    凄く初歩的な質問で申し訳ありませんが… 入門書の構造体のところで 以下のようなプログラムの例がありました。 #include <stdio.h> struct seiseki { /* 構造体の宣言 */ int no; char name[20]; double average; }; int main(void) { int i; struct seiseki seito1, seito2[20]; /* 構造体変数と構造体配列の宣言 */ >char name[20] というのは、NAMEの領域を20文字 確保すると言うことですよね? >struct seiseki seito1, seito2[20] ここの箇所が分からないのですが seito2[20]の20というのは どうして20なのですか? NAMEだけではないので もっと大きな数字になるような気がするのですが… またseito1の方は どうして数字が何もないんですか? 考え違いをしているところを ご指摘して頂ければ幸いです。

  • C言語の構造体について

    ご質問があります。 現在C言語について学習しているのですが、構造体を勉強しているときに下記のようなコードを作ったのですが storage size of 'mydata' isn't known というエラーが出てきてしまいます。 どこが間違っているのかがわかりません。 ご指南ご指導して頂けると助かります。 以下コード int main(void){ struct data mydata; mydata.name = "Yamada"; mydata.age = 30; mydata.height=173; mydata.weight = 65.4; printf("name = %s\n",mydata.name); printf("age = %d\n",mydata.age); printf("height = %d\n",mydata.height); printf("weight = %1f\n",mydata.weight); return EXIT_SUCCESS; }

  • C言語で配列の連結について教えてください

    以下のような構造体でmember[]の要素の後にmember2[]の要素を追加して、member[]を返す関数を作りたいのですがやり方がわかりません。よろしくお願いします。 (C++ vectorのpush_back、phpのarray_push()に相当する関数) typedef struct _MEMBER { char *name; int age; char *address; } MEMBER; MEMBER member[] = { "山田", 25, "東京都aaaaa", "木村", 30, "東京都bbbbb", "森田", 24, "東京都ccccc", }; MEMBER member2[] = { "伊藤", 23, "大阪府ddddd", "山野", 31, "大阪府eeeee", };

  • 構造体での2次元配列の宣言について

    構造体で2次元配列を初期化したいのですがうまくいきません。どうすればいいでしょうか? #include<stdio.h> struct student{ long gakusekino; char name[20]; char clas[5]; long age; }seito[10] = {2004001,"Aクン","sskk",20},        {2004001,"Bクン","ssdd",20}; /*下記はコンパイルが成功する例ですが上記の記述がうまくいかないしだいです。 struct student seito[10] = { {2004001,"Aクン","sskk",20},   {2004001,"Bクン","ssdd",20}; };

  • C言語 関数が文字列を含む構造体を返すとき

    生徒名、テストの点数 を要素とする構造体 struct test{char name[10];int score;}; を定義し、 点数の大きいほうを返す関数 struct test Top(struct test test1,struct test test2) { if(test1.score > test2.score) return test1; else return test2; } を定義しました。(この状態では同点のとき後者を返してしまいますが) main関数内で struct test test1; struct test test2; strcpy(test1.name,"yamada"); test1.score=70; strcpy(test2.name,"tanaka"); test2.score=90; と宣言・代入したあと、Top関数が返した点数と名前を表示したいのですが、 名前の表示がうまくいってくれません。 文字配列の操作が誤っているのでしょうか? 実行したのは次の操作です。 printf("Top score = %d\n",Top(test1,test2).score); printf("Top man = %c\n",Top(test1,test2).name[0]); printf("Top man = %s\n",Top(test1,test2).name); Top score = 90 Top man = t Top man = tanaka と表示されるのを期待していたのですが、 前二つの表示が終わるとダンプを起こしてしまいます

  • C言語 家系図

    問題 構造体personを以下のように仮定する。 struct person { int age; char name[20]; struct person *father; struct person *mother; }; この構造体の表す人の名前、年齢、その人の父親の名前、およびその人の母親の名前を出力する関数 void print_person(struct person *p) を作成せよ。出力の形式は name: 本人の名前 age: 本人の年齢 father: 父親の名前 mother: 母親の名前 となるようにすること。 また、ポインタ father や mother の値が NULL のときには、名前のかわりに unknown と出力するようにせよ。 以上が問題なのですが自分でプログラムを作ってみたところ実行したら、エラーになって矯正終了されてしまいました。 以下が私の作ったプログラムです。 #include <stdio.h> struct person { int age; char name[20]; struct person *father; struct person *mother; }; void set_name(struct person *p, char name[]) { int i; i = 0; while (name[i] != 0) { p->name[i] = name[i]; i++; } p->name[i] = 0; } void print_person(struct person *p) { printf("name:%s", p->name); printf("age:%s\n",p->age); if(p->father != NULL){ printf("father:%s\n",p->father); } else{ printf("unknown"); } if(p->mother != NULL){ printf("mother:%s\n",p->mother); } else{ printf("unknown"); } } int main(void) { struct person me, dad, mom; set_name(&me, "Michael"); me.age = 16; me.father = &dad; me.mother = &mom; set_name(&dad, "David"); dad.age = 38; dad.father = NULL; dad.mother = NULL; set_name(&mom, "Susan"); mom.age = 36; mom.father = NULL; mom.mother = NULL; print_person(&me); print_person(&dad); print_person(&mom); return (0); } どこが違うのか教えていただけないでしょうか?

  • C言語

    よろしくお願いします。  下記の構造体タグ「seiseki」を使って,表に示すデータをもつ構造体配列「list」を作成する.  関数に構造体配列「list」のアドレスを渡す.  関数で構造体ポインタ「*list」を利用して,一番点 数の高い者(1名限定)を調べ,その名前を表示する. struct seiseki{ char name[30]; int score; name score }; 表 佐藤 80 鈴木 75 田中 95 高橋 90