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

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

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

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

5回答

5212閲覧

C++ printf関数がループの際何故か二回実行される

tearetta

総合スコア10

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

1クリップ

投稿2018/08/18 09:33

編集2018/08/18 09:55
コード ```### 前提・実現したいこと 英字以外を入力した場合 ふざけるな と一回出てほしいのですが なぜか英字以外を入力すると **ふざけるなふざけるな** と二回出てしまいます (何も入力せずエンターキーを入力すると一回 ふざけるな と出ます) 一回だけ ふざけるな と言わせたい場合どのように記述したら良いでしょうか   ### 発生している問題・エラーメッセージ

英字を一字キー入力せよ2
ふざけるなふざけるな3
ふざけるなふざけるな4
ふざけるなふざけるな
ふざけるな
ふざけるな
ふざけるな
ふざけるな
ふざけるな
ふざけるな
ふざけるな000000
ふざけるなふざけるなふざけるなふざけるなふざけるなふざけるなふざけるなa
aの大文字はA
続行するには何かキーを押してください . . .

### 該当のソースコード ```C++ #include <stdio.h> int main(void) { char a,b; printf("英字を一字キー入力せよ"); Loop: scanf_s("%c", &a); if (a <= 'Z' && a >= 'A') { b = a + 32; printf("%cの小文字は%c\n",a, b); goto end; } else if (a <= 'z' && a >= 'a') { b = a - 32; printf("%cの大文字は%c\n",a, b); goto end; } else printf("ふざけるな"); goto Loop; end: return 0; }

試したこと

変数aを空にすれば良いのかなと、a=¥0; などと goto Loop;の前に入れてみたのですが 変わりませんでした
何か根本的に違う気がします

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

cateye

2018/08/18 10:11 編集

わざとなら構わないのですが、なぜgoto?
tearetta

2018/08/18 12:02

自分がわかりやすいようにした結果、gotoを使うことになりました
tearetta

2018/08/18 12:03

すみません、何故か三回連続で投稿されたので削除依頼を行っています
cateye

2018/08/18 13:50

他の方の投稿にも有りますが、(関数内ならどこにでも飛べる)gotoは見通しが悪くなるので止めた方がいいです。
tearetta

2018/08/18 14:23

gotoの良くない点がわかりました 別の方法も考えてみたいと思います アドバイスありがとうございます
guest

回答5

0

scanf(scanf_s)は、初心者が意図通りに使うのは難しい関数です。
使うのをやめましょう。

fgetsを使いましょう。

投稿2018/08/18 10:01

otn

総合スコア84555

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

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

tearetta

2018/08/18 12:01

まだ習っていませんが念頭にいれておこうと思います アドバイスありがとうございます
guest

0

ベストアンサー

・・・回答になってしまいますが、“こういう方法もある”と言うことで・・・

c

1usr~/test/c % cat ct0.c 2#include <stdio.h> 3int main(void) 4{ 5 char a, b, buf[32]; 6 7 printf("英字を一字キー入力せよ"); 8 // 9 for (;;) { // 永久ループ while(1)でも可 10 // scanf_s("%c", &a); 11 fgets(buf, sizeof buf, stdin); // otnさんの指摘 12 a = buf[0]; // 先頭に空白があればNG 13 // if (a <= 'Z' && a >= 'A') { 数学で言うところの a <= X <= bに合わせた 14 if ('A' <= a && a <= 'Z') { 15 b = a + 32; 16 printf("%cの小文字は%c\n", a, b); 17 break; 18 // } else if (a <= 'z' && a >= 'a') { 19 } else if ('a' <= a && a <= 'z') { 20 b = a - 32; 21 printf("%cの大文字は%c\n", a, b); 22 break; 23 } else { 24 printf("ふざけるな"); 25 } 26 } 27 28 return 0; 29} 30usr~/test/c % ./a.out 31英字を一字キー入力せよ0 32ふざけるな0 33ふざけるなa 34aの大文字はA 35usr~/test/c % ./a.out 36英字を一字キー入力せよ 2 37ふざけるな a 38ふざけるな d 39ふざけるなc 40cの大文字はC 41usr~/test/c % 42

投稿2018/08/18 16:02

cateye

総合スコア6851

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

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

tearetta

2018/08/19 08:10

コメントなども含め丁寧にコードを書いてくださりありがとうございます Visualstudioでy_waiwaiさんのアドバイス通り一行づつ確認し、問題なく動作していて感服しました 複数の文字をキー入力することで一文字づつストックされ一周事に一文字一文字処理されて、最後にエンターも文字として認識しもう一周しているということがわかりました まだ完全には理解出来ていない部分もありますが、自分なりに勉強して完全に理解出来るように知識を深めたいと思います 今回は一番長く付き添ってくださったcateyeさんをベストアンサーとして選ばせて頂きたいと思います 皆様本当にありがとうございました
cateye

2018/08/19 10:00 編集

コードは、ちゃんと動くのが大前提ですが、(いつ誰が見るかも分らないので)見やすいのも大事です(自分も余り自信はありませんが・・・)。scanf()が使いたいならfgets()で文字列を読み込んでsscanf() で取り出すのが、改行の対応も必要ないのでベターです。(fgets()は改行まで文字として読み込むので行末処理を行うような場合は注意が必要です)
tearetta

2018/08/20 11:50

あとで修正する手間を考えると見やすい表記に慣れていた方が良さそうだなと思いなおしました 今のところ参考にしているテキストですとscanfを多用しているので、もし練習問題などで悩む場面が来たらfgetsとsscanfを視野に入れたいと思います アドバイスありがとうございます
guest

0

まず、VC++ 2017でコンパイルしたら、

scanf_s("%c", &a);

ここが、そのままでは、動かなかったのですが、問題無いですか?
(一応、警告なので、動くが期待と違う結果)

なぜ、2回出るかですが、例えば、 1[Enter] とすると、入力は、2文字になります。 '1' と [Enter] です。最初に、 '1' が入力となり、goto で戻るので、残った、 [Enter] が読み込まれ、これも英字で無いと判定されます。

簡単には、 "%c" --> "%s" として最初の文字のみ判定するのも一つでしょう。

なお、goto文を使うと見通しが悪くなるので、使わないようにした方が良いと思います。

投稿2018/08/18 09:58

pepperleaf

総合スコア6383

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

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

tearetta

2018/08/18 12:00

テキストですとscanf表記なのですが、scanfを使うとビルドに失敗してしまい、ネットで調べた結果scanf_sを使っています ご丁寧な回答をありがとうございます
guest

0

いきなり 回答だけいうと よくないかと思いますので・・・。
y_waiwai さんがおっしゃっているように、きちんとデバッグして 確認してくださいね。

C

1scanf_s("%c", &a);

 で入力されるのは、1文字のコードだけではありません。
キーは2回押しているかと思います。

投稿2018/08/18 09:57

showkit

総合スコア1638

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

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

tearetta

2018/08/18 11:54

お心遣いありがとうございます ハッとさせられました
guest

0

VisualStudioを使ってるなら、ソースコードの左側をクリックして赤くすると、そこで実行を止めることができます。
そこから、変数の中身を見ながら、1行づつ実行したりもできますんで、そうやってコードの動作を見ていけばどうでしょうか

投稿2018/08/18 09:39

y_waiwai

総合スコア87774

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

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

tearetta

2018/08/18 09:41

ありがとうございます 検証してみます
y_waiwai

2018/08/18 09:43

で、質問のコードがぐちゃぐちゃになってます 編集ボタン、<code>ボタンを押して、'''の枠の中に貼り付けてください
tearetta

2018/08/18 09:56

ご指摘ありがとうございます 直しました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問