ソート
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
void swap(char p[], char q[]);
void get(char bufG[],char **p_str);
typedef struct {
int number;
char *class_type;
char* name;
char *subject;
int num_akaten;
} my;
my *data;
int main(int argc, char* argv[])
{
FILE *fp;
int field = 0, line = 0;
char buf[1000];
char bufG[1111];
char *str;
int m;
int line2 = 0;
if((fp=fopen("test3.csv","r"))==NULL){
printf("ファイルが開けません");
}
while(fgets(buf, 1000, fp) != NULL){
line2++;
}
fclose(fp);
printf("%d\n", line2);
if((fp=fopen("test3.csv","r"))==NULL){
printf("ファイルが開けません");
}
data = (my *)malloc(sizeof(my) * line2);
while(fgets(buf,1000,fp) != NULL){
str = buf;
while(*str != '\0'){
get(bufG,&str);
switch(field){
case 0:
data[line].number = atoi(bufG);
break;
case 1:
data[line].class_type = (char *)malloc(strlen(bufG) +1);
strcpy(data[line].class_type, bufG);
break;
case 2:
data[line].name = (char *)malloc(strlen(bufG) + 1);
strcpy(data[line].name, bufG);
break;
case 3:
data[line].subject =(char *)malloc(strlen(bufG) + 1);
strcpy(data[line].subject, bufG);
break;
case 4:
data[line].num_akaten = atoi(bufG);
}
str++;
field++;
}
line++;
field = 0;
}
fclose(fp);
for(m = 0; m < line; m++){
printf("%d\n", data[m].number);
printf("%s\n", data[m].class_type);
printf("%s\n", data[m].name);
printf("%s\n", data[m].subject);
printf("%d\n", data[m].num_akaten);
}
return 0;
}
void get(char bufG[],char **p_str) {
int i;
char *str;
str = *p_str;
for(i = 0; *str != ',' && *str != '\0' ; i++){
if(*str == '\n'){
bufG[i] = '\0';
}
else{
bufG[i] = *str;
}
str++;
}
bufG[i] = '\0';
*p_str = str;
return ;
}
前問題の解答例を提示してくださった方のサンプルをコピペさせてもらって成績の項目を追加しています。本文ではget関数の型はchar*型で文字列を返していますが今回の件では余り関係ないのでこのままで。
ファイルの中身は
1,犬,ボルト,国語,2
2,猫,山田,数学,1
3,犬,鈴木,英語,2
4,犬,居合,国語,1
5,猫,伊藤,数学,2
6,猫,斎藤,数学,1
のような感じになってます。
クラスの名前は今までアルファベットできたがこちらにしました。
名前自体に意味はありません。クラス名を文字列にしただけです。
やりたいソートの条件は赤点の多い順が優先でクラスと好きな教科が
同じものをソートしたい。優先順位は赤点→クラスとが一致→教科が一致
なので
1,犬,ボルト,国語,2
3,犬,鈴木,数学,2
5,猫,伊藤,数学,2
2,猫,山田,数学,1
6,猫,斎藤,数学,1
4,犬,居合,国語,1
このようなファイルに並び替えされます。
今試してるのは↑のソースで各値を入れ終わった後に
for(p = 0; p < line; p++){
for(q = p + 1; q < line; q++){
if(data[p].num_akaten < data[q].num_akaten){
swap(&p,&q);//swapはp行とq行の全項目を入れ替える関数
}
}
}
こうするととりあえず赤点数の順にはなります
これからさらに上記のような並びにしたいです。(クラスと教科が同じ順)
ここからどうすればいいでしょうか?
出来れば同じループ内で処理したいです。
私が考えていたのがp行のクラスとq行のクラスが同じ場合
p+1行目のクラスがp行目のクラスと異なっているなら
p+1行目とq行目を交換するというのを試していましたが
うまくいかないのでこの方法はダメなのでしょう。
他にもっとよい方法がある といった場合教えていただけると助かります。
お礼
問題数の多い問いでしたが、 御回答有り難うございました(・∀・)