シューティングゲームのサンプルを勉強しています。
下記のこの部分のコードが二つあります。
memset(buf,0,sizeof(buf));
気になっています。
なぜ二つあるのかを意味を知りたいです。
よろしくお願いします。
コードは以下に記述します。
CONTROL::CONTROL()
{
player = new PLAYER;
back = new BACK;
FILE *fp;
ENEMYDATA data[ENEMY_NUM];
char buf[100];
int c;
int col=1;
int row=0;
memset(buf,0,sizeof(buf));
fp = fopen("enemydata1.csv","r");
while(fgetc(fp)!='\n');
while(1){
while(1){
c=fgetc(fp);
if(c==EOF)
goto out;
if(c!=','&& c!='\n')
strcat(buf,(const char*)&c);
else
break;
}
switch(col){
case 1: data[row].type=atoi(buf); break;
case 2: data[row].stype=atoi(buf); break;
case 3: data[row].m_pattern=atoi(buf); break;
case 4: data[row].s_pattern=atoi(buf); break;
case 5: data[row].in_time=atoi(buf); break;
case 6: data[row].stop_time=atoi(buf); break;
case 7: data[row].shot_time=atoi(buf); break;
case 8: data[row].out_time=atoi(buf); break;
case 9: data[row].x=atoi(buf); break;
case 10: data[row].y=atoi(buf); break;
case 11: data[row].speed=atoi(buf); break;
case 12: data[row].hp=atoi(buf); break;
}
memset(buf,0,sizeof(buf));
++col;
if(c=='\n'){
col=1;
++row;
}
}
out:
for(int i=0;i<ENEMY_NUM;++i){
enemy[i]=new ENEMY(
data[i].type,
data[i].stype,
data[i].m_pattern,
data[i].s_pattern,
data[i].in_time,
data[i].stop_time,
data[i].shot_time,
data[i].out_time,
data[i].x,
data[i].y,
data[i].speed,
data[i].hp,
data[i].item);
}
}
No.5
- 回答日時:
strcat については前の
http://oshiete.goo.ne.jp/qa/8460028.html
で指摘したんだけどねぇ>#3.
memset 自体は, 既に回答があるようにループのどこかに入れれば 1個で済むはず.
しかし... 前のときにはあえて書かなかったんだけど, ENEMY のコンストラクタがすっごくバカに見える.
No.4
- 回答日時:
参加するつもりはありませんので書き逃げになりますかねぇ…
csv読む込むのにfgetc()で読むよりは、1行読み込んで処理した方が…というは前回も指摘したところですが。
読もうとしているcsvにShift-JISで日本語とか書いてあったときに誤動作する可能性があります。
fgetc()で読むならすでに指摘されているようにstrcat()でつなげるのは正しくないです。
どこまで読み込んだのか…のカウンタでも持って
buf[cnt++] = (char)c;
buf[cnt] = '\0';
として追加していくべきでしょう。
# strcatする度にbufの先頭から'\0'を探す処理が走ってCPUが仕事シテマスをアッピールとか?
memset()が2つあるのはすでに回答あるとおりですね。
実施する場所をちゃんと厳選すれば1つで充分です。
というか「strcat()で繋げる」ならbuf[0] = '\0'でもいいでしょう。
# デバッガでメモリの状態見るなら向きませんけどね。
お世話になります。
memset(buf,0,sizeof(buf));
の部分は一つでも出来ることがわかってよかったです。
ありがとうございました。
失礼します。
No.3
- 回答日時:
No.2です。
書き漏らしました。このソースコードには潜在的なバグが
あると思います。
strcat(buf,(const char*)&c);
ですが、strcatの第2パラメータは0終端文字列を指定しなければ
ならないのに、int型のcのアドレスを指定しています。
リトルエンディアンのintel系CPUで動作させるなら
これでもたまたまうまく動作すると思いますが、
bufクリア箇所といい、あまり勉強のお手本には
しない方がいい下手なコーディングだと思います。
なぜリトルエンディアンのintel系CPUなら動作するのか、
ビッグエンディアンだとどうなるのか調べて、
反面教師として利用すればいいのかもしれません。
No.2ベストアンサー
- 回答日時:
このソースコードは、fgetc(fp)で読み込んだ文字を1文字ずつ
bufにstrcatで追記し、カンマで区切られた単語を読み込む
処理になっています。
例えば「1234,5678, ....」という入力があった場合、
bufに「1234」まで文字を追記した後、「,」の出現を検出して
bufに入っている値(1234)をdata[row].typeに取り出します。
それを取り出した後
memset(buf,0,sizeof(buf));
でbufの内容をクリアしてから、またループの先頭に戻って
次の単語の処理に入りますが、もしこのクリアがないと
次の入力を読み込んだ時、現在bufに入っている「1234」に
追記して「12345678」という単語を作ってしまいます。
このため、この後半のbufクリアが必要です。bufをクリアして、
また先頭から追記し「5678」として読み込む必要があります。
ただ、こういうふうにループに入る前にクリアして、
ループの先頭に戻る前にクリアするような2度手間するよりも、
1個目のwhile(1)の直後にbufをクリアすればクリア処理は
1箇所で済む話で、その方がすっきりしていると思います。
bufを初期化するポイントが整理されていない印象です。
No.1
- 回答日時:
ざっと見ただけできちんと確認してないけど
bufの内容としては CSV ファイルの1行分のデータを格納・処理のループをしているようです
他の行のデータ残骸が残らないようにクリアしているだけではないかと思われます
残骸が残っても支障がないように作ってあるならクリア必須というわけではありませんが
デバッグ等行う場合にはクリアしていた方がわかりやすい(確認しやすい)
といった事はあるかもしれません
貴重な意見ありがとうございます。
ここの部分が気になったのですが
デバッグ等行う場合にはクリアしていた方がわかりやすい(確認しやすい)
他の場合はクリアしなくてもいいと言うことですか。
出来ればこの部分の事を教えて
もらえるとありがたいです。
失礼します。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(プログラミング・Web制作) Python - Excel で Webからデータを連続取得したいのですが エラーが出ます 1 2023/07/06 20:08
- その他(プログラミング・Web制作) pythonのこのエラーがわかりません 3 2022/11/16 14:54
- Excel(エクセル) 2つのVBAを一緒にしたら機能しなくなりました(エクセル) 7 2022/06/02 12:41
- C言語・C++・C# #include <stdio.h>int main(void) { int buf[100] = 6 2022/11/01 22:45
- PHP PHPSpreadsheetによる書き出し時のページネーション方法について 1 2023/03/20 10:35
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、以下のプログラムをどう直せ 1 2022/07/09 22:16
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
- JavaScript jsで、switch文で書かれた分をif文にできませんか。 1 2022/07/28 15:10
- Visual Basic(VBA) フォルダの場所を可変にしたいです(マクロ) 4 2023/05/11 10:00
- Visual Basic(VBA) 複数シート一括作成後に、特定範囲の数式は値で貼り付けしたい 3 2022/10/07 11:18
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ポインター引数の関数でコンパ...
-
stable diffusionのエラー
-
pythonでDBのカラム名で取得し...
-
matlabのソースコードをpython...
-
エクセルVBA:日付データの変換...
-
C言語の構造体にてバブルソート...
-
データの値の近いものをグルー...
-
printfの%eで指数部分の桁数を...
-
テキストファイルの結合について
-
パイソン、データーサイエンス...
-
POSTで配列のデータを渡す方法は?
-
基本クラスのポインタから、特...
-
オセロゲーム 2次元配列で困...
-
花の名前を教えて下さい。
-
途中経過も表示するプログラム
-
python 気象データの取得
-
UTF-8で5~6バイトになる文字コ...
-
COBOLのCOMP形式について
-
ビットスワップとバイトスワッ...
-
エクセルシート名の制限を変更...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ポインター引数の関数でコンパ...
-
stable diffusionのエラー
-
printfの%eで指数部分の桁数を...
-
エクセルVBA:日付データの変換...
-
int型(2バイト)データの分割
-
c言語の多次元配列で1から100ま...
-
C#でのswitch文
-
【Excel VBA】10進数を2進数に...
-
途中経過も表示するプログラム
-
CreateProcessでの環境変数の設...
-
pythonでDBのカラム名で取得し...
-
C言語についてです! 同じ年の...
-
linuxのシェルでファイル名に先...
-
c言語 配列から数字だけをint型...
-
c言語での wavファイルの編集(...
-
matlabのソースコードをpython...
-
ビットデータのチェック方法
-
10個の実数に対する降順ソート...
-
python 気象データの取得
-
C言語の構造体にてバブルソート...
おすすめ情報