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

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

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

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

Q&A

解決済

3回答

1150閲覧

文字列比較の条件式について

syachi

総合スコア3

C

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

0グッド

1クリップ

投稿2022/07/20 03:55

各行に1単語が羅列している辞書ファイルをコマンドラインから読み取り、標準入力に単語を入力すると二部探索で入力した単語の行数を探し、行数を返すコードです。
質問は、ファイルにない単語を入力した場合、-1を返すように書かなければならないのですが、60行目あたりの条件文でelseのときに-1をzに代入したらよいと思って、以下のコードのように書きました。
しかし、ファイルにない単語を入力しても何も表示されませんでした。ファイルにある単語は表示されます。何がいけないか教えていただきたいです。
また、6行目のint strCompare...から24行目の部分において、int r~の前の部分は日本語でヒントが与えられており、自分で書いたもので、int r~からの部分は資料に書かれていたコードをそのまま使うように言われました。int r~の部分が何を表しているのか教えていただきたいです。
試したこと:zの初期を-1にしておき、elseの時にzをprintするように書きましたが上手くいきませんでした。

C言語

1#include <stdio.h> 2#include <stdlib.h> 3typedef struct { 4 unsigned char s[24]; 5} word; 6int strCompare(unsigned char *a, unsigned char *b) { 7while((*a==*b)&&(*a!=0)&&(*b!=0)){ 8 a++; 9 b++; 10 } 11 if (*a<*b){ 12 return -1; 13 }else if(*a>*b){ 14 return 1; 15 }else if(*a==*b){ 16 return 0; 17 } 18int r = *a - *b; 19while((r == 0) && (*a != 0)) { 20a++; b++; 21r = *a - *b; 22} 23return r; 24} 25int main(int argc, char **argv) { 26 int i,c,k; 27 unsigned char t[24]; 28 word dict[110000]; 29 FILE *fp; 30 31 if (argc < 2) { 32 fprintf(stderr,"usage: ./a.out dictFile\n"); exit(1); 33 } 34 if ((fp=fopen(argv[1],"r")) == NULL) { 35 fprintf(stderr,"cannot open file %s\n",argv[1]); exit(1); 36 } 37 i=0; k=0; 38 while((c=fgetc(fp)) != EOF) { 39 if (c == '\n') { 40 dict[i].s[k] = 0; 41 i++; 42 k=0; 43 } else { 44 dict[i].s[k] = c; 45 k++; 46 } 47 } 48 fclose(fp); 49 int z; 50 int a, b, m; 51 while(scanf("%s",t)!=EOF){ 52 a=0;b=110000; 53 while(a<b){ 54 middle=(a+b)/2; 55 if(strCompare(dict[m].s, t)==0){ 56 z=m+1; 57 break; 58 }else if (strCompare(dict[m].s, t)>0){ 59 b=m; 60 }else if (strCompare(dict[m].s, t)<0){ 61 a=m; 62 }else{ 63 z=-1; 64 } 65 } 66 } 67 printf("%d\n",z); 68 } 69 return 0; 70} 71

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

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

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

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

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

ozwk

2022/07/20 04:10

そもそもコンパイルエラーになり、問題を再現できません。 質問文のコードを質問文に書いてある問題が起こるコードに修正してください
fana

2022/07/20 04:36

> int r~からの部分は資料に書かれていたコードをそのまま使うように言われました。 何故言われたことすらやらないのです??? > 何がいけないか教えていただきたいです。 てきとーにコードを弄りまわした結果が「上手くいく」可能性に賭けていること,では? ……とか書くと言葉が悪いとか何とか言われそうだけども,要はそういう事でしょう? > 60行目あたりの条件文でelseのときに-1をzに代入したらよいと思って の時点で,いじくる前のコードの意味を把握してないことは明白と見える.
int32_t

2022/07/20 05:07

middle は m の間違いでしょうかね。
dodox86

2022/07/20 06:01

マルチポスト先で既に回答をいただいていたのに、teratailにこの質問を投稿しているようですね。どちらの回答もないがしろにする自分勝手な行為。
guest

回答3

0

ベストアンサー

c

1 if(strCompare(dict[m].s, t)==0){ 2 }else if (strCompare(dict[m].s, t)>0){ 3 }else if (strCompare(dict[m].s, t)<0){ 4 }else{ 5 z=-1;

strCompare() の結果が0の場合、正の場合、負の場合がそれぞれ処理されているので、それ以外のケースというのは存在しません。} else{ は無意味です。

たとえば、a=100, b=101 のとき m=100 になりますが、strCompare() の結果が0以外だったらもう探索するところがないので内側のループを抜けたいですよね。

  • 結果が正の場合は b=100 になり while (a<b) が成立しなくなりループ終了します。
  • 結果が負の場合は a=100 になるので無限ループしていしまいますね。

投稿2022/07/20 05:05

編集2022/07/20 05:06
int32_t

総合スコア20832

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

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

fana

2022/07/20 05:25

・まず動かしているコードをそのまま貼れ ・変数の未初期化 ・無限ループって怖くね? + その対策法 ・そのelse意味なくね? 全てマルチポスト先で既出なのに何一つ直すつもりもない模様.
guest

0

z = -1となった時はmain関数内の変数a、bの値はどちらも変化しないのでwhile文から抜け出せず、最後のprintf関数まで行かないため、結果として何も表示されてないのではないのでしょうか?

投稿2022/07/20 04:44

ALOHAMS

総合スコア195

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

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

0

ローカル変数のmですが、初期化されてませんね

投稿2022/07/20 04:09

y_waiwai

総合スコア87747

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問