電子書籍の厳選無料作品が豊富!

下にあるようなプログラムを組んだのですが、
警告 W8075 test4.c 47: 問題のあるポインタの変換(関数 map_data )
といった警告が出てしまい、どのように対処したらいいのかわかりません。
警告内容からmap_data()関数がおかしいと思いますが、何がおかしいのか指摘していただけないでしょうか。
/*読み込むマップデータテキストの例10×10
0011111111
1000111111
1000011111
1100011111
1111011111
1111011111
1111000111
1111000111
1111000111
1111001111
*/

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#define MAXBUFF 256

void disp(char dt[][10]);//コントロール+表示
void map_data(char map_name[]);//マップデータ読み込み関数
int PC_ymove=0,PC_xmove=0;//キャラクターの初期値

int main(void)
{

//マップデータ読み込み関数
map_data("dun1.txt");

return 0;
}

//マップデータ読み込み関数
void map_data(char map_name[])
{
FILE *fp;
char str[MAXBUFF];
fp=fopen(map_name,"r");
if(NULL==fp){
fprintf(stderr,"ファイルのオープン失敗\n");
exit(0);
}
while(NULL!=fgets(str,MAXBUFF,fp)){
disp(str);
}
fclose(fp);
}

//読み込んだマップデータに床と壁とキャラを表示させる
void disp(char dt[][10])
{

int key;
int y,x;
system("cls");
for(y=0;y<10;y++){
for(x=0;x<10;x++){
if((y==PC_ymove)&&(x==PC_xmove)){
printf("@");
}
else if(dt[y][x]==0){
printf("+");
}
else{
printf("#");
}

while(1){ //キャラクターの操作部分
if(kbhit()){
key=getch();
switch(key){
case 'w'://Key↑ 119
if((PC_ymove>0)&&(dt[PC_ymove-1][PC_xmove]!=1))
PC_ymove--;
break;
case 's'://Key↓ 115
if((PC_ymove<9)&&(dt[PC_ymove+1][PC_xmove]!=1))
PC_ymove++;
break;
case 'a'://Key← 97
if((PC_xmove>0)&&(dt[PC_ymove][PC_xmove-1]!=1))
PC_xmove--;
break;
case 'd'://Key→ 100
if((PC_xmove<9)&&(dt[PC_ymove][PC_xmove+1]!=1))
PC_xmove++;
break;
default:
//printf("想定外のキー入力がありました。\n");
break;
}
}
}
}
}
printf("\n");
}

A 回答 (7件)

>@だけしか表示されないし動かないので



そりゃそうです。

@だけしか表示されないのは、x=0,y=0で@を表示したあと
> while(1){ //キャラクターの操作部分
の無限ループに入ってしまい、x,yのforループが回ってないから。

キーを押しても動かないのは
> while(1){ //キャラクターの操作部分
のループの中で何も表示せず、ひたすらキー入力とPC_xmove, PC_ymoveの変更しかしていないから。

プログラムは書かれた通りに動いています。
配列云々以前に、プログラムの構成自体がおかしいのです。

また、
>else if(dt[y][x]==0){
>if((PC_ymove>0)&&(dt[PC_ymove-1][PC_xmove]!=1))
>if((PC_ymove<9)&&(dt[PC_ymove+1][PC_xmove]!=1))
>if((PC_xmove>0)&&(dt[PC_ymove][PC_xmove-1]!=1))
>if((PC_xmove<9)&&(dt[PC_ymove][PC_xmove+1]!=1))
ここでdt[][]と0/1を比較していますが、dtの中身はmain関数のstrの中身、つまり、テキストファイルから読み出した文字です。
文字'0'と数値0、文字'1'と数値1、とは一緒ではありません。


一つの解として。
・disp( char dt[][10] )という宣言に合うように、マップデータの入った二次元配列を用意する。
→ char map[10][10];とでもしておく。

・map_data関数で取り込んだ文字'0','1'を数値0,1に変換してmapに入れる。
そのために、宣言をチョット変える

・disp関数はマップと自キャラの表示だけにする。
むやみに一つの関数でなにもかもやろうとしない。今回は表示と移動を同時にやろうとして失敗している。
→while(1)のループをばっさりと削除
→printf("\n")の場所もおかしい。これではマップの1行毎に改行されず、全部表示されたあとに改行される。

・移動は別関数にする。moveとでも名付ける。
↑で削ったwhile(1)ループを使うけど、キー入力があったらループを抜けるように工夫する

・main関数は次の通り
1)map_dataでファイルを読み込み
2)表示
3)移動
4) 2)へ戻る
    • good
    • 0

つづき)


で、変更したらこうなりました。
エラー処理とか終了処理とか system("cls")とか、まだまだ不十分だけど、とりあえず動作は確認。

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#define MAXBUFF 256

void disp(char dt[][10]);//コントロール+表示
void map_data(char dt[][10], char map_name[]);//マップデータ読み込み関数
void move(char dt[][10]) ;//キャラクターの操作部分
int PC_ymove=0,PC_xmove=0;//キャラクターの初期値

int main(void)
{
char map[10][10]; //マップデータ

//マップデータ読み込み関数
map_data(map,"dun1.txt");

//メインループ
while (1) {
disp(map); //表示する
move(map);//移動する
}

return 0;
}

//マップデータ読み込み関数
void map_data(char dt[][10], char map_name[])
{
FILE *fp;
int x,y = 0 ;
char str[MAXBUFF];
fp=fopen(map_name,"r");
if (NULL==fp) {
fprintf(stderr,"ファイルのオープン失敗\n");
exit(0);
}
while (NULL!=fgets(str,MAXBUFF,fp)) {
for ( x = 0 ; x < 10 ; ++ x ) {
if ( str[x] == '1' ) {
dt[y][x] = 1 ;
} else {
dt[y][x] = 0 ;
}
}
y ++ ;
}
fclose(fp);
}

//読み込んだマップデータに床と壁とキャラを表示させる
void disp(char dt[][10])
{
int y,x;
system("cls");
for (y=0; y<10; y++) {
for (x=0; x<10; x++) {
if ((y==PC_ymove)&&(x==PC_xmove)) {
printf("@");
}
else if (dt[y][x]==0) {
printf("+");
}
else {
printf("#");
}
}

printf("\n");
}
}
//キャラクターの操作部分
void move(char dt[][10])
{
int key;
while ( ! kbhits()) {
//キー入力待ち
}

key=getch();
switch (key) {
case 'w'://Key↑ 119
if ((PC_ymove>0)&&(dt[PC_ymove-1][PC_xmove]!=1))
PC_ymove--;
break;
case 's'://Key↓ 115
if ((PC_ymove<9)&&(dt[PC_ymove+1][PC_xmove]!=1))
PC_ymove++;
break;
case 'a'://Key← 97
if ((PC_xmove>0)&&(dt[PC_ymove][PC_xmove-1]!=1))
PC_xmove--;
break;
case 'd'://Key→ 100
if ((PC_xmove<9)&&(dt[PC_ymove][PC_xmove+1]!=1))
PC_xmove++;
break;
default:
//printf("想定外のキー入力がありました。\n");
break;

}
}
    • good
    • 0
この回答へのお礼

ありがとうございます。
まだまだ未熟者でした。
関数を覚えると、ついついmain関数の中を少しでもスッキリさせたくなって、余計に分からなくしていました。

あと、void map_data(char dt[][10], char map_name[])でchar dt[][10]とchar map_name[]の二つを引数に取るアイデアっていうか、そういったのが浮かんでこなかったです。
もっとがんばりますので、これからもよろしくお願いします。

お礼日時:2010/01/29 08:20

 


>disp(str); -> disp((char (*)[10])str);
 これだけじゃ、だめだ。
 

int c, i;
...
for(i = 0; i < 256 && (c = fgetc(fp)) != EOF; ){
if(c != '\n') str[i] = c, ++ i;
}
disp((char (*)[10])str);
...

他は見てないけど、とりあえずこんな感じにしてみる。
 

 
    • good
    • 0
この回答へのお礼

1文字ずつ読み込ませて見るやり方も試してみましたが、なんかうまくいきません。
で、こっちもやって見ましたがだめでした。
while ((c = fgetc(fp)) != EOF){
   str[i] = (char)c;
   i++;
@だけしか表示されないし動かないので、他に何か配列をいじれる別の方法を模索してみます。
受け取り側の、disp関数をもう少しいじってみたいと思います。

お礼日時:2010/01/28 21:19

#2追加(本題からはそれた内容です)


キャストの具体的な方法が分からなかったので書かなかったんですが
キャストで対応するにしても読み込みバッファを変更するにしても
このプログラムでは質問者さんが期待してるととうりには動かないでしょう
そもそも disp 関数の処理の中身を考えると関数呼んでる位置が悪いから
(そこらへんは御自分でお考えください)
    • good
    • 0
この回答へのお礼

がんばってみましたが頭がパニックってしまい、何がなにやらわからなくなってしまいました。
普通に画面へ表示させるだけなら出来るのですが、読み込んだ配列データを他の関数にうまく渡せません。
もう少し悪戦苦闘はしてみます。

お礼日時:2010/01/28 21:06

 


 disp(str); -> disp((char (*)[10])str);
    • good
    • 0
この回答へのお礼

質問に答えていただきありがとございます。
書かれている事をやってみましたが、残念ながらうまく表示されませんでした。
警告は出なくなりましたが@だけ表示され、キーコマンドは受け付けてくれません。
もう少し配列と関数について調べてみます。

お礼日時:2010/01/28 21:02

>警告内容からmap_data()関数がおかしいと思いますが、何がおかしいのか指摘していただけないでしょうか。


多分違う

おかしいのは disp 関数で
プロトタイプで void disp(char dt[][10]) にしてるのに
実際の呼び出しで disp(str); ってしてるからだと思いますが
型合わせてください
    • good
    • 0
この回答へのお礼

質問に答えていただきありがとございます。
書かれている事をやってみましたが、残念ながらうまく表示されませんでした。
おっしゃる通りで、disp関数側で二次元配列として受け取ってもらえないです。
もう少し配列と関数について調べてみます。

お礼日時:2010/01/28 21:00

int main(void)


{
//マップデータ読み込み関数
map_data("dun1.txt");
return 0;
}
//マップデータ読み込み関数
void map_data(char map_name[])


void map_data(char *map_name)
後、プロトタイプ宣言の修正。
で、どうでしょうか。
    • good
    • 0
この回答へのお礼

質問に答えていただきありがとございます。
書かれている事をやってみましたが、残念ながらうまく表示されませんでした。
もう少し配列と関数について調べてみます。

お礼日時:2010/01/28 20:58

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!