|
みなさん親切なレス有難うございます。
qsortはそもそも配列に使うものなんですね。知りませんでした。
YUOさんsizeofについての説明有難うございます。理解することができました。
ですが、もうひとつの質問に答えていただいたほうが理解できていません。
>ちなみに,n_cmpは
>int n_cmp(const void *, const void *);
>という宣言でないといけません。
>int n_cmp(const struct node *, const struct node *);
>でも,キャストすればコンパイルは通るでしょうけれど,コンパイルが通>る程度の安全性しかありません。
と答えていただいたのですが、
int n_cmp(const void *, const void *);
で宣言したときにこのファンクションの中を作る方法がわかりません。
私が前に示したリンクリストのプログラムは下のインターネットで見つけたプログラムを参考につくったものです。
/*
qsort関数を用いて配列をソート
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char name[10]; /* 名前 */
int height; /* 身長 */
int weight; /* 体重 */
} person;
/*--- person型オブジェクトの比較関数(名前昇順) ---*/
int npcmp(const person *x, const person *y)
{
return (strcmp(x->name, y->name));
}
/*--- person型オブジェクトの比較関数(身長昇順) ---*/
int hpcmp(const person *x, const person *y)
{
return (x->height < y->height ? -1 :
x->height < y->height ? 1 : 0);
}
/*--- person型オブジェクトの比較関数(体重降順) ---*/
int wdcmp(const person *x, const person *y)
{
return (x->height < y->height ? 1 :
x->height < y->height ? -1 : 0);/* 降順 */
}
/*--- 一人分のデータを表示 ---*/
void print_person(person x)
{
printf("%-10.10s %dcm %dkg\n", x.name, x.height, x.weight);
}
int main(void)
{
int i;
person x[]= {{"Shibata", 170, 52},
{"Takaoka", 180, 70},
{"Nangoh", 172, 63},
};
int nx = sizeof(x) / sizeof(x[0]); /* 配列xの要素数 */
puts("ソート前");
for (i = 0; i < nx; i++)
print_person(x[i]);
/* 名前昇順にソート */
qsort(x, nx, sizeof(person), (int(*)(const void*, const void*))npcmp);
puts("\n名前昇順ソート後");
for (i = 0; i < nx; i++)
print_person(x[i]);
/* 身長昇順にソート */
qsort(x, nx, sizeof(person), (int(*)(const void*, const void*))hpcmp);
puts("\n身長昇順ソート後");
for (i = 0; i < nx; i++)
print_person(x[i]);
/* 体重降順にソート */
qsort(x, nx, sizeof(person), (int(*)(const void*, const void*))wdcmp);
puts("\n体重降順ソート後");
for (i = 0; i < nx; i++)
print_person(x[i]);
return (0);
}
ここではnpcmpの引数にstructをつかっているようなのですが、これはあまりよくないのでしょうか?
今回、私はqsortの勉強のためにディレクトリにあるファイルの名前をアルファベット順にならべてみようと思い構造体のソートに挑戦しているんですが、
qsortは配列に使うものということなので構造体をリンクリストから配列に直してみました。(これではファイルの数に制限ができてしまいますが。。。今回はqsortの使い方を覚えたいので。)
ですが、やはりうまくいきません。以下にプログラムを示します。
どうか間違いを指摘ください。(構造体内のファイルの名前が格納される文字
列の変数のなまえがpathとなっていますが、いずれここにpathをいれるつも
りなので現段階ではそれをつかってます。)
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
struct File_info{
char path[500];
int size;
};
void file_list(char *dir, struct File_info *file_info);
int n_cmp(const struct File_info *x, const struct File_info *y);
int counter=0,num=0;
int main(int argc, char *argv[])
{
struct File_info file_info[100];
int k;
char dir_name[100];
strcpy(dir_name,argv[1]);
file_list(dir_name,file_info);
for(k=0; k<counter; k++){
printf("file path is %s and its size is %d.\n",
file_info[k].path,file_info[k].size);
}
int n = sizeof(file_info) / sizeof(file_info[0]);
qsort(file_info, n, sizeof(struct File_info),
(int(*)(const void*,const void*))n_cmp);
printf("Updated:\n");
for(k=0; k<counter; k++){
printf("file path is %s and its size is %d.\n",
file_info[k].path,file_info[k].size);
}
return 0;
}
int n_cmp(const struct File_info *x, const struct File_info *y)
{
return (strcmp(x->path, y->path));
}
void file_list(char *dir, struct File_info *file_info)
{
struct dirent *entry;
struct stat statbuf;
char *tail;
DIR *dp;
printf("%s/\n",dir);
dp = opendir(dir);
if (dp == NULL) {
perror("Can not open the directory.\n");
exit(1);
}
printf("dir is %s\n",dir);
tail = dir + strlen(dir);
*tail++ = '/';
while ((entry = readdir(dp)) != NULL) {
strcpy(tail, entry->d_name);
stat(dir, &statbuf);
if (!S_ISDIR(statbuf.st_mode)){
int n = strlen(entry->d_name);
if ((n > 2 && strcmp(entry->d_name + n - 2, ".c") == 0)){
strcpy(file_info[num].path,entry->d_name);
file_info[num].size = statbuf.st_size + 50;
num++;
counter++;
printf(" %s\n", entry->d_name);
}
}
}
rewinddir(dp);
while ((entry = readdir(dp)) != NULL) {
if (strcmp(entry->d_name, ".") == 0) continue;
if (strcmp(entry->d_name, "..") == 0) continue;
strcpy(tail, entry->d_name);
stat(dir, &statbuf);
if (S_ISDIR(statbuf.st_mode)){
file_list(dir,file_info);
}
}
closedir(dp);
}
|