![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?8acaa2e)
下にあるようなプログラムを組んだのですが、
警告 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");
}
No.6ベストアンサー
- 回答日時:
>@だけしか表示されないし動かないので
そりゃそうです。
@だけしか表示されないのは、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)へ戻る
No.7
- 回答日時:
つづき)
で、変更したらこうなりました。
エラー処理とか終了処理とか 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;
}
}
ありがとうございます。
まだまだ未熟者でした。
関数を覚えると、ついついmain関数の中を少しでもスッキリさせたくなって、余計に分からなくしていました。
あと、void map_data(char dt[][10], char map_name[])でchar dt[][10]とchar map_name[]の二つを引数に取るアイデアっていうか、そういったのが浮かんでこなかったです。
もっとがんばりますので、これからもよろしくお願いします。
No.5
- 回答日時:
>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);
...
他は見てないけど、とりあえずこんな感じにしてみる。
1文字ずつ読み込ませて見るやり方も試してみましたが、なんかうまくいきません。
で、こっちもやって見ましたがだめでした。
while ((c = fgetc(fp)) != EOF){
str[i] = (char)c;
i++;
@だけしか表示されないし動かないので、他に何か配列をいじれる別の方法を模索してみます。
受け取り側の、disp関数をもう少しいじってみたいと思います。
No.4
- 回答日時:
#2追加(本題からはそれた内容です)
キャストの具体的な方法が分からなかったので書かなかったんですが
キャストで対応するにしても読み込みバッファを変更するにしても
このプログラムでは質問者さんが期待してるととうりには動かないでしょう
そもそも disp 関数の処理の中身を考えると関数呼んでる位置が悪いから
(そこらへんは御自分でお考えください)
がんばってみましたが頭がパニックってしまい、何がなにやらわからなくなってしまいました。
普通に画面へ表示させるだけなら出来るのですが、読み込んだ配列データを他の関数にうまく渡せません。
もう少し悪戦苦闘はしてみます。
No.2
- 回答日時:
>警告内容からmap_data()関数がおかしいと思いますが、何がおかしいのか指摘していただけないでしょうか。
多分違う
おかしいのは disp 関数で
プロトタイプで void disp(char dt[][10]) にしてるのに
実際の呼び出しで disp(str); ってしてるからだと思いますが
型合わせてください
質問に答えていただきありがとございます。
書かれている事をやってみましたが、残念ながらうまく表示されませんでした。
おっしゃる通りで、disp関数側で二次元配列として受け取ってもらえないです。
もう少し配列と関数について調べてみます。
No.1
- 回答日時:
int main(void)
{
//マップデータ読み込み関数
map_data("dun1.txt");
return 0;
}
//マップデータ読み込み関数
void map_data(char map_name[])
↓
void map_data(char *map_name)
後、プロトタイプ宣言の修正。
で、どうでしょうか。
質問に答えていただきありがとございます。
書かれている事をやってみましたが、残念ながらうまく表示されませんでした。
もう少し配列と関数について調べてみます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Enterキーを押されたら次の処理...
-
空白を含んだ文字列がうまく格...
-
C言語で複数列のデータを1列の...
-
printf による16進表示について
-
#defineが使用するメモリ領域に...
-
プログラミングの授業の課題です
-
フレーム画像の連続保存について
-
配列から構造体へデータコピー
-
C言語のシリアル通信について
-
Ç言語でファイルサイズを変更す...
-
char型2つを結合し、short型に...
-
エラーについて質問です。
-
終了条件Ctrl+zについて,結果表...
-
C メモリの解放について
-
C言語のプログラムで、途中で止...
-
C++で指定文字列のカウント方法...
-
c言語
-
#define _CRT_SECURE_NO_WARNIN...
-
信頼区間の1.96や1.65ってどこ...
-
2÷3などの余りについて
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Enterキーを押されたら次の処理...
-
C言語で複数列のデータを1列の...
-
printf による16進表示について
-
C言語のプログラムで、途中で止...
-
矢印キーを押下してコンソール...
-
char型2つを結合し、short型に...
-
#defineが使用するメモリ領域に...
-
【C言語】全角文字の配列を、全...
-
終了条件Ctrl+zについて,結果表...
-
空白を含んだ文字列がうまく格...
-
プログラミングの授業の課題です
-
リストの作成と出力(C言語)
-
構造体メンバの初期化
-
c言語で文書を読み込み、単語の...
-
エラーについて質問です。
-
reallocでエラー
-
C言語でのCSVファイルの読み出...
-
Cプログラムについて
-
なぜ無限ループになるかが分か...
-
C++で指定文字列のカウント方法...
おすすめ情報