構造体を用いた並び替え関数

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
もやしいも

構造体を用いた並び替え関数

#1

投稿記事 by もやしいも » 13年前

『あらかじめ「名前 点数」が4行書かれているテキストファイルが保存されている。
これを読み込み構造体に代入して、点数が大きい順に並び替える関数を作りそれを表示する』
といったプログラムを作っています。並び替えるところまではできたのですがそれを関数で
作ることがうまくできません。どうすればよいでしょう?

コード:

 
#include<stdio.h>
#define N 500

struct seiseki
{
	char name[N];
	int ten;
};

int main(void)
{
	FILE *fp;
	int i,j,k;
	struct seiseki dummy,sort[4];
	
	fp=fopen("test.txt","r");
	
	for(i=0;i<4;i++){
		fscanf(fp,"%s %d",sort[i].name,&sort[i].ten);
	}
	
	for(j=0;j<4;j++){
		for(k=j+1;k<5;k++){
			if(sort[j].ten < sort[k].ten){
				dummy = sort[j];
				sort[j] = sort[k];
				sort[k] = dummy;
				}
				}
	printf("%s %d \n",sort[j].name,sort[j].ten);
				}
			
return 0;
}

 

usao

Re: 構造体を用いた並び替え関数

#2

投稿記事 by usao » 13年前

23行目以降の処理を,別関数にすればよいのだと思いますが
関数化できない理由は何でしょうか?
(例えば
void sort_seiseki( struct seiseki *pSeisekiArrayHead, int SeisekiArraySize );
のような)

それと,
このコードだと,kの値的に 存在しないsort[4]にアクセスしてしまうことになりそうです.

もやしいも

Re: 構造体を用いた並び替え関数

#3

投稿記事 by もやしいも » 13年前

初心者ですので、勉強のため便利な関数はできるだけ使わないようにプログラムを組んでいるためです。

non
記事: 1097
登録日時: 15年前

Re: 構造体を用いた並び替え関数

#4

投稿記事 by non » 13年前

usaoさんの質問されたことに対する回答になっていません。

関数でわからないことは何ですか?と、問われてますよ。
non

usao

Re: 構造体を用いた並び替え関数

#5

投稿記事 by usao » 13年前

より平たく書きます.

>23行目以降の処理を,別関数にすればよいのだと思いますが
>関数化できない理由は何でしょうか?
>(例えば
>void sort_seiseki( struct seiseki *pSeisekiArrayHead, int SeisekiArraySize );
>のような)
 ↓
あなたの目的を達するには,
23行目以降あたりに書かれている(おそらくバブルソートの)処理内容を,
main()関数とは別の関数としてまとめればよい ものと思いますが,
これを行うにあたり障害となっているものは何なのでしょうか?

(あなたが新たに作るべき当該関数のプロトタイプの例を挙げるとしたら,
 void sort_seiseki( struct seiseki *pSeisekiArrayHead, int SeisekiArraySize );
 のようになるのではないでしょうか.)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 構造体を用いた並び替え関数

#6

投稿記事 by softya(ソフト屋) » 13年前

質問とは直接関係ないのですが、インデントに乱れがあるので非常にコードを読み辛い状況です。
あくまで一例ですが、こんな風に書いてもらうとすごく読みやすくなります。

コード:

#include<stdio.h>
#define N 500

struct seiseki {
	char name[N];
	int ten;
};

int main( void ) {
	FILE *fp;
	int i, j, k;
	struct seiseki dummy, sort[4];

	fp = fopen( "test.txt", "r" );

	for( i = 0; i < 4; i++ ) {
		fscanf( fp, "%s %d", sort[i].name, &sort[i].ten );
	}

	for( j = 0; j < 4; j++ ) {
		for( k = j + 1; k < 5; k++ ) {
			if( sort[j].ten < sort[k].ten ) {
				dummy = sort[j];
				sort[j] = sort[k];
				sort[k] = dummy;
			}
		}
		printf( "%s %d \n", sort[j].name, sort[j].ten );
	}

	return 0;
}
インデントのスタイルにはいろんな流派がありますが統一してもらえればどれでも良いです。
「字下げスタイル - Wikipedia」
http://ja.wikipedia.org/wiki/%E5%AD%97% ... 4%E3%83%AB
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

もやしいも

Re: 構造体を用いた並び替え関数

#7

投稿記事 by もやしいも » 13年前

意味をよく理解しておらず失礼しました。
実際に関数を用いたプログラムを載せます。
主なエラー・警告は以下の2つです。ご教授お願いします。
【エラー E2277 kadai4-6.c 24: 左辺値が必要(関数 main )】
【警告 W8075 kadai4-6.c 48: 問題のあるポインタの変換(関数 nara )】

コード:

#include<stdio.h>
#define N 500

typedef struct seiseki
{
	char name[N];
	int ten;
}seisekiTyp;

seisekiTyp *nara(seisekiTyp *sort);

int main(void)
{
	FILE *fp;
	int i,n;
	seisekiTyp sort[4],kekka[4];
	
	fp=fopen("profiles.dat","r");
	
	for(i=0;i<4;i++){
		fscanf(fp,"%s %d",sort[i].name,&sort[i].ten);
	}

	kekka=nara(sort);
	for(n=0;n<4;n++){
		printf("%s %d \n",kekka[n].name,kekka[n].ten);
	}

 return 0;
}

seisekiTyp *nara(seisekiTyp *sort)
	{
		int j,k=0;
		seisekiTyp dummy,b[5];

	for(j=0;j<4;j++){
		for(k=j+1;k<5;k++){
			if(sort[j].ten < sort[k].ten){
				dummy = sort[j];
				sort[j] = sort[k];
				sort[k] = dummy;
				}
			}
			b[j]=sort[j];
		}

	return(b);
}

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 構造体を用いた並び替え関数

#8

投稿記事 by softya(ソフト屋) » 13年前

インデントに関する注意点とusaoさんの
>それと,
>このコードだと,kの値的に 存在しないsort[4]にアクセスしてしまうことになりそうです.

はスルーしないでいただきたいのですが。特にusaoさんの物は重要です。

>【エラー E2277 kadai4-6.c 24: 左辺値が必要(関数 main )】
>【警告 W8075 kadai4-6.c 48: 問題のあるポインタの変換(関数 nara )】

については、この上の2つが片付いてからで良いと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

non
記事: 1097
登録日時: 15年前

Re: 構造体を用いた並び替え関数

#9

投稿記事 by non » 13年前

usaoさんの指摘が解決したとして、次に

コード:

seisekiTyp *nara(seisekiTyp *sort)
関数の仕様をはっきりさせましょう。
引数として渡すのは、構造体のアドレスだけのようですが、個数はどうしますか?
一般的には、個数を渡したいところです。必ず、4個と限定していいのですか。

戻り値として、構造体のアドレスを返すようにしていますが、これは何を返したいのでしょうか?
ローカルで作成した変数のアドレスを返しても意味がありません。
non

usao

Re: 構造体を用いた並び替え関数

#10

投稿記事 by usao » 13年前

うーん,段階的にやるなら

(1)処理アルゴリズムの正しさを固める
まずは,最初の(関数を分ける前の)コードの状態から,ソート処理のバグ(配列の領域外参照)を解消し,
正しく動作することを十分に確認する.
(2)とりあえずソート処理を別関数に移す
次に,処理対象データたるsort[]をとりあえず外部変数にした状態で
  ソート処理だけをmain()とは別の関数にしてみる
  (これだと戻り値も引数もいらない.単にソート処理コードが別の関数に分離されて収まった,というだけの状態)
(3)ソート関数の仕様決定,変数のスコープとかの解決
最後に,(2)の状態から改造して,sort[]がmain()の中にある状態から
うまいこと引数をソート処理関数に引き渡す形に仕上げる

のように,いったん(2)の段階を差し挟んでみると一歩ずつ進めていけてよいのかなぁ?

閉鎖

“C言語何でも質問掲示板” へ戻る