ページ 11

配列について

Posted: 2007年10月12日(金) 19:11
by 神魔
どうも、お久しぶりです。
以前、DXライブラリが学校でうまく起動せず、一回は諦めましたが家では正常に動作したのでまたDXライブラリにお世話になっております。
課題研究では人工無脳というものを自分なりに作ってみようと思い、現在製作しております。
そのなかで、配列に格納された文字列の中からキーワードを探し、もしもキーワードと一致するものがあれば特定の文字列を出力する、というプログラムを作っております。
しかし半角文字ではうまくいくのですが、全角文字ではうまくいきません。
ポインタを使わなければいけないのかなぁ、なんて思いやってみたのですが結果は同じでした。
いくら考えても解決策が思いつかなかったので質問させていただきます。




#include "DxLib.h"
#include <string.h>
#pragma warning(disable : 4267)
#pragma warning(disable : 4996)
void hitori(void);
void aikotoba(void);
char *K;
char name[31],hatugen[40];
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
ChangeWindowMode( TRUE ) ; // ウィンドウモードに変更
if( DxLib_Init() == -1 ) return -1 ; // DXライブラリ初期化処理


SetDrawScreen( DX_SCREEN_BACK ) ; // 描画先を裏画面に設定



if(CheckHitKey(KEY_INPUT_LSHIFT)==1){
printfDx("%s>",name);
KeyInputString(380,0,33,hatugen,FALSE);
printfDx("%s\n",hatugen);
aikotoba();
}





WaitKey(); // 何かキー入力があるまで待つ
DxLib_End() ; // DXライブラリ使用の終了処理
return 0 ; // ソフトの終了
}

void aikotoba(void){
SetDrawScreen( DX_SCREEN_BACK ) ;

K=hatugen;

while(*K != '\0'){
if(*K=='?'){
printfDx("柳葉魚>それは内緒のさくらんぼです。\n");
goto hell;
}
K++;
}

hell: ;


};




上のプログラムは現在作っているものの一部です。
このプログラムでは左のシフトキーを押し、発言権を得てから半角の"?"を入力すると"柳葉魚>それは内緒のさくらんぼです。"と出力するプログラムです。
一回配列に文字列を格納し、それをポインタ変数に渡して調べます。
これは正常に動くのですが、if(*K=='?')の''内のキーワードにあたる部分を全角文字にするとうまくいきません。
どうすれば全角文字でも反応してくれるようになるのでしょうか?
どなたか教えてください。

Re:配列について

Posted: 2007年10月13日(土) 02:47
by 管理人
このプログラムはコンソール出力ではダメなのでしょうか?
後、SetDrawScreen( DX_SCREEN_BACK ) ;は一度だけ呼べばOKです。
それと繰り返し描画を行っていないので、裏画面に設定する必要がありません。
このプログラムは動くと仰っていますが、一瞬で処理が終わるため、シフトキーを押している暇が無いのと、nameに何も入っていないのと、描画反映関数が無いので描画されないので思った処理が出来ていないのではないでしょうか。

'?'を'?'に、つまり全角にするとうまくいかないのは、シングルコーテーションで半角文字を囲むとそれが文字コードを表すからです。

printf("%d ", 'a');
printf("%d ", 'b');
printf("%d ", '1');
printf("%d ", '2');

これらを出力してみるとその意味がわかります。全角文字は2バイトで扱われていますから、配列2つ分両方一致しないとその文字が一致するかどうか判定出来ません。

char c[/url] = "?";

として、c[0]とc[1]が両方検索対象に一致するか調べる必要があります。
printfDxしか使わないならコンソール画面でも同じことが出来ますし、もしDXライブラリを生かした処理がしたいなら裏画面設定をし、ループ処理させて入力の監視、描画をしてみるといいと思います。

DXライブラリの使い方についてはゲームプログラミングの館にて紹介していますし、本家リファレンスページなどにも詳しく載っていますのでよければ参考にしてください。

Re:配列について

Posted: 2007年10月13日(土) 21:35
by 神魔
管理人様、ありがとうございます!!!
そうか全角って2バイトでしたね。
学校では半角の数値か文字でしかやってなかったので気付きませんでした…。
でもこれで前に進めそうです、本当にありがとうございました!!!


>それと繰り返し描画を行っていないので、裏画面に設定する必要がありません。
>このプログラムは動くと仰っていますが、一瞬で処理が終わるため、シフトキーを押している暇が無いのと、nameに>何も入っていないのと、描画反映関数が無いので描画されないので思った処理が出来ていないのではないでしょ>うか。

えっとですね、載せたプログラムは一部でして…。
全部載せようかとも思ったのですがプログラムが整理されていなくて見にくいと思い、必要と思われる部分だけ載せさせていただきました。
なのでちゃんと名前を聞いてきてくれるしキャラクターはマウスに向かって動いてくるし独り言もしゃべるし、と動きます。
そこの所書くの忘れてました、すいません。

Re:配列について

Posted: 2007年10月13日(土) 23:01
by 管理人
なるほど、一部でしたか、失礼しました。
私もなんちゃって人工知能ソフトウェアロボットを作ったことがあります。
OpenGLで画面にロボットを描いて、わずかながら会話や言葉で遊ぶゲーム(ノット21やジャンケン、○×ゲームなど)が出来るものでした。
作っていると会話させることがどんなに難しいことか感じさせられたことがあります。
何かつまったらまたいつでも聞いてください。
それでは研究がんばってくださいm(_ _)m

Re:配列について

Posted: 2007年10月14日(日) 18:28
by 神魔
すいません、また行き詰ってしまいました…。
全角文字は2バイト使用している、だから検出できなかったところまではわかったのですが、今度は新しいエラーが出るようになってしまいました。

error C2446: '==' : 'const char *' 型から 'int' 型への変換ができません。
error C2040: '==' : 'int' は 'const char [3]' と間接操作のレベルが異なります。

あと、使用している配列が出てきている部分だけ載せさせていただきます。

#include "DxLib.h"
#include <string.h>
#pragma warning(disable : 4267)
#pragma warning(disable : 4996)
void hitori(void);
void aikotoba(void);
char name[31],hatugen[29];
int A[29];
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
ChangeWindowMode( TRUE ) ; // ウィンドウモードに変更
if( DxLib_Init() == -1 ) return -1 ; // DXライブラリ初期化処理


SetDrawScreen( DX_SCREEN_BACK ) ; // 描画先を裏画面に設定

if(CheckHitKey(KEY_INPUT_LSHIFT)==1){
printfDx("%s>",name);
KeyInputString(380,0,29,hatugen,FALSE);
printfDx("%s\n",hatugen);
aikotoba();
}



WaitKey(); // 何かキー入力があるまで待つ
DxLib_End() ; // DXライブラリ使用の終了処理
return 0 ; // ソフトの終了
}

void aikotoba(void){
SetDrawScreen( DX_SCREEN_BACK ) ;
int i;
for(i=0;i<29;i++){
A=hatugen;
}

for(i=0;i<29;i++){
if(A=='?'){
printfDx("柳葉魚>それは内緒のさくらんぼです。\n");
goto hell;
}
if(A=="?"){
printfDx("柳葉魚>それは企業秘密です。\n");
goto hell;
}


}


hell: ;
for(i=0;i<29;i++){
hatugen=0;
A=0;
}

};

なんでも最後の
if(A=="?"){
のところに間違いがあるそうなんですが、'const char *'とか'const char [3]'とか言われても自分にはちんぷんかんぷんで…。
ネットで調べてみたんですけどどれも難しい事例ばかりでわかりませんでした。
どうすればいいのでしょうか?
ちなみに配列Aは気にしないでください。
char型でダメならint型だ!!とか浅はかな考えで作っただけですので…。

Re:配列について

Posted: 2007年10月14日(日) 18:38
by tk-xleader
文字列比較はこんな感じです。

char str[/url]={"YES"};
printf("%d\n",strcmp(str,"YES"));

printfによって出力される値は0になります。strcmpは、文字列が同一の時に0を返します。違う場合は確か辞書式にどうにかした整数値を返すはずです。

Re:配列について

Posted: 2007年10月14日(日) 19:36
by 神魔
えっと、strcmpって””内の文字列と全て一致していないと0を返さないのですか?
自分が今作ろうと思っているものは、例えば配列str内に、
「ねぇ今恋人とかおるん?」
という文字列が入っていたときに
「それは内緒のさくらんぼです。」
と返すような、キーワードが配列のどの部分に入っていても反応するものを作ろうと思っております。
strcmpという関数の構造や仕組みがよくわからないのでいけないのですが、例を見ると配列内の文字列と完全一致していないと0を返さないようなので今作ろうとしているプログラムには使えないかもなんです。

tkmakwins15さん、勘違いだったらスイマセン