文字列配列同士の比較について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら

文字列配列同士の比較について

#1

投稿記事 by » 14年前

現在、VC++とDXライブラリを用いてタイピングクイズゲームを作っています。
問題が提示され、その答えをタイピングで答えるというものです。

実はかなり前から壁にぶち当たっていました。
当初は文字列配列同士を比較して、同じなら正解判定、違うなら不正解判定、という感じで書いていました。
以下はタイピング問題そのものではなく、文字列配列の比較の簡易的な具体例です。
実際は「文字列1」には外部データより読み込んだ解答を配列に格納し、「文字列2」にはKeyInputStringを使って答えを入力させます。
char moji1[16]="あいうえお";        //文字列1
char moji2[16]="あいうえお";        //文字列2
if(moji1==moji2)    正解判定;    //文字列1と文字列2が同じなら正解判定
else            不正解判定;    //違うなら不正解判定
//これだと正解判定になるはず。
しかし、この方法だとどうやっても正解判定になるはずのものが不正解判定になってしまいます。
この段階で長いこと悩んでいました。

しばらく悩んでいた結果、配列全体同士を直接比較するのではなく、配列の個々同士を比較するときちんと思うように動作することに気がつきました。
先ほどのものを例にすると、moji1==moji2では不正解判定になるのにmoji1[0]==moji2[0]とするときちんと正解判定がでました。
つまり、以下のようにしてみたら正解判定になったのです。
char moji1[16]="あいうえお";        //比較文字列1
char moji2[16]="あいうえお";        //比較文字列2
if(moji1[0]==moji2[0])    正解判定;    //訂正箇所。各1バイト目同士が同じなら正解判定
else            不正解判定;    //違うなら不正解判定
そこで、以下のようにmoji1[0]~moji1[15]とmoji2[0]~moji2[15]を全て比較し、全て同じなら正解判定を出すプログラムを組んでみたところ、見事に成功しました。
char moji1[16]="あいうえお";        //比較文字列1
char moji2[16]="あいうえお";        //比較文字列2
int i;        //for文のカウント用
int j=0;    //一致数のカウント用
for(i=0;i<16;i++)
    if(moji1==moji2)
        j++;            //iバイト目同士が同じならjを1増やす
if(j==16)    正解判定;    //j(一致数)が16、つまり完全一致なら正解判定
else        不正解判定;    //違うなら不正解判定
前置きが長くなってしまいましたが、ここで質問があります。

1.
上記のように「moji1==moji2」といった、文字列配列同士を直接比較するのは無理なのでしょうか?
実際は文字列配列同士の比較はできるのに、私に落ち度があって出来なかった可能性はないのでしょうか?
「moji1[0]==moji2[0]」から順番に全部比較するという回りくどい方法でしか比べられないのでしょうか?

2.
仮に文字列配列同士の比較が出来ない場合、上記のような配列の個々を順番に全部比較する方法以外に、何か別のもっと良い方法というものはありますか?

3.
これはタイトルとは関係ない質問となりますがご容赦ください。
タイピングして答えるという特性上、万が一表記の揺れがあったり(例:引っ越し/引越し/引越)するかもしれません。
また、漢字の読み方を答えさせる問題も検討しているため、ひらがなだけで答えさせたいのです。
最初に言った通り、DXライブラリのKeyInputStringを使って答えさせようとしているのですが、変換を禁止することは実現可能ですか?

以上、拙い文章ですが宜しくお願いします。 画像

初級者

Re:文字列配列同士の比較について

#2

投稿記事 by 初級者 » 14年前

標準関数のstrcmp

Re:文字列配列同士の比較について

#3

投稿記事 by » 14年前

>初級者様

回答ありがとうございます!
言い訳にしかなりませんが、DXライブラリのリファレンスページと睨めっこしてばかりで、
恥ずかしながら標準関数のことについてはほとんど無知な状態でした。
strcmp、調べてきました。こんな便利な関数があったとは……。
これをきっかけに標準関数のことももっと勉強しないといけませんね。
精進します。改めてありがとうございました!



引き続き、どなたか3.について宜しくお願いします。 画像

へろりくしょん

Re:文字列配列同士の比較について

#4

投稿記事 by へろりくしょん » 14年前

試してはいませんのでうまくいくか分かりませんが。

DXライブラリのメインウィンドウをサブクラス化して、WM_IME_・・・系のメッセージを独自に処理すればよいのではないでしょうか。

しろ

Re:文字列配列同士の比較について

#5

投稿記事 by しろ » 14年前

#include <stdio.h>

int main(void){

    char a[15]="あいうえお";
    char b[15]="あいうえお";

    printf("%p\n",a);
    printf("%p",b);

    return 0;
}
をためしてみてください。

ゆーずぃ

Re:文字列配列同士の比較について

#6

投稿記事 by ゆーずぃ » 14年前

3の答えではないですが、
(moji1 == moji2)
では、配列のアドレスが同じかを判定しています。なので中身がどうであれアドレスが違えば偽になります。

Re:文字列配列同士の比較について

#7

投稿記事 by » 14年前

>へろり様

調べてみましたが、クラスをやっと理解し始めた自分にサブクラスは難しくて判りませんでした……。
文字の変換に関してはIMEをどうにかしていじって制御すれば良いということでしょうか?
DxLib.hの中にもIMEに関する記述があったので色々いじってみましたが相も変わらずといった状態です……。

>しろ様
>ゆーずぃ様

なるほど、アドレスを比べてたんですね。
アドレスが同じなわけないですから、通りで不正解判定になるわけですね。
また勉強になりました。



3.については、元々タイトルと関係ないので自分なりに調べなおしてから改めようと思います。
文字列の比較についてだけでも解決できたので十分な進展です。
回答してくださった皆さん、ありがとうございました!

ゆーずぃ

Re:文字列配列同士の比較について

#8

投稿記事 by ゆーずぃ » 14年前

DxLibの、MakeKeyInput関数なんかはどうでしょう?これのSingleCharOnlyFlagをTRUEにすると半角文字だけの受付になるようですから、これを使って一文字ずつの判定を行うというのは。
例:
問題文:引越し → 入力:hi=ひ○ kko=っこ○(又はltu=っ○ ko=こ○)sa=さ× si=し○

のような感じで。又はKeyInputSingleCharStringとか。使ったことがないので何とも言えませんが・・・。
エンターを押さなくても入力を受け付ける関数もその辺りにあるようですけど、もしエンターを押さなければ入力完了しないというのであれば、常にプログラムでエンターを流し続けるとかで対応できそうです。
私もタイピング好きなので、その内自作したいと思っていたところです。試作品が出来たらUPして下さいね(*´∇`*)

へろりくしょん

Re:文字列配列同士の比較について

#9

投稿記事 by へろりくしょん » 14年前

言葉が足りなかったようです。

>調べてみましたが、クラスをやっと理解し始めた自分にサブクラスは難しくて判りませんでした……。

サブクラス化とは、あるウィンドウに送られるメッセージをそのウィンドウのプロシージャが受け取る前に横取りしてしまう仕組みの事です。
ここで言うクラスというのは C++ のクラスとなんら関係ありません。

詳しくはこのあたりを。
http://wisdom.sakura.ne.jp/system/winap ... win64.html


>文字の変換に関してはIMEをどうにかしていじって制御すれば良いということでしょうか?

例えば、文字列が変換されると、Windows はそのウィンドウに対し WM_IME_COMPOSITION メッセージを送ります。
そういった WM_IME_*** といったメッセージを受け取った時に無視するなりなんなりすればよいのでは無いかと。

Re:文字列配列同士の比較について

#10

投稿記事 by » 14年前

>ゆーずぃ様

ローマ字で判定するのですね、なるほど。
出来ないこともなさそうですが、少々骨を折りそうですね……。
やらないことには何も始まらないので、とりあえず試してみますね。
ありがとうございました!

>へろり様

根本から変換禁止にするにはwindowsプログラム(で合ってるでしょうか……)を使わないといけない感じですね。
windowsプログラムには一切触ったことがなかったのですが、紹介されたサイトを熟読してみたらなんとか理解できそうです。
そもそも、いつも使ってたint WINAPI WinMain~のコピペもwindowsプログラムだったんですね。
とりあえずwindowsプログラムを最初から、順番にサブクラス化についても勉強してみたいと思います。
色々とありがとうございました!

閉鎖

“C言語何でも質問掲示板” へ戻る