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

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

ただいまの
回答率

89.05%

C言語 文字列の操作に関する問題

解決済

回答 3

投稿 編集

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

aya0

score 14

問題
文字列sの中に、文字cが含まれていれば、その添え字(文字列中に文字cが複数ある場合は、最も先頭側の添え字とする)を返し、含まれていなければ-1を返す関数を作成せよ。
int str_char(const char s[],int c){/* ・・・*/}

下記は私が考えた、この問題に対するプログラムです。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int str_char(const char s[], int c)
{
    int i;
    int len = 0;

    while (s[len])
        len++;

    for (i = 0; i < len; i++) {
        if (s[i] == c) return i;    
    }
    return -1;
}

int main(void)
{
    char str[128];
    int co;

    printf("文字列を入力してください\n");
    scanf("%s", str);
    printf("文字を入力してください\n");
    scanf("%d",&co);
    printf("文字列の中にある入力した文字の添え字は%d\n", str_char(str, co));

    return 0;
}

このプログラムを実行すると、int str_char(const char s[],int c){/* ・・・*/}の返却値が必ず-1になってしまいます。
なぜ、if (s[i] == c) return i;としては、いけないのか理由が知りたいです。
よろしくお願いします。

下記は訂正後のコードです

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int str_char(const char s[], int c)
{
    int i;
    int len = 0;

    while (s[len])
        len++;

    for (i = 0; i < len; i++) {
        if (s[i] == c)
            return i;
    }
    return -1;
}

int main(void)
{
    char str[128];
    int a;
    char co;

    printf("文字列を入力してください\n");
    scanf("%s", str);
    printf("文字を入力してください\n");
    scanf(" %c", &co);
    a = str_char(str, co);
    printf("文字列の中にある入力した文字の添え字は%d\n", a);

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 3

checkベストアンサー

+2

なぜ、if (s[i] == c) return i;としては、いけないのか理由が知りたいです。

いえ、特に問題ありません。

問題があるのは値の入力の方で、scanf("%d",&co);intを入力させるようになっているので、「指定された文字コード」の文字を探す、という動作になってしまいます。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/02/25 16:20

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

    キャンセル

+2

int co; を char co; に、
scanf("%d", &co); を scanf(" %c", &co); にしてください。
" %c" の中のスペースは重要です。
これがなくて "%c" ではどうなるか試してみて
なぜそうなるのかを調べてみてください。

*追記*

3名の方が回答してくださったやり方をまとめて、やってみたのですが、文字を入力する部分で入力待ちがされなくて正常に実行されませんでした。

まとめてやってはいけません。別々にやったらどうなりますか?

そこで、getchar();をscanf(" %c", &co); の前に追加することも行った結果、正常に実行されました!

scanf(" %c", &co); の前に getchar(); は不要です。

正常に実行されなかった理由はscanf("%s", str);の処理後、stdin(標準入力)に[Enter](char型である?)が残ったままであったので、[Enter](char型である?)がscanf(" %c", &co);に入ってしまったためと考えました。

scanf("%c", &co); なら co に '\n' が入りますが、
scanf(" %c", &co); なら co に '\n' は入りません。
%c の前のスペースが '\n' を読み飛ばすので、co には [Enter] の後の文字が入ります。

<<これがなくて "%c" ではどうなるか試してみて
なぜそうなるのかを調べてみてください。>>については
%dですと'a'',b'',c'などの文字を入力すると、その文字のコード(数値)がcoに入力されてしまい、(s[i] == c)が文字と数値の比較になってしまうため、-1が返却値になってしまうと考えました。

int co; scanf("%d", &co); で a や b の文字を入力すると、
それらは数字ではないので、co に数値は入りません。
int co; scanf("%d", &co); で 97 や 98 を入力すると、
co にはそれらの数値が入り、それらは 'a' や 'b' のコードの値なので
文字を探すことができます。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/02/25 16:19

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

    3名の方が回答してくださったやり方をまとめて、やってみたのですが、文字を入力する部分で入力待ちがされなくて正常に実行されませんでした。

    そこで、getchar();をscanf(" %c", &co); の前に追加することも行った結果、正常に実行されました!
    正常に実行されなかった理由はscanf("%s", str);の処理後、stdin(標準入力)に[Enter](char型である?)が残ったままであったので、[Enter](char型である?)がscanf(" %c", &co);に入ってしまったためと考えました。
    ※[Enter]はchar型なのかは分かりません。

    <<これがなくて "%c" ではどうなるか試してみて
    なぜそうなるのかを調べてみてください。>>については
    %dですと'a'',b'',c'などの文字を入力すると、その文字のコード(数値)がcoに入力されてしまい、(s[i] == c)が文字と数値の比較になってしまうため、-1が返却値になってしまうと考えました。

    キャンセル

  • 2020/02/27 11:14

    ご指摘ありがとうございます!
    私がkazuma-sさんの回答文を読み間違えてしまい本当に申し訳ありません。
    %cの前にスペースを入れるとそのスペースが\nを読み飛ばしてくれるのですね!
    それと、scanf(" %c", &co);の部分なのですが、%cを%dにしても文字のコード(数値)を入力すれば、大丈夫だったのですね!
    危うく、勘違いのまま終わるところでした。
    すごく助かります!

    キャンセル

+1

先に回答された方と同じですが、解決策としては、
関数宣言のint str_char(const char s[], int c)の後半のint c
mainの中のint co;の2か所のintをcharにすると、
「文字コード」ではなく「文字」として認識されるのでよいかと思います。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/02/25 16:20

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

    キャンセル

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

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

関連した質問

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