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

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

ただいまの
回答率

88.92%

文字が一致するか比較するif文がわからない

解決済

回答 5

投稿

  • 評価
  • クリップ 0
  • VIEW 371

langhtorn

score 59

実現したいこと

文字列s[7]t[7]が一致していたらsame,そうではなくて大文字と小文字の違いだけであったらcase-insentive,これらに該当しなかったらdifferentを出力したい。
以下私の考え方です。

  1. 文字が一致している->cnt++
  2. 1が一致していないとき、s[i]が大文字でt[i]が小文字のとき、またはs[i]が小文字でt[i]が大文字のとき、それぞれを大文字または小文字変換してそれがt[i]と一致すればカウント->cnsup++またはcnlow++
  3. 上記以外になったとき->cdiff++

回りくどい気がしますが私が思いついたのはこの程度です。

問題点

一致しないカウントのcdiffは何をいれてもカウントが0になってしまう。
printf("もはや全部違う\n");whileの最後のifを通過したかどうか確認してみたが出力されることはなかった。
実行例

s: AbcDe
t: AbcDf
一致cnt= 5  大文字小文字cnsup= 0  小文字大文字cnlow= 0  違うcdiff= 0
--------------------------------------------------------------------
文字列を入力してください
s: AbCdE
t: AbcDe
s[2]が大文字でt[2]が大文字のとき
s[3]が小文字でt[3]が大文字の時
s[4]が大文字でt[4]が大文字のとき
一致cnt= 3  大文字小文字cnsup= 2  小文字大文字cnlow= 1  違うcdiff= 0
case-insensitive
-------------------------------------------------------------------
文字列を入力してください
s: AbcDe
t: AbcDe
一致cnt= 6  大文字小文字cnsup= 0  小文字大文字cnlow= 0  違うcdiff= 0
same

コード

//文字列の比較1

#include<stdio.h>
#include<ctype.h>

int main(void)
{
    char s[7],t[7];
    printf("文字列を入力してください\n");
    printf("s: ");
    fgets(s,7,stdin);
    printf("t: ");
    fgets(t,7,stdin);

    int cnt,cnsup,cnlow,cdiff;
    cnt=0;
    cnsup=0;
    cnlow=0;
    cdiff=0;
    int i=0;
    while(t[i]!='\0'){
        if(s[i]==t[i]){ //小文字大文字もすべて一致
            cnt++;
        }else if(isupper(s[i])){ //s[i]が大文字で
                   if(islower(t[i])){ //t[i]が小文字の時
                       printf("s[%d]が大文字でt[%d]が大文字のとき\n",i,i);
                       char isi=tolower(s[i]);
                          if(isi==t[i]){ //s[i]を小文字に変換して一致したらOK
                               cnsup++;
                            }
                    }
        }else if(islower(s[i])){ //s[i]が小文字でt[i]が大文字の時
                  if(isupper(t[i])){
                      printf("s[%d]が小文字でt[%d]が大文字の時\n",i,i);
                      char isl=toupper(s[i]);
                        if(isl==t[i]){ //s[i]が大文字変換して一致したらOK
                            cnlow++;
                        }
                    }
        }else{ //もはや文字が違う時
        printf("もはや全部違う\n");
            char isi=tolower(s[i]); //小文字
            char isl=toupper(s[i]); //大文字

            if(isi!=t[i] || isl!=t[i]) cdiff++; //小文字を大文字に変換しても大文字を小文字に変換しても一致しないとき
        }
        i++;
    }
    printf("一致cnt= %d  大文字小文字cnsup= %d  小文字大文字cnlow= %d  違うcdiff= %d  \n",cnt,cnsup,cnlow,cdiff);
    if(cnt==6){ //\0を含めて一致している
        printf("same\n");
    }else if(cdiff>0){
        printf("differnt\n");
    }else if(cnsup>0||cnlow>0){
        printf("case-insensitive\n");
    }

    return 0;
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 5

checkベストアンサー

+1

これはif文とelse文の対応(というべきか?)に起因する問題ですね。
PAST2020 Aだと思いますが、その場合入力は英大小文字のみなので、

}else if(isupper(s[i])){ //s[i]が大文字で


英大文字の場合ここでキャッチされ、

 }else if(islower(s[i])){ //s[i]が小文字でt[i]が大文字の時


英小文字の場合ここでキャッチされ、

        }else{ //もはや文字が違う時
        printf("もはや全部違う\n");
            char isi=tolower(s[i]); //小文字


ここに到達することはありません。

これをそのままのコードの構造で解決するのはなかなか面倒なので、アルゴリズムから見直すことにしましょう。
質問者様のやりたかったことは、

  1. s[i] == t[i]なら、cnt++
  2. s[i]が大文字かつt[i]が小文字のとき、tolower(s[i]) == t[i]なら、cnsup++
  3. s[i]が小文字かつt[i]が大文字のとき、toupper(s[i]) == t[i]なら、cnlow++
  4. どの条件も満たさないとき、cdiff++

だと思われますが、この2と3は区別する必要がないのではありませんか?

例えば、もうどちらも小文字に変換してから比較すれば、どちらが元々どうだったか考える必要はありません。

こういうのはどうでしょう。

  1. s[i] == t[i]なら、cnt++
  2. tolower(s[i]) == tolower(t[i])なら、cnlow++
  3. どの条件も満たさないとき、cdiff++

また、もしかすると、カウントする必要すらないのではないでしょうか。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/16 11:16

    自分の考えは回りくど過ぎました💦ありがとうございます。

    キャンセル

+1

else if(isupper(s[i])の判定で分岐してしまえば、それ以降のelseに流れることはありません。ということで、「s[i]が大文字で、t[i]と(大小を無視しても)全く違う文字だった」という場合には、何の処理もなされないことになります。

他にも同様に、何の処理も行われないパターンがあります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/15 22:27

    「全く違う」文字数は直接カウントせずに、処理した文字数 - 残りの条件に当てはまった文字数、で算出するのが手軽かと思います。

    キャンセル

  • 2020/07/16 11:16

    最後のifを判定してくれない理由がよくわかりました。ありがとうございます。

    キャンセル

+1

                   if(islower(t[i])){ //t[i]が小文字の時


この if()が falseの時、何もカウントされません。ここで、違うをカウントすべきでは?
また、

                  if(isupper(t[i])){


も同様。
なお、入力の最後の \nも比較されてますが、必要?

        }else{ //もはや文字が違う時


ここに来るのは、s[i]が、t[i]に一致せず、英字以外の時ですね。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/16 11:15

    回答ありがとうございます。

    キャンセル

+1

if に対応する else が無いところがあるのが問題です。

次のように考えればもっと簡単になります。

2つの文字列のどちらかが終端になるまでループ

  • 大小を無視しても異なれば、different 確定。
  • そうでなくて、一致しなければ case-insensitive の可能性あり。

ループ終了後、

  • different 確定か、どちらかが終端になっていなければ different。
  • そうでなければ、case-insensitive または same。
#include <stdio.h>  // printf, puts, fgets
#include <ctype.h>  // tolower

int main(void)
{
    char s[100], t[100];
    puts("文字列を入力してください");
    printf("s: "); fgets(s, sizeof s, stdin);
    printf("t: "); fgets(t, sizeof t, stdin);
    int different = 0;
    int case_insensitive = 0;
    int i;
    for (i = 0; s[i] && t[i]; i++) {
        if (tolower(s[i]) != tolower(t[i])) { different = 1; break; }
        if (s[i] != t[i]) case_insensitive = 1;
    }
    if (different || s[i] || t[i]) puts("differnt");
    else if (case_insensitive) puts("case-insensitive");
    else puts("same");
    return 0;
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/16 11:14

    ありがとうございます。

    キャンセル

0

//文字列の比較1

#include<stdio.h>
#include<ctype.h>

int main(void)
{
    char s[7],t[7];
    printf("文字列を入力してください\n");
    printf("s: ");
    fgets(s,7,stdin);
    printf("t: ");
    fgets(t,7,stdin);

    int cnt,cnsup,cnlow,cdiff;
    cnt=0;
    cnsup=0;
    cnlow=0;
    cdiff=0;
    int i=0;
    while(t[i]!='\0'){
        if(s[i]==t[i]){
            cnt++;
        }else if(tolower(s[i])==tolower(t[i])){
            cnlow++;
        }else{
            cdiff++;
        }
        i++;
    }
    //printf("一致cnt= %d  大文字小文字cnsup= %d  小文字大文字cnlow= %d  違うcdiff= %d  \n",cnt,cnsup,cnlow,cdiff);
    if(cnt==6){ //\0を含めて一致している
        printf("same\n");
    }else if(cdiff>0){
        printf("different\n");
    }else{
        printf("case-insensitive\n");
    }

    return 0;
}

/*実行結果
文字列を入力してください
s: AbcDe
t: AbcDe
same
-----------------------
文字列を入力してください
s: ABcDe
t: AbcDf
different
-----------------------
文字列を入力してください
s: AbcDe
t: ABcdE
case-insensitive
*/

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/16 11:40

    s: abcd
    t: abcd
    case-nsensitive
    5文字未満は入れてはいけないのですか?

    キャンセル

  • 2020/07/16 12:21

    条件に長さ5文字と書いてありました。

    キャンセル

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

  • ただいまの回答率 88.92%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る