始めたばかりの初心者で分からないことだらけですがよろしくお願いいたします
使用言語:C++
VitualStdio2017を使っています
Dxライブラリでゲーム制作しようとしています
ところで、http://dixq.net/g/50.html
ここの資料を参考にして一文字ずつ文章を表示しようとしたのですが、これを実行するとiの値が56くらいまで行ったところでGameProg.exeは動作を終了しましたと出ているようなのです
私は3行に分けて文字列を表示したかったのですが、エラーが出て困っています
なぜエラーが出るのかを必死に考えたのですが万策尽きた感じです
ただ一つ分かったことは
//////////////////////////////////////////////////////////////////////////////////////////////////の間でエラーが出てることです
もしわかる方がいましたら教えてくださいm(_ _)m
#pragma warning(disable:4996)
#include"DxLib.h"
#include"Upgradekey.h"//これは各フレームごとのキーの入力状態を取得し、int型の要素数256の配列、Keyに格納するUpgradeKey()を宣言したヘッダーです
extern int Key[256];//ほかのファイルで定義しています
int i = 0,ch_i0 = 0,ch_i1 = 0,ch_i2 = 0, counter = 0, White;
char disp0[72] = "", disp1[72] = "", disp2[72] = "";
char ch0[5][72] = {
{"プログラムを習得するには、実際に自分で書いてみることが大事" },
{"参考書を読むことも重要だが、数学のように演習を通して、"},
{"体に身につけるようにしよう。"},
{"きっと、よりはっきりと、関数の使い方、"},
{"プログラムの書き方がわかるだろう。"}
};
char ch1[5][72] = {
{ "プログラムを習得するには、実際に自分で書いてみることが大事" },
{ "参考書を読むことも重要だが、数学のように演習を通して、" },
{ "体に身につけるようにしよう。" },
{ "きっと、よりはっきりと、関数の使い方、" },
{ "プログラムの書き方がわかるだろう。" }
};
char ch2[5][72] = {
{ "プログラムを習得するには、実際に自分で書いてみることが大事" },
{ "参考書を読むことも重要だが、数学のように演習を通して、" },
{ "体に身につけるようにしよう。" },
{ "きっと、よりはっきりと、関数の使い方、" },
{ "プログラムの書き方がわかるだろう。" }
};
void con0(){
White = GetColor(255, 255, 255);
while (!ScreenFlip() && !ProcessMessage() && !ClearDrawScreen() && !Upgradekey()) {
if (Key[KEY_INPUT_RETURN] == 1) { // 前回押されてなくて、今回押されていたら
i = 0; // iを初期値に戻し
ch_i0++; // 表示する配列を1つずらす
ch_i1++; // 表示する配列を1つずらす
ch_i2++; // 表示する配列を1つずらす
}
// 配列の終端-2以下で、今回コピーするiまでの配列要素のi番目が\0じゃなくカウンターが5の倍数なら
if (i <= 72 - 2 && ch0[ch_i0] != '\0' && counter % 5 == 0) {
i += 2; // 全角文字なので配列要素2つずつカウントアップ
strncpy(disp0, ch0[ch_i0], i);// iバイトまでの配列要素をdisp配列にコピー
disp0 = '\0'; // 終端記号を代入
if (ch0[ch_i0] == '\0') {
i = 72;
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
if (i >= 72 && i <= 144 - 2 && ch1[ch_i1] != '\0' && counter % 5 == 0) {
i += 2; // 全角文字なので配列要素2つずつカウントアップ
strncpy(disp1, ch1[ch_i1], i - 72);// iバイトまでの配列要素をdisp配列にコピー
disp1 = '\0'; // 終端記号を代入
if (ch1[ch_i1] == '\0') {
i = 144;
}
}
if (i >= 144 && i <= 214 && ch2[ch_i2] != '\0' && counter % 5 == 0) {
i += 2; // 全角文字なので配列要素2つずつカウントアップ
strncpy(disp2, ch2[ch_i2], i - 144);// iバイトまでの配列要素をdisp配列にコピー
disp2 = '\0'; // 終端記号を代入
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
//3行に文章を表示したい
DrawFormatString(50, 350, White, "%s", disp0);//disp配列の文字データを表示
DrawFormatString(50, 395, White, "%s", disp1);//disp配列の文字データを表示
DrawFormatString(50, 440, White, "%s", disp2);//disp配列の文字データを表示
if (i >= 144) {
if (ch2[ch_i2] == '\0') {
ch_i0++;
ch_i1++;
ch_i2++;
break;
}
}
counter++;
ScreenFlip();
}
}
ADV風文字表示についてのエラー
Re: ADV風文字表示についてのエラー
ソースコードを提示する際は、BBCodeが有効な(無効にしない)状態で、
BBCodeのcodeタグの開始タグと終了タグの組(開始タグが先)で囲んでいただけると、
見やすくてありがたいです。
disp1やdisp2は72要素しかないのに、if文の条件よりiは必ず72以上(144以上ならば72以上)なので、
という行で必ず範囲外への書き込みが発生し、未定義動作になります。
添字として使うために何かを引くのを忘れていないですか?
BBCodeのcodeタグの開始タグと終了タグの組(開始タグが先)で囲んでいただけると、
見やすくてありがたいです。
disp1やdisp2は72要素しかないのに、if文の条件よりiは必ず72以上(144以上ならば72以上)なので、
ユーマ さんが書きました:disp1 = '\0'; // 終端記号を代入
ユーマ さんが書きました:disp2 = '\0'; // 終端記号を代入
という行で必ず範囲外への書き込みが発生し、未定義動作になります。
添字として使うために何かを引くのを忘れていないですか?
オフトピック
コード
を追加してみましたが、通常のエントリポイントであるmain関数やWinMain関数が無く、実行できませんでした。
しかし、という警告が出力され、範囲外へのアクセスがあることはわかりました。
► スポイラーを表示
しかし、
main.cpp:1:0: warning: ignoring #pragma warning [-Wunknown-pragmas]
#pragma warning(disable:4996)
^
main.cpp: In function 'void con0()':
main.cpp:59:11: warning: array subscript is above array bounds [-Warray-bounds]
disp1[i] = '\0'; // 終端記号を代入
^
main.cpp:68:11: warning: array subscript is above array bounds [-Warray-bounds]
disp2[i] = '\0'; // 終端記号を代入
^
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: ADV風文字表示についてのエラー
今日は外せぬ用事があり、返信が遅れてしまい申し訳ありません
また、分かりにくい書き方ですみません。
次から気を付けます(|||´Д`)
内容についてですが、おっしゃっている意味はよく分かりました。修正したところきちんと動かせました!
本当に感謝です( T∀T)
これからも質問させていただくことがあるかと思いますが、その時はまた宜しくお願いします。
また、分かりにくい書き方ですみません。
次から気を付けます(|||´Д`)
内容についてですが、おっしゃっている意味はよく分かりました。修正したところきちんと動かせました!
本当に感謝です( T∀T)
これからも質問させていただくことがあるかと思いますが、その時はまた宜しくお願いします。