環境
visul studio 2019
DXライブラリ
Cで書いたこのプログラムで何がいけないのか全く分からくて積んでいます。
デバッグを書けても正常にファイルを読み込んでいるし、文字での比較も問題なくできているので何が原因かさっぱりです。
どうか何がいけないのか助言を頂けないでしょうか。
ちなみに、低評価を押すのはいいんですけど、その理由も教えてもらえるとありがたいです。今後の質問の仕方の改善のために。
問題:da.txtに「映画」を含んだ文章を保存し、「映画」と入力すると「映画」という文字を含んだ文章を表示するようにしたいです。ですが、「映画」と入力しても最後の行の文章が表示されるだけで意図した文章が表示されません。
さらに短くしたプログラムです。
#pragma warning(disable: 4996) #include "DxLib.h" #include <string> char String[256]; int InputHandle; int InputHandleA; int modoru = 0; int mozicount = 0; int gimonnlock = 0; int gimon = 0; int my_str2(const char* s1, const char* s2)//s1がs2を含んでいたら1を返す { //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; } } const char* str[100] = { "はい!" };//ここで文字を直接書いてるので、この文字のバイト数が各posmozi[]に入るだけ int frame[100] = { 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 memory = 0; char buffer[256];//★InputHandleに入ったのは文字のデータなので、文字のデータが受け取れる変数の型にする。 char buffer2[256]; char input[256]; char* p; FILE* outputfile; // 出力ストリーム int hyouzi = 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(150, FALSE, FALSE, FALSE); //これで総計150バイトの文字データを保持できる。 // 作成したキー入力ハンドルをアクティブにする SetActiveKeyInput(InputHandle); // キー入力終了待ちループ // (ProcessMessageをループごとに行う) while (ProcessMessage() == 0) { // 画面の初期化 ClearDrawScreen(); //まずは描画する部分から作る。 // 入力モードを描画 DrawKeyInputModeString(640, 480); // 入力途中の文字列を描画 DrawKeyInputString(0, 0, InputHandle);//InputHandleはint型とリファレンスに書いてあったんで //その後にif文での分岐を考える。 // 入力が終了している場合は終了 //ループ内とは言えエンターキー一回でCheckKeyInputが呼べればいい。 //エンターキーが押された時の部分。 if (CheckKeyInput(InputHandle) != 0) { hyouzi = 0; gimon = 0; ++mozicount; // 入力された文字列を取得、その文字列を数値に変換 GetKeyInputString(buffer, InputHandle);//ここでInputHandleに入力された文字列の数値をGetKeyInputStringにより文字コードに変換したものを上でchar型で定義したbufferに入れる。 //覚えてという言葉以外の場合はメモを読み込む込んでループに入るようにした。 if (memory == 0) { outputfile = fopen("da.txt", "r"); // ファイルを読み込み用にオープン(開く) if (outputfile == NULL) { // オープンに失敗した場合 printf("cannot open\n"); // エラーメッセージを出して exit(1); // 異常終了 } //fgetsがNULLになるまで繰り返す //fgets(str,256,lf)!=NULL //と同じです。このように短縮することも可能 //★bufferには文字入力の文字列を入れたので、ここにはメモからの文字列は入れられない。なので新しくbuffer2を作る。 while ((p = fgets(buffer2, 256, outputfile)) != NULL)//メモに書いた文字列をbuffer2の中に入れる。 { // 文字の入力の入るバッファと、メモからの文字が入るバッファ2とで一致する文字が出てきた場合 if (my_str2(buffer, buffer2) == 0) { hyouzi = 1; break; } // 文字の入力の入るバッファと、メモからの文字が入るバッファ2とで一致しない文字が出てきた場合 if (hyouzi == 0) { if (strcmp(buffer, buffer2) != NULL) { gimon = 1; } } } fclose(outputfile); // ファイルをクローズ(閉じる) } // 再度インプットハンドルをアクティブにする SetActiveKeyInput(InputHandle); // 入力文字列を初期化する SetKeyInputString("", InputHandle); } DrawFormatString(100, 300, GetColor(255, 255, 0), "bufferは%s,buffer2は%s", buffer, buffer2); DrawFormatString(100, 400, GetColor(5, 105, 0), "gimonは%d,hyouziは%d", gimon, hyouzi); //文字カウントが1の時 if (mozicount > 0) { drawString(z, 10, 100, GetColor(5, 255, 255)); } if (p != NULL or hyouzi == 1) { DrawFormatString(100, 500, GetColor(5, 105, 19), " buffer2は%s", buffer2); } if (hyouzi == 0 && gimon == 1) { DrawFormatString(100, 600, GetColor(5, 105, 0), "申し訳ありません%sとは何ですか?", buffer); } // 裏画面の内容を表画面に反映させる ScreenFlip(); } // 用済みのインプットハンドルを削除する DeleteKeyInput(InputHandle); // 画面の初期化 ClearDrawScreen(); // 裏画面の内容を表画面に反映させる ScreenFlip(); //ループないやループから出た後で何かしらの問題が発生したら終了する。 // DXライブラリの使用終了 DxLib_End(); // 終了 return 0; }
回答3件
あなたの回答
tips
プレビュー