質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
char

charは文字データ型を指します。一文字分の文字コードの格納を想定としている型です。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

ソート

複数のデータを、順序性に従って並べ替えること。 データ処理を行う際に頻繁に用いられ、多くのアルゴリズムが存在します。速度、容量、複雑さなどに違いがあり、高速性に特化したものにクイックソートがあります。

Q&A

解決済

2回答

5814閲覧

qsort()を用いてchar[][](ニ次元配列の文字列)のソートをするときの引数が分からない。

退会済みユーザー

退会済みユーザー

総合スコア0

char

charは文字データ型を指します。一文字分の文字コードの格納を想定としている型です。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

ソート

複数のデータを、順序性に従って並べ替えること。 データ処理を行う際に頻繁に用いられ、多くのアルゴリズムが存在します。速度、容量、複雑さなどに違いがあり、高速性に特化したものにクイックソートがあります。

0グッド

0クリップ

投稿2020/04/26 15:39

編集2020/04/26 15:46

##1.やりたいこと
qsortを用いて二次元配列内の文字列をソートしたい。
最初の入力で、入力する文字列の量を指定し、
以降の入力で文字列を入力する。
##2.問題点
以下のソースコードを実行しても、何も表示されない。
デバッガなどを用いて配列を確認してみたところ、
どうもqsortの引数がおかしくて配列が破壊されているように見える。

##3.ソースコード

C

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4 5int cmp(const void *a, const void *b){ 6 return strcmp(*(const char**)a, *(const char**)b); 7} 8 9int main(void){ 10 int n; 11 char s[10][10]; 12 13 scanf("%d",&n); 14 15 for(int i=0;i<n;i++){ 16 scanf("%s",s[i]); 17 } 18 19 qsort(s,n,1,cmp); 20 21 for(int i=0;i<n;i++){ 22 printf("%s\n",s[i]); 23 } 24 25 return 0; 26} 27

##4.自分が今分かっていること
- cppreference.comによると、qsortは4つの配列を持つ。
これの説明を用いて、なぜ自分のコード内のqsortをそう記述したのかを書いてみる。

qsort(s,n,1,cmp);

1つめの引数:ソートする配列を指すポインタ
ソートする配列は、自分のソースコードではs[10][10]であるので、sとした。

2つめの引数:配列の要素数
配列の要素数(=文字列の個数)は入力したnによって変化するのでnとする。

3つ目の引数:配列の各要素のバイト単位のサイズ
charは1バイトなので、1とした。

4つ目の引数:第1引数が第2引数より小さい場合は負の整数値、
第1引数が第2引数より大きい場合は正の整数値、
第1引数が第2引数と等しい場合はゼロを返す比較関数。

intをsortする場合と違って、charでは

cmpforint

1int cmp(const void *a,const void *b){ 2 if(*(int*)a>*(int*)b){return -1;} 3 else if(*(int*)a<*(int*)b){return 1;} 4 else {return 0;} 5}

でなく

cmpforchar

1int cmp(const void *a, const void *b){ 2 return strcmp(*(const char**)a, *(const char**)b); 3}

としなければ動かないらしいため。
(スタックオーバーフロー内の質問より)

引数のどこが間違っているか教えていただけないでしょうか。
##5.実行環境
Windows 10 VSC 1.44.2 GCC6.3.0

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

strcmp((char *)a, (char *)b); とすれば、C でも C++ でも OK。
C だと、strcmp(a, b); でもよい。

strcmp(*(const char**)a, *(const char**)b); はだめ。

これだと、呼び出し元のデータが、char s[10][10]; ではなく、
char *s[10]; でないといけません。

呼出しは、qsort(s, n, sizeof(s[0]), cmp);

投稿2020/04/26 16:47

編集2020/04/26 16:57
kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/04/26 16:55

ご回答ありがとうございます。 ご指摘の通りにqsortの呼び出しとcmp関数の修正を行ったところ、ちゃんと動くようになりました。 一つ質問があるのですが、なぜsizeof(s[0])という指定でないと動かないのでしょうか? sizeof(s[0])=10だと思うので、変わらないと思うのですが。
kazuma-s

2020/04/26 16:59

char s[10][20]; に変更した場合でも、呼び出しは変更しなくて済みます。
退会済みユーザー

退会済みユーザー

2020/04/26 17:03

すいません、そういう意味ではなく、 sizeof(s[0])=10なのだから、 qsort(s, n, sizeof(s[0]), cmp);と qsort(s, n,10, cmp); は等しいのではないか、という意図で質問しました。
退会済みユーザー

退会済みユーザー

2020/04/27 04:31

すいません、どうやらソートされない問題はcmp関数のほうにあったようなので、 qsort(s, n, sizeof(s[0]), cmp);と qsort(s, n,10, cmp);どちらでも正しく動くようになりました。
guest

0

3つ目の引数:配列の各要素のバイト単位のサイズ

charは8バイトなので、8とした。

ここが違います。charは1バイトです。で、char s[10][10];charが10個の配列を10個宣言しているので、ソートの単位である1つの配列は10バイトなので、10を指定します。

4つ目の引数:

は、それでも合ってますが、単にstrcmpをそのまま(あるいは適切にキャストして)引数にすればいいです。

投稿2020/04/26 15:58

otn

総合スコア84505

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/04/26 16:02

ご回答ありがとうございます。 qsort(s,n,10,cmp);としてみましたが、何も出力されませんでした。
otn

2020/04/26 22:43

> qsort(s,n,10,cmp);としてみましたが、何も出力されませんでした。 ああ、失礼。cmpはキャストしてるだけだと思っていたら、*演算子が付いてますね。 qsort(s,n,10,strcmp); で。
退会済みユーザー

退会済みユーザー

2020/04/27 04:28

出来ました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問