誕生日にもらった意外なもの

C言語を勉強し始めて2ヵ月の者です。

今、苗字と年齢、身長、体重の順に10人分のデータを入力し、身長が降べきの順になるように並び替えて出力させるプログラムを、構造体を使って作成する問題を考えています。

ですが、コンパイルはうまくいくのですが、いざ実行するときにうまくいきません。どこがおかしいのでしょうか? 教えてください。



成功したとき、出力は、
伊藤 19歳 190cm 60kg
鈴木 25歳 188cm 72kg
    ・
    ・
    ・
というようになります。

以下が私の作成したソースです。よろしくお願いします。



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

typedef struct{
char name[7];
int age;
int height;
int weight;
}keisoku;

void swap(keisoku a[10], int i, int j){

keisoku temp;

temp=a[i];
a[i]=a[j];
a[j]=temp;

}



int main(void){

keisoku a[10];
int i, j;


while(scanf("%s %d %d %d",a[i].name,&a[i].age,&a[i].height,&a[i].weight)!=EOF){

for(i=0;i<10;i++){
for(j=0;j<10;j++){

if(a[i].height<a[j].height){

swap(a,i,j);
}
}
}

}
for(i=0;i<10;i++){

printf("%s %d歳 %dcm %dkg",a[i].name,a[i].age,a[i].height,a[i].weight);
printf("\n");
}

return 0;
}

A 回答 (4件)

#3です。



2カ所訂正してください。


struct set1 {
char name[24];

  ↓↓↓ 訂正 ↓↓↓

struct set1 {
char name[SIZE];


/* バブルソート */
for (i = 0; i < 10; i++) {

  ↓↓↓ 訂正 ↓↓↓

/* バブルソート */
for (i = 0; i < n; i++) {



なお、data_fileは元の data_fileが降順になっており、動きを確認できない環境にあるため

3
伊藤 19 190 60
鈴木 25 168 72
和田 22 173 663

としてください。そうすれば身長に応じて並べ替えられているのが確認できるでしょう。
失礼しました m(_ _)m
    • good
    • 0

 Linux または Mac OSXなどの UNIX系OSを使っている場合の回答です。


 struct構造体はなるべく main()関数の前に置くと広域変数として引数を意識することなくプログラミングできます。また、main()関数を最後に配置してCコンパイラーが関数を main()関数からジャンプできるようにしているのを良く見かけますが、プログラムの流れは上から下へ流れるようにしたほうが見易く、わかり易いですよ。なるべくなら面倒でもプロトタイプ宣言をして top-downプログラミングされることを勧めます(好みの問題もありますが...)。
 ファイルの読み込みのは、while(!feof(stdin)) が定番です。そのうち知らず知らずのうちに覚えてしまうでしょう。バブルソートの for()はうっかりミスのようですね。まあ、先は長いので、取り合えずは動くプログラムの内容を確認していただければ良いんじゃないでしょうか。
 実際の起動に際しては次の

3
伊藤 19 190 60
鈴木 25 188 72
和田 22 173 66

ようなデータファイル(例えば Data_file)をエディタで作成しておき、ターミナルのシェルプロンプトから
  ./a.out<data_file
と打ち込めば動きます。なお、データファイルの文字間は半角スペースを厳守してください。
 では、焦らない程度に頑張ってください。



/* One sample program by Mac OSX
* file name: tyran.c
* compile: gcc tyran.c
*/

#include<stdio.h>
#define SIZE 24/* 漢字が12字分 */
#define NUMBER 15/* データ数+α */

struct set1 {
char name[24];
int age;
int height;
int weight;
} keisoku[NUMBER];// データは広域設定の方が楽ですよ

/* プロトタイプ宣言(top-down記述ができ、見易い)*/
void print_out(char *, int);
void swap(struct set1 *, struct set1 *);

int main(void) {
int n, i, j;

/* データの読み込み */
i = 0;
scanf("%d", &n);
scanf("%s %d %d %d", keisoku[i].name, &keisoku[i].age, &keisoku[i].height, &keisoku[i].weight);
while (!feof(stdin)) {
i += 1;
scanf("%s %d %d %d", keisoku[i].name, &keisoku[i].age, &keisoku[i].height, &keisoku[i].weight);
}

/* 読み込みデータの内容 */
print_out("入力データ", n);

/* バブルソート */
for (i = 0; i < 10; i++) {
for (j = n - 1; j > i; j--) {
if(keisoku[j - 1].height < keisoku[j].height) {
swap(&keisoku[j -1], &keisoku[j]);
}
}
}

/* 結果の出力 */
print_out("整列結果", n);

return 0;
}


void print_out(char *comment, int n) {
int i;

printf("%s\n", comment);// 見易く改行
for(i = 0; i < n; i++) {
printf("\t%-10s %d歳 %dcm %dkg", keisoku[i].name, keisoku[i].age, keisoku[i].height, keisoku[i].weight);
printf("\n");
}
}


void swap(struct set1 *a, struct set1 *b) {
struct set1 temp;

temp = *a;
*a = *b;
*b = temp;
}
    • good
    • 0
この回答へのお礼

こう見ると、まだまだ私は勉強不足だなぁと感じさせられました。
本当にありがとうございました!

お礼日時:2010/01/05 09:19

main関数の最初で


while(scanf("%s %d %d %d",a[i].name,&a[i].age,&a[i].height,&a[i].weight)!=EOF){
としてるけど、このときiの値はどうなってるの?

他にもおかしいところがあるけど、それは他の人が指摘してくれるでしょう。
    • good
    • 0

void swap(keisoku a[10], int i, int j){


 keisoku temp;

 temp=a[i];
 a[i]=a[j];
 a[j]=temp;
}
値渡しの変数を操作して、何を求めたい?

 while(scanf("%s %d %d %d",a[i].name,&a[i].age,&a[i].height,&a[i].weight)!=EOF){
一番最初にこの「i」には何が入っている?
2回目以降この「i」には何が入っている?

 for(i=0;i<10;i++){
  for(j=0;j<10;j++){

   if(a[i].height<a[j].height){
    swap(a,i,j);
   }
  }
 }
一回しか入力していないのに、ループが100回回っている。
何も入っていない構造体を比較している。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!