データのソートについて
たとえば、下のようなデータがあるとして
flow0_0 0.00 0.00 edge1_0 1.5 0 0
flow0_0 1.00 1.48 edge1_0 1.5 0 0
flow0_0 2.00 4.64 edge1_0 1.5 0 0
flow0_0 3.00 10.23 edge1_0 1.5 0 0
flow0_0 4.00 17.52 edge1_0 1.5 0 0
flow0_0 5.00 26.32 edge1_0 1.5 0 0
flow0_1 6.00 0.00 edge1_0 1.5 0 0
flow0_0 6.00 36.79 edge1_0 1.5 0 0
flow0_1 7.00 1.67 edge1_0 1.5 0 0
flow0_0 7.00 48.75 edge1_0 1.5 0 0
flow0_1 8.00 5.30 edge1_0 1.5 0 0
flow0_0 8.00 62.29 edge1_0 1.5 0 0
flow0_2 9.00 0.00 edge1_0 1.5 0 0
flow0_1 9.00 11.09 edge1_0 1.5 0 0
flow0_0 9.00 77.03 edge1_0 1.5 0 0
flow0_2 10.00 2.20 edge1_0 1.5 0 0
flow0_1 10.00 18.48 edge1_0 1.5 0 0
flow0_0 10.00 93.32 edge1_0 1.5 0 0
flow0_2 11.00 6.54 edge1_0 1.5 0 0
flow0_1 11.00 27.48 edge1_0 1.5 0 0
このデータを並び替えて
flow0_0 0.00 0.00 edge1_0 1.5 0 0
flow0_0 1.00 1.48 edge1_0 1.5 0 0
flow0_0 2.00 4.64 edge1_0 1.5 0 0
flow0_0 3.00 10.23 edge1_0 1.5 0 0
flow0_0 4.00 17.52 edge1_0 1.5 0 0
flow0_0 5.00 26.32 edge1_0 1.5 0 0
flow0_0 6.00 36.79 edge1_0 1.5 0 0
flow0_0 7.00 48.75 edge1_0 1.5 0 0
flow0_0 8.00 62.29 edge1_0 1.5 0 0
flow0_0 9.00 77.03 edge1_0 1.5 0 0
flow0_0 10.00 93.32 edge1_0 1.5 0 0
flow0_1 6.00 0.00 edge1_0 1.5 0 0
flow0_1 7.00 1.67 edge1_0 1.5 0 0
flow0_1 8.00 5.30 edge1_0 1.5 0 0
flow0_1 9.00 11.09 edge1_0 1.5 0 0
flow0_1 10.00 18.48 edge1_0 1.5 0 0
flow0_1 11.00 27.48 edge1_0 1.5 0 0
flow0_2 9.00 0.00 edge1_0 1.5 0 0
flow0_2 10.00 2.20 edge1_0 1.5 0 0
flow0_2 11.00 6.54 edge1_0 1.5 0 0
のような形にしたいのですが
そのプログラムがわかりません。教えてください。
flow0_0
flow0_1
flow0_2の順番にしたいです。
たとえば、flow0_300までデータがあってでもソートできますか?
よろしくお願いします。
/* 読み込み行の、第1番目と2番目の2項目データについて一括ソートする例です。
なお、メモリサイズは malloc()により動的となっており、読み込み行数はあなたのマシン容量となっています。
実行は
./×××.exe data.txt
○○○.txtファイルにしまいたければ
./×××.exe data.txt >○○○.txt
*/
#include <stdio.h> /* printf(), fgets(), sprintf() */
#include <string.h> /* strcmp() */
#include <stdlib.h> /* malloc() */
#include <errno.h> /* errno */
#define SIZE 128 /* 読み込みメモリ容量 */
#define RETU 40 /* 1行の文字列長さ */
struct view {
char code[6];
char val[10];
char pocket[RETU];
};
/* プロトタイプ宣言 */
void setup_data(char *a, char *b, char *p);
int compare(const void *ta, const void *tb);
int main(int argc, char *argv[])
{
FILE *fp;
char *file_name, temp[SIZE];
struct view (*dat);
int line_size, n_gyo, n, i;
/* 1)ファイル名を特定 */
if(argc!=2){
fprintf(stderr, "Parameter error.\n");
exit(EXIT_FAILURE);
}
file_name=argv[--argc];
/* 2)ファイルを開く */
if( (fp=fopen(file_name,"r")) == NULL){
fprintf(stderr, "%s\n", strerror(errno));
exit(EXIT_FAILURE);
}
/* 3)1行の大きさとその行数から、配列を動的に割り当て. */
fgets(temp, SIZE, fp);
line_size = strlen(fgets(temp, SIZE, fp));
fseek(fp, 0, SEEK_END);
n_gyo = ftell(fp) / line_size;
if((dat = (struct view *)malloc(n_gyo * sizeof(*dat))) == NULL){
fprintf(stderr, "%s\n", strerror(errno));
exit(EXIT_FAILURE);
}
fseek(fp, 0, SEEK_SET);
/* 4)ファイルの終わりまで配列を読み込み、その都度表示する */
n = 0;
while(i < n_gyo && fgets(dat[n].pocket, SIZE, fp) != NULL){
setup_data(dat[n].code, dat[n].val, dat[n].pocket);
fprintf(stderr, "%s\n", dat[n].pocket); //表示はお好きなように
n++;
}
fprintf(stderr, "\n");
/* 5)ファイルを閉じる */
fclose(fp);
/* 6)ソート(内部qsort()関数を使う) */
qsort(dat,n,sizeof(dat[0]), compare);
/* 7)結果の出力 */
for(i=0; i<n; i++){
printf("%s\n", dat[i].pocket);
}
/* 8)malloc()後のメモリ解法を忘れぬこと */
free(dat);
return 0;
}
void setup_data(char *a, char *b, char *p)
{
char buff[12], *x;
int c;
while(*p++ != '_');
x = buff;
while((*x++ = *p++) != ' ');
*x = '\0';
sprintf(a, "%4s", buff); //右詰めで4文字の長さ
while(*p == ' ') p++; //スペースをスキップ
x = buff;
while((*x++ = *p++) != ' ');
*x = '\0';
sprintf(b, "%8s", buff); //右詰めで8文字の長さ
while(*p != '\n') p++; //末尾を探し
*p = '\0'; //改行コードを抹消する
}
int compare(const void *ta, const void *tb)
{
struct view *a=(struct view *)ta, *b=(struct view *)tb;
int flag;
if((flag=strcmp(a->code, b->code)) == 0){ //codeについて
return strcmp(a->val, b->val); //valについて
} else return flag;
}
----- ./a.out data.txt 2>/dev/null -----
flow0_0 0.00 0.00 edge1_0 1.5 0 0
flow0_0 1.00 1.48 edge1_0 1.5 0 0
flow0_0 2.00 4.64 edge1_0 1.5 0 0
flow0_0 3.00 10.23 edge1_0 1.5 0 0
flow0_0 4.00 17.52 edge1_0 1.5 0 0
flow0_0 5.00 26.32 edge1_0 1.5 0 0
flow0_0 6.00 36.79 edge1_0 1.5 0 0
flow0_0 7.00 48.75 edge1_0 1.5 0 0
flow0_0 8.00 62.29 edge1_0 1.5 0 0
flow0_0 9.00 77.03 edge1_0 1.5 0 0
flow0_0 10.00 93.32 edge1_0 1.5 0 0
flow0_1 6.00 0.00 edge1_0 1.5 0 0
flow0_1 7.00 1.67 edge1_0 1.5 0 0
flow0_1 8.00 5.30 edge1_0 1.5 0 0
flow0_1 9.00 11.09 edge1_0 1.5 0 0
flow0_1 10.00 18.48 edge1_0 1.5 0 0
flow0_1 11.00 27.48 edge1_0 1.5 0 0
flow0_2 9.00 0.00 edge1_0 1.5 0 0
flow0_2 10.00 2.20 edge1_0 1.5 0 0
flow0_2 11.00 6.54 edge1_0 1.5 0 0
> ごめんなさい、プログラムはあまり勉強していないのでわかりません。
プログラムを勉強することが目的でないなら、sort コマンドとか使えばいいじゃん。結構 OS 標準で使えるでしょ。それでスクリプトでもでっち上げれば、入力データが毎回変わっても対応できるし。
#include <stdio.h>
#include <stdlib.h>
int cmp(const void *a, const void *b)
{
return strtol(*(char **)a + 6, NULL, 10) - strtol(*(char **)b + 6, NULL, 10);
}
int main(void)
{
const char *s[] = {"flow0_0 0.00 0.00 edge1_0 1.5 0 0",
"flow0_0 1.00 1.48 edge1_0 1.5 0 0",
"flow0_0 2.00 4.64 edge1_0 1.5 0 0",
"flow0_0 3.00 10.23 edge1_0 1.5 0 0",
"flow0_0 4.00 17.52 edge1_0 1.5 0 0",
"flow0_0 5.00 26.32 edge1_0 1.5 0 0",
"flow0_1 6.00 0.00 edge1_0 1.5 0 0",
"flow0_0 6.00 36.79 edge1_0 1.5 0 0",
"flow0_1 7.00 1.67 edge1_0 1.5 0 0",
"flow0_0 7.00 48.75 edge1_0 1.5 0 0",
"flow0_1 8.00 5.30 edge1_0 1.5 0 0",
"flow0_0 8.00 62.29 edge1_0 1.5 0 0",
"flow0_2 9.00 0.00 edge1_0 1.5 0 0",
"flow0_1 9.00 11.09 edge1_0 1.5 0 0",
"flow0_0 9.00 77.03 edge1_0 1.5 0 0",
"flow0_2 10.00 2.20 edge1_0 1.5 0 0",
"flow0_1 10.00 18.48 edge1_0 1.5 0 0",
"flow0_0 10.00 93.32 edge1_0 1.5 0 0",
"flow0_2 11.00 6.54 edge1_0 1.5 0 0",
"flow0_1 11.00 27.48 edge1_0 1.5 0 0"};
int i;
const int n = sizeof s / sizeof s[0];
for(i = 0; i < n; ++ i) puts(s[i]);
putchar('\n');
qsort(s, n, sizeof s[0], cmp);
for(i = 0; i < n; ++ i) puts(s[i]);
return 0;
}
できますよ。
あなたはどこまで考えたのですか?
質問の補足で
あなたの考えたプログラムを見せて下さい。
それを見た上で、お教えしてもいいです。
没有评论:
发表评论