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

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

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

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

標準入力

標準入力(stdin)は、プログラムが標準的に用いるデータ入力元。リダイレクトしない限り、プログラムを起動した端末のキーボードが標準入力になります。UNIX系OSやC言語に実装されて普及した概念ですが、他のOSや言語も含めた総称としても使われます。

標準出力

標準出力(stdout)は、プログラムが標準的に用いるデータ出力元。標準出力に書き込み要求を発行しすることにより、ディスプレイ装置にデータを表示することができます。UNIX系OSやC言語に実装されて普及した概念ですが、他のOSや言語も含めた総称としても使われます。

ソート

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

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

Q&A

解決済

3回答

1688閲覧

文字列の辞書順ソートで出力されない

grape_ll

総合スコア83

C

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

標準入力

標準入力(stdin)は、プログラムが標準的に用いるデータ入力元。リダイレクトしない限り、プログラムを起動した端末のキーボードが標準入力になります。UNIX系OSやC言語に実装されて普及した概念ですが、他のOSや言語も含めた総称としても使われます。

標準出力

標準出力(stdout)は、プログラムが標準的に用いるデータ出力元。標準出力に書き込み要求を発行しすることにより、ディスプレイ装置にデータを表示することができます。UNIX系OSやC言語に実装されて普及した概念ですが、他のOSや言語も含めた総称としても使われます。

ソート

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

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

0グッド

0クリップ

投稿2020/05/22 02:54

編集2020/05/23 01:10

質問内容

C言語で,文字列の辞書順ソートをした一番若い者を出力したいのですが,入力をしても何も出力されませんでした。
またwhileのあとにprintf("%s\n",str[0]);としても何も起こりませんでした。
これはもう最初から入力が出来ていないということだと思うのですが,どこを直せばいいのか教えてください。
よろしくお願いいたします。

問題

英単語が1個以上の空白類(空白または改行)で区切られて並んでいるとする。入力の中で辞書順で一番若い単語(通常の英語辞書の見出しとして最も前にくる単語)を出力するプログラムを作れ。ただし,英字はすべて小文字に置き換えて扱え。

入力

標準入力がキーボードから行われるときは、入力の最後に C-d を入力する。

出力

出力は、その英単語だけを1行として書き出せ。

入力例1
first
second third
third
出力例1
first

入力例2
one two one
three
four
出力例2
four

書いたコード

C

1#include<stdio.h> 2#include<string.h> 3#include<stdlib.h> 4int scmp(const void *a, const void *b){ 5 return strcmp(*(char**)a, *(char**)b); 6} 7 8int main(void){ 9 char str[1000][1000]; 10 int i=0; 11 while(scanf("%s",str[i])!=EOF) i++; 12 printf("%s\n",str[0]); 13 14 qsort(str,i,sizeof(char*),scmp); 15 printf("%s\n",str[0]); 16 17 return 0; 18}

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

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

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

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

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

guest

回答3

0

ベストアンサー

char str[10000][100000];char str[1000][1000]; に変更して
領域が確保できない問題は解決されました。

でも、なぜ 1000 にしたのか説明できますか?
100000 は大きすぎるから 1000 にしただけですか?

一つの文字列(英単語) の長さが 1000 に近いことってあるでしょうか?
辞書に載っている最も長い単語とされているのが
pneumonoultramicroscopicsilicovolcanoconiosis
で、これでも 45文字です。
char str[1000][50]; で十分でしょう。

次にソートですが、並べ替えたいものは 英単語が入っている
50バイトの領域です。これが i 個あるのです。

qsort の呼び出しの第3引数には、sizeof(char[50])
または sizeof(str[0]) または sizeof(*str) と書かなければなりません。

scmp の引数の a と b は比較したい英単語の入った 50バイトの領域のアドレスです。

strcmp は const char * の引数を要求しますが、
C では void * から char * への暗黙の変換ができるので、
return strcmp(a, b); と書くことができます。

strcmp(*(char**)a, *(char**)b); と書かなければならないとすれば、
それは元のデータが char str[1000]; と宣言された場合の話です。
その場合は qsort の第3引数も sizeof(char
) となります。
またデータの入力方法は次のようになります。

C

1 char *str[1000]; 2 char buf[50]; 3 int i = 0; 4 while (scanf("%s", buf) == 1) str[i] = strdup(buf);

ここまでは理解できましたか?
コードを修正して思い通りに動きましたか?

さて、この問題ですが、ソートは不要です。
辞書順で一番若い単語を求めるだけですから、
ひとつの単語を読み込むたびに、それまでの一番若い単語と比較して
一番若い単語を更新すれば済みます。
そういうコードを書いてみてください。

そしてそれを質問に追記してください。

投稿2020/05/23 02:08

kazuma-s

総合スコア8224

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

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

grape_ll

2020/05/23 06:22

解説ありがとうございました。 1000はおっしゃる通り、なんとなく0を減らしただけでした。というのも単語が実在するものとは限らず,100を超えたら,と考えてなにも工夫せず1000にしてしまいました。 また、あまり関係のない話になるのですが大文字は小文字よりも若い扱いを受けるのですね。なので大文字を小文字に変換する部分を新たに付け加えました。 ご助言のおかげで思い通り動かせたので、最後に書かれているやり方にも挑戦してきます。辞書順と指定されてすぐにsortに行くのは短絡的なのですね。とても勉強になります。 コードを書くのに少々お時間を頂くことになりますが,書き終わりましたらぜひチェックの方,よろしくお願いいたします。
grape_ll

2020/05/23 06:33

コード書き終わりました。 よろしくお願いいたします。 ``` #include<stdio.h> #include<string.h> #include<stdlib.h> char str[50]; int main(void){ char ans[50]="zzzzzzzzzzzzzz"; while(scanf("%s",str)!=EOF) { if(strcmp(ans,str)>0) strcpy(ans,str); } printf("%s\n",ans); return 0; }```
guest

0

char str[10000][100000];
スタック領域を、大きく超えてしまいそうです。
(unix系なら大丈夫かもしれませんが、普通一般ユーザーは制限されています)

char str[10000][100000];
int main(void){
と、外部変数にしましょう。
出来ればもっと減らしましょう。

前出 qsort関数の呼び出し方が違うのもそのとおりです。
多分、第2引数の i-1 は i だけでいい気はします。

投稿2020/05/22 03:44

編集2020/05/22 03:51
PingHermit

総合スコア478

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

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

grape_ll

2020/05/22 06:09

この数にする前は適当にもっと大きい数にしてたらエラーになっていたのはそういう理由だったのですね。 数を減らして外に出すことにします。 呼び出し方はどのようにするのがいいのか教えていただけると幸いです。 またiについては確かにi-1だと1足りないです、ご指摘ありがとうございます。
PingHermit

2020/05/22 08:32

>呼び出し方はどのようにするのがいいのか 領域の確保の仕方は違いますが。 参照範囲が一つ外になっただけですから。 同じで大丈夫です。
grape_ll

2020/05/23 01:15

外部変数にして、i-1をiに直したのですが,出力がなにもありませんでした。 これの他にどこを直せばいいのか見当は付きますでしょうか? よろしくお願いします。
guest

0

qsort(str,i-1,sizeof(char*),scmp);

qsort関数の第3引数がポインタのサイズになってしまっています
これではだめですね

投稿2020/05/22 03:07

y_waiwai

総合スコア88042

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

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

grape_ll

2020/05/22 12:39

その部分はどう直せばいいのか教えていただけると幸いです。 よろしくお願いいたします。
y_waiwai

2020/05/23 09:01

よくみるといろいろスカなところがありますが、 それはまず横に置いといて、ここの部分だけでいうと、 qsort(str,i,sizeof(str[0]),scmp); ですかね
grape_ll

2020/05/25 11:02

sizeof(str[0])とするのに気づけていなかったみたいです。 ご回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問