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

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

ただいまの
回答率

90.23%

c言語で特定の文字列が入力されるまで配列に文字列を格納し続けるプログラムが上手く書けない

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,750

ijuya_yika

score 46

前提・実現したいこと

c言語で特定の文字列が入力されるまで配列に文字列を格納し続けるプログラムを書く

発生している問題・エラーメッセージ

(1) while文からbreakするための条件を満たす入力をしてもループから抜け出せない
(2) output_arrに入力した配列を結合する際に改行無しで結合したい

該当のソースコード

#include <stdio.h>
#include <string.h>

int main(void){
    int MaxInput = 1025;
    char output_arr[1025]; 
    char input_arr[1025];

    while(1){ 
        // Read user input
        puts("Enter a value : ");
        fgets(input_arr, MaxInput, stdin);

        if(!strcmp(input_arr, "a")) 
            break;
        else
            strcat(outputrr, input_arr);

        printf("Input_arr is %s\n", input_arr);
        printf("So far you entered %s\n", output_arr);
    }    

    return 0;
}

試したこと

printfで実際に入力された文字がinput_arrに格納されているか確認したが(!strcmp(input_arr, "a")の条件に引っかからない

実際に動かしてみると以下の通りになります。

Enter a value : 
123
Input_arr is 123

So far you entered 123

Enter a value : 
456
Input_arr is 456

So far you entered 123
456

Enter a value : 
a
Input_arr is a

So far you entered 123
456
a
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • kimurayu

    2017/10/25 12:40 編集

    実際 input_arr の値と strcmp(input_arr, "a") の値は何になりましたか

    キャンセル

  • ijuya_yika

    2017/10/25 12:49

    入力する値によって変動します。 例えば3と入力した場合-46, 其の次にAと入れた場合-32, 更に入力でaと入れた場合10となりました

    キャンセル

回答 3

checkベストアンサー

+2

printfで実際に入力された文字がinput_arrに格納されているか確認したが(!strcmp(input_arr, "a")の条件に引っかからない

fgetsは改行コードも取得するからです。
aとだけ打ち込んでエンターを押すと、実際にはa\nがinput_arrに与えられます。

output_arrに入力した配列を結合する際に改行無しで結合したい

原因は同様で、改行コードを含んだまま結合されてしまうからです。


改行コードを終端文字に置き換えてしまうといいでしょう。

for(int i = 0; input_arr[i]; i++) {
    if(input_arr[i] == '\n') {
        input_arr[i] = '\0';
    }
}

実行結果

Enter a value :
hoge
Input_arr is hoge
So far you entered hoge
Enter a value :
hoge
Input_arr is hoge
So far you entered hogehoge
Enter a value :
piyo
Input_arr is piyo
So far you entered hogehogepiyo
Enter a value :
fuga
Input_arr is fuga
So far you entered hogehogepiyofuga
Enter a value :
a

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/10/25 13:00 編集

    迅速なご回答ありがとうございます。とても助かりました。ただ入力文字数が大きくなるとfor文のループが無駄に感じてしまうのですが、何か別の方法は無いのでしょうか?

    キャンセル

  • 2017/10/25 13:05 編集

    yuki-saitoさんの方法で問題なく実行できました。
    そちらの方が簡潔でわかりやすく、処理速度の向上も期待できそうです。

    キャンセル

+2

input_arrには改行コード\nも一緒に入っています。
そのため一致しないのだと思われます。

output_arrも改行コードも一緒に結合されてしまうので
fgetsしたあとに\n の場所に \0を設定してから処理をすれば大丈夫かと思います。

input_arr[strlen(input_arr)-1] = '\0'

この1行をfgetsの次に入れれば、それ以外の処理は変えなくてもできるはずです。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/10/25 13:17

    はい、そうなります。
    先程の1行はフェールセーフ的なことは何も考慮されていないものなので、危険だと感じたらチェックぐらいは入れてもらった方が良いかもしれません!
    (基本的には入力値なので添え字がマイナスになることはないですが、それでもチェックを入れておく方がより安全です。)

    キャンセル

  • 2017/10/25 14:08

    ちなみにgets_s(C11で追加)は改行文字を\0に置き換え済みのものを返してくれます

    キャンセル

  • 2017/10/25 15:18 編集

    全然そっちの方が良いですね!
    (C言語を触らなくなってもう7年経つので的確な回答できずすみません。。)

    キャンセル

+2

こんにちは。

(1) while文からbreakするための条件を満たす入力をしてもループから抜け出せない

fgets()はgets()と異なり、(バッファが不足しない限り)改行文字まで含めて読み取ります。
ですので、判定はif(!strcmp(input_arr, "a\n"))とすれば意図通りになるだろうと思います。

(2) output_arrに入力した配列を結合する際に改行無しで結合したい

input_arrに既に改行文字が入っているので、それを単純にstrcat()するとoutput_arrにも改行文字が入ります。
strcat()する前にinput_arrの最後の改行文字を削るのも手です。バッファが不足している時は改行文字が無いので、それを想定する場合は、最後の文字が改行文字だったらそれを'\0'に置き換える等の工夫が必要です。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/10/25 13:02

    迅速なご回答ありがとうございます。とても助かりました。削る手段としてはfor文でループする等以外の方法ってあるのでしょうか?

    キャンセル

  • 2017/10/25 13:07

    例えば、下記で削れる筈です。(デバッグしてないのでバグがあったらごめんなさい。)
    int i=strlen(input_arr)-1;
    if (input_arr[i] != '\n') input_arr[i]=0;

    キャンセル

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

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

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

  • トップ
  • Cに関する質問
  • c言語で特定の文字列が入力されるまで配列に文字列を格納し続けるプログラムが上手く書けない