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

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

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

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

if

if文とは様々なプログラミング言語で使用される制御構文の一種であり、条件によって処理の流れを制御します。

DXライブラリ

DXライブラリとは、DirectXを使ったWindowsソフトの開発に必ず付いて回るDirectXやWindows関連のプログラムを使い易くまとめた形で利用できるようにしたC++言語用のゲームライブラリです。

Q&A

解決済

3回答

3353閲覧

同じ条件が被った際にif文が真になってしまわないようにしたい。

KZK13

総合スコア43

C

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

if

if文とは様々なプログラミング言語で使用される制御構文の一種であり、条件によって処理の流れを制御します。

DXライブラリ

DXライブラリとは、DirectXを使ったWindowsソフトの開発に必ず付いて回るDirectXやWindows関連のプログラムを使い易くまとめた形で利用できるようにしたC++言語用のゲームライブラリです。

0グッド

0クリップ

投稿2020/06/22 14:14

編集2020/06/23 07:10

環境
Windows10
DXライブラリ
visual studio 2019

例えばif (my_str2(buffer, "映画") && my_str2(buffer, "好き")) と
if (my_str2(buffer, "なぜ") && my_str2(buffer, "映画") && my_str2(buffer, "好き") && my_str2(buffer, "?") or
my_str2(buffer, "なんで") && my_str2(buffer, "映画")&& my_str2(buffer, "好き") && my_str2(buffer, "?"))の映画と好きという言葉が被ってしまうためバグが起きたり、mozicountが一気に+2されたりしてしまします。何か良い解決方法はないでしょうか。
orを || に編集しました。
編集後のコード

さらに編集後のコード

fanaさんの意見を参考に作ったコードです。※未完成です。

#include "DxLib.h" #include <string> int konnnitiwasound = 0; int situreisimasitasound = 0; char String[256]; char StringA[256]; int InputHandle; int InputHandleA; int modoru = 0; std::string input; std::string message; std::string messageA; int i; int a[1] = { 3}; int suuti = 256; int duration = 0; int konnnitiwa = 0; int sitaidou = 0; int sitaidouA = 0; int mozicount = 0; int mozicount2 = 0; int mozicount3 = 0; int gimonnlock = 0; // 自作文字列比較関数 int my_strcmp(const char* s1, const char* s2) { // 先頭から走査して差があればループ終了 for (; *s1 == *s2; s1++, s2++) { // 終了前に終端文字が見つかったら差分なし if (*s1 == '\0'&& *s2 == '\0') { return 0; } } return *s1 > * s2 ? 1 : -1; } int my_str2(const char* s1, const char* s2)//ここで入力した文字列と用意された文字列を引数として扱う。 { //s1, s2を比較する関数を使うためだけにs2の文字列のサイズが必要なので、変数aに用意した文字列の情報s2を文字列の長さを測るための関数strlenに引数として渡す。 const size_t a = strlen(s2); //無限ループする。 for (;;) { //関数memcmpの返り値が0の時は一致した時なので、==0とする。 if (memcmp(s1, s2, a) == 0) return 1;//入力した文字列にい指定された文字列が入っていた場合は1を返すように設定した。 //入力した文字列が最後の文字まで到達した場合は一致する文字列がないということなので0を返すようにした。 else if (*s1 == '\0') return 0;//入っていなかった //文字列が一致した場合でも一致する文字列がない場合でも入力した文字列の一文字分の文字コードのバイト数?が繰り上がるようにした。 else ++s1; } } int rireki = 0; int rireki2 = 0; int LEFTmark = 0; const char* str[100] = { "どんな映画が好きなんですか?","はい!大好きです!!あなたはどんな映画が好きですか? " ,"私は恋愛映画が好きです!", "人間観察が好きだからかもしれません。","申し訳ありません。わかりません。" ,"おはようございます。今日は何をなさるんですか?"};//ここで文字を直接書いてるので、この文字のバイト数が各posmozi[]に入るだけ int frame[100] = { 10,10 ,10,10,10,10};//次の一文字が出るまでのカウンタとして働いている、ここの数値を変えることで文字が一文字ずつ出るまでの間隔を設定できる。 int posmozi[100];//文字のバイト数が入る箱を表している。 int countS[100];//次の文字が出るまでのカウントするためのもの int z;//関数drawString外でも使えるように外にも定義を書いた。zの数値は関係なく、文字列が入った数列がif文により同じ変数zの時にframe[z]と同じになるまで+1されていったり、+2バイトor+1バイトされていくため、 //文字が一文字ずつ入っていく、なんでzの変数に値を入れて動かす必要がないのだ。ちなみにfor (z = 0; z < 3; ++z)で書いてしまうとキーAを押した際のif文に関係なく関数drawStringの最初のzどこかに値が入っただけで繰り返しを開始してしまうため、今回のように同じ変数zの時にフレームを利用して描画するようにした。 char c = str[z][posmozi[z]];//関数drawString外でも使えるように外にも定義を書いた。 void drawString(int z, int x, int y, int color) { c = str[z][posmozi[z]];//posmozi[z] if (countS[z] == 0 && c != '\0') posmozi[z] += IsDBCSLeadByte(c) ? 2 : 1; if (++countS[z] == frame[z]) countS[z] = 0; DrawFormatString(x, y, color, "%.*s", posmozi[z], str[z]); DrawFormatString(300, 300, (0, 0, 255), "countS[0]は%d", countS[0]); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { SetGraphMode(1500, 780, 32); // ウィンドウの大きさを指定 ChangeWindowMode(TRUE); // 全画面ではなくウインドウを使用 // DXライブラリの初期化 if (DxLib_Init() == -1) return -1; SetFontSize(42); //サイズを42に変更 // 描画先を裏にする SetDrawScreen(DX_SCREEN_BACK); // キー入力ハンドルを作る(キャンセルなし全角文字有り数値入力じゃなし) //MakeKeyInputは開発者の方が一回呼び出せば使えるように作ったのでループ内には書かない。 InputHandle = MakeKeyInput(50, FALSE, FALSE, FALSE); // 作成したキー入力ハンドルをアクティブにする SetActiveKeyInput(InputHandle); // キー入力終了待ちループ // (ProcessMessageをループごとに行う) while (ProcessMessage() == 0) { // 画面の初期化 ClearDrawScreen(); //まずは描画する部分から作る。 // 入力モードを描画 DrawKeyInputModeString(640, 480); // 入力途中の文字列を描画 DrawKeyInputString(0, 0, InputHandle);//InputHandleはint型とリファレンスに書いてあったんで //その後にif文での分岐を考える。 // 入力が終了している場合は終了 //ループ内とは言えエンターキー一回でCheckKeyInputが呼べればいい。 //エンターキーが押されていないとき?の部分。 if (CheckKeyInput(InputHandle) != 0) { // 入力された文字列を取得 char buffer[256];//★InputHandleに入ったのは文字のデータなので、文字のデータが受け取れる変数の型にする。 // 入力された文字列を取得、その文字列を数値に変換 GetKeyInputString(buffer, InputHandle);//ここでInputHandleに入力された文字列の数値をGetKeyInputStringにより文字コードに変換したものを上でchar型で定義したbufferに入れる。 input = buffer;//bufferに入った文字コードに変換したものを DrawString(0, 0, input.c_str(), GetColor(255, 255, 255)); /* 配列の要素を出力 */ //inputに入った文字のデータを数値化するために input.c_str()を定義して、下のif文に使った。 //変数inputに入る前はchar型のbufferに文字列が入るので、my_str2はchar*型を引数にとるため、char*型は文字列を定義するので、 //関数my_str2にはそのまま文字列が使えるので、その文字列が入っているbufferを直接書いた。 if (my_str2(buffer, "映画") && my_str2(buffer, "好き")) { // message = "どんな映画が好きなんですか?"; konnnitiwasound = LoadSoundMem("line-girl1-konnichiha1.mp3"); PlaySoundMem(konnnitiwasound, DX_PLAYTYPE_BACK); z = 0; ++mozicount; if (my_str2(buffer, "どんな") && my_str2(buffer, "?") || my_str2(buffer, "?")) { // message = "どんな映画が好きなんですか?"; konnnitiwasound = LoadSoundMem("line-girl1-konnichiha1.mp3"); PlaySoundMem(konnnitiwasound, DX_PLAYTYPE_BACK); z = 1; ++mozicount; gimonnlock = 1; } else if (my_str2(buffer, "なぜ") && my_str2(buffer, "?") || my_str2(buffer, "なんで") && my_str2(buffer, "?")) { // message = "どんな映画が好きなんですか?"; konnnitiwasound = LoadSoundMem("line-girl1-konnichiha1.mp3"); PlaySoundMem(konnnitiwasound, DX_PLAYTYPE_BACK); z = 3; ++mozicount; } } if (my_str2(buffer, "映画") && my_str2(buffer, "事実") || my_str2(buffer, "映画") && my_str2(buffer, "アクション")) { // message = "どんな映画が好きなんですか?"; // konnnitiwasound = LoadSoundMem("line-girl1-konnichiha1.mp3"); //PlaySoundMem(konnnitiwasound, DX_PLAYTYPE_BACK); z = 2; ++mozicount; } if (my_str2(buffer, "おはよう") ) { // message = "どんな映画が好きなんですか?"; konnnitiwasound = LoadSoundMem("line-girl1-konnichiha1.mp3"); PlaySoundMem(konnnitiwasound, DX_PLAYTYPE_BACK); z = 5; ++mozicount; } else { z = 4; ++mozicount; } //duration = 1; // 再度インプットハンドルをアクティブにする SetActiveKeyInput(InputHandle); // 入力文字列を初期化する SetKeyInputString("", InputHandle); } // DrawFormatString(100, 150, GetColor(255, 255, 0), "ProcessMessage()は%d,modoruは%d", ProcessMessage(), modoru); DrawFormatString(0, 150, GetColor(255, 255, 0), "zは%d,konnnitiwaは%d,sitaidouは%d,mozicountは%d", z, konnnitiwa, sitaidou, mozicount); DrawFormatString(0, 250, GetColor(255, 255, 0), "mozicount2は%d,input.c_str()は%d, LEFTmarkは%d", mozicount2, input.c_str(), LEFTmark); //新しい言葉の処理 //文字カウントが1の時 if (mozicount > 0 ) { drawString(z, 10, 100, GetColor(5, 255, 255)); } // 裏画面の内容を表画面に反映させる ScreenFlip(); } // 用済みのインプットハンドルを削除する DeleteKeyInput(InputHandle); // 画面の初期化 ClearDrawScreen(); // 裏画面の内容を表画面に反映させる ScreenFlip(); // キー入力待ち // WaitKey(); //ループないやループから出た後で何かしらの問題が発生したら終了する。 // DXライブラリの使用終了 DxLib_End(); // 終了 return 0; }

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

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

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

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

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

cateye

2020/06/22 14:25 編集

ソースはC++のようですが・・・・Cのタグは外しましょう。 また、“バグが起きたり”ではなく“判定の切り分けが、ちゃんと出来ていない”のでは?
Daregada

2020/06/22 14:49

if文の条件式を読んでたら「or」が出てきたので……って、もう突っ込み入っていた
KZK13

2020/06/22 16:25

ありがとうございます。 さっそく編集します。
raccy

2020/06/22 22:28

FizzBuzz問題を自分で考えて解くことができますか?やりたいことのロジックはFizzBuzz問題と一緒だということは理解できますか?
KZK13

2020/06/23 03:34

ならば、FizzBuzz問題の問題を解いてみます。うまくいけば自己解決できるかもしれませんし。
episteme

2020/06/23 05:24 編集

↑きっと人違いですよー(棒読み 「複数のユーザーIDを1人で保有する行為」は禁止事項なんだもん。
KZK13

2020/06/23 05:43

人違いですね。(素
Zuishin

2020/06/23 06:14 編集

なぜ騙せると思うのか理解に苦しむ。あまりにバカにしている。
thkana

2020/06/23 07:30

忘れちゃったんですね。
guest

回答3

0

考え方はFizzBuzz問題と同じです。

FizzBuzz問題は次のようなものです。

1から100までの数を順番に下記処理を行う。

  1. 数が3で割り切れる場合は「Fizz」と表示する。
  2. 数が5で割り切れる場合は「Buzz」と表示する。
  3. 数が3で割り切れ、かつ、5で割り切れる場合は「FizzBuzz」と表示する。
  4. 数がいずれでもない場合は、その数そのものを表示する。

質問にあった最初のコードは次のようなことをしたかったのだ(実現したい処理)と思われます。

入力された文字列について下記処理を行う。

  1. 文字列に「映画」が含まれ、かつ、「好き」が含まれている場合は、「どんな映画が好きなんですか?」と返事する。
  2. 文字列に「映画」が含まれ、かつ、「好き」が含まれ、かつ「?」が含まれている場合は、「はい!大好きです!!あなたはどんな映画が好きですか?」と返事する。
  3. 文字列に「映画」が含まれ、かつ、「事実」が含まれる場合は、「私は恋愛映画が好きです!」と返事する。
  4. 文字列に「映画」が含まれ、かつ、「アクション」が含まれる場合は、「私は恋愛映画が好きです!」と返事する。
  5. 文字列に「なぜ」が含まれ、かつ、「映画」が含まれ、かつ、「好き」が含まれ、かつ、「?」が含まれる場合は、「人間観察が好きだからかもしれません。」と返事する。
  6. 文字列に「なんで」が含まれ、かつ、「映画」が含まれ、かつ、「好き」が含まれ、かつ、「?」が含まれる場合は、「人間観察が好きだからかもしれません。」と返事する。
  7. 文字列に「おはよう」が含まれる場合は、「おはようございます。今日は何をなさるんですか?」と返事する。
  8. 文字列がいずれでもない場合は、「申し訳ありません。わかりません。」と返事する。

条件が増えただけで、FizzBuzz問題と同じ構造であることが分かりますね。つまり、FizzBuzz問題を少し複雑にしただけで、そのロジックや考え方は何も変わりません。逆に言うとFizzBuzz問題は、今やろうとしていることをもっと単純な物にした物です。FizzBuzz問題を自力で理解しながら解けるようにならない限り、想定している動作のコードを書けることはありません。

さて、いくつかヒントを与えましょう。

  1. 最初のFizzBuzz問題には、動作についての解釈に曖昧さがあります(これはわざとです)。この曖昧な部分を解決しないと、そもそも何が正しい動作なのかが判定できません。この曖昧な部分は、後に示した実現したい処理の文章にも含まれています。まずは、これを解決してください。
  2. FizzBuzz問題も実現したい処理も、単に書いてある順番に場合分けを書いていってもうまくいきません。ちゃんと考えて、条件の順番や内容を書く必要があります。
  3. FizzBuzz問題も実現したい処理も、適切な順番で条件を書いていく方法でも、条件を入れ子にして計算回数を効率よく減らす方法でも、どちらでも書けます。やり方の考え方は一緒です。

投稿2020/06/23 10:57

編集2020/06/23 11:00
raccy

総合スコア21735

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

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

KZK13

2020/06/23 11:17

そうかもしれません。
fana

2020/06/23 11:25

> FizzBuzz問題は、今やろうとしていることをもっと単純な物にした物です。 「FizzBuzz問題をもっと単純にした物」が欲しいところかもですね. (スタート地点のハードルをいきなり高めに設定してもうまくいかないかもしれない)
KZK13

2020/06/23 11:31

問題を解決するのには簡単な例題や考え方がベストですね。
guest

0

(未知のリンクを踏みたくないので)

バグが起きたり、mozicountが一気に+2されたり

という話の具体的なところはわかりませんが,
ごくごく普通に「条件を整理すれば良い」という話ではないのでしょうか?

「何かが多重に動いてしまう」みたいな話は,そもそもの条件分岐方法(フロー)自体を適切に捉えることができていないのが原因でしょう.
まずは(コーディングよりも前に),紙上なりで整理/吟味して,筋道をすっきりさせるべきです.

で,そのフローを淡々とifやらelseやらを使うコード上での表現に(半ば機械的に)置き換えていけばよいでしょう.

//--- //※こんなフローになるべきなのかどうか,実際のところは知らんけれども //--- //とりあえず "映画"と"好き" を同時に満たすかどうかを判定 if (my_str2(buffer, "映画") && my_str2(buffer, "好き")) { //"映画"と"好き"を満たしていて,さらに追加の条件も満たすかどうかを判定 if( my_str2(buffer, "?") && ( my_str2(buffer, "なぜ") || my_str2(buffer, "なんで") ) ) { //"映画"と"好き"と"?" を全て満たしていて,且つ,{"なぜ","なんで"}のうち少なくとも1つを満たす場合 ... } ... }

#上記のようifで各条件をぽちぽち追加実装していく方法というのは限界が早そうに思えますが,
まずは小さなものを思った通りに作るステップというのが必要そうに思えるので,とりあえずはifで思った通りの条件分岐を書けることを目指すと良いかと.

投稿2020/06/23 01:51

fana

総合スコア11656

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

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

fana

2020/06/23 01:56

全然関係ないけど, PSのゲームで Carnage Heart というのがあるのだけど, この手の「ifと処理フロー(+ちょっとした変数)」みたいな話に触れるのに最適な教材の1つであると勝手に思っている. 小学校で導入すべき.
KZK13

2020/06/23 03:25

いつもありがとうございます。 fanaさんの解答を正しく理解できたかわからないのですが、編集してみました。 うまく機能していない部分もありますが、帰ってきたら編集をします。
fana

2020/06/23 03:35

理解すべきはココ: > 紙上なりで整理/吟味して,筋道をすっきりさせるべき 何をどう実装すればすべてが上手くいくのか?が 具体的に/明確に ならないうちは実装は不可能.
KZK13

2020/06/23 05:46

Carnage Heart はゲームですが、プログラミングの学習材料になるとは知りませんでした。
KZK13

2020/06/23 06:26

fanaさんの意見と教本を参考に書き換えてみました。しかしif文の部分がうまく機能していないようで、 どんな映画が好きなんですか?と入力すると申し訳ありませんと表示され、mozicountの値は3となってしまいます。 何か良い解決法はないでしょうか。こちらはコードです。https://pastebin.com/LXxi6ih5
fana

2020/06/23 06:35

> (未知のリンクを踏みたくないので) という主義(?)というか,個人的なわがまま(?)なので… sorry.
episteme

2020/06/23 06:53

デバッガで155行あたりにbrake-point仕掛け、 一時停止したらstep-traceで追っかければわかるんでないの?
KZK13

2020/06/23 07:10

そうとは知らずに載せてしまいすいませんでした。 なので、質問の方にコードをそのまま載せました。
guest

0

ベストアンサー

if ( A ) { ... }
if ( B ) { ... }

if ( A ) { ... }
else if ( B ) { ... }

とすれば A, B 両方の条件が成立することはなくなります。

※ お願いだから教本読んで。

[追記] "両方の条件が成立することはなくなります"は正確じゃないですね。
A が成立すると、if ( B ) { ... } が"評価されなくなる(skipされる)"というべきかな。

投稿2020/06/22 20:25

編集2020/06/23 01:50
episteme

総合スコア16614

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

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

KZK13

2020/06/23 05:48 編集

ありがとうございます。 教本は読んでいます。が、言われなければ気がつきませんでした。
episteme

2020/06/23 06:03

言われなければ気づかないなら読んでないのと同じ。身に付いてないんだから。
KZK13

2020/06/23 07:07

すいません。 epistemeさんの方法で書いてみたのですが、正しいでしょうか? こちらがコードです。 https://pastebin.com/52Ka0SLj
episteme

2020/06/23 07:10

動作確認を僕にさせるん?
KZK13

2020/06/23 07:17

言い方が悪かったです。 epistemeさんの方法で正しく動くと思うのですが、私の出来が悪いばかりに正しく動かないので、何が間違っているのか指摘がほしいです。
episteme

2020/06/23 07:27

”おはよう"を含まない入力であるかぎり、すべて z = 4 ですね。 あなたの書いたとおりです。
KZK13

2020/06/23 09:59

epistemeさんのやり方で解いたプログラムです。 https://pastebin.com/9Euuc8Qr どうもありがとうございます。 epistemeさんの方が解答の投稿時間が速かったのでこちらをベストアンサーとさせていただきます。
episteme

2020/06/23 10:07 編集

"映画が好きなあなたにおはよう" , "映画が好きという事実" に対し、所望の動作になりますか?
KZK13

2020/06/23 10:08

そこまでは。 ですが、そんなコメントを打つ人はたぶんいないと思うので。 "映画が好きなあなたにおはよう" に対し、おはようと返事するのである意味いいのではないかと思います。
episteme

2020/06/23 10:13 編集

それが所望の動作であるなら問題ない。 仕様が与えられず、あなたの頭の中にある限り第三者は検証できんて。 だから「正しく動かないので、何が間違っているのか指摘がほしいです。 」はナンセンス。 正しい動作は第三者にはわからんのだから。
KZK13

2020/06/23 10:17

はい。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問