質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

DXライブラリ

DXライブラリとは、DirectXを使ったWindowsソフトの開発に必ず付いて回るDirectXやWindows関連のプログラムを使い易くまとめた形で利用できるようにしたC++言語用のゲームライブラリです。

Q&A

解決済

3回答

3371閲覧

自作文字列比較関数を使って入力した文字に複数のあらかじめ用意した文字と一致した場合に特定の返事が来るようにしたい。

KZK13

総合スコア43

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

DXライブラリ

DXライブラリとは、DirectXを使ったWindowsソフトの開発に必ず付いて回るDirectXやWindows関連のプログラムを使い易くまとめた形で利用できるようにしたC++言語用のゲームライブラリです。

0グッド

0クリップ

投稿2020/06/21 05:33

編集2020/06/21 11:58
// 自作文字列比較関数 int my_strcmp(const char* s1, const char* s2) { // 先頭から走査して差があればループ終了 for (; *s1 == *s2; s1++, s2++) { // 終了前に終端文字が見つかったら差分なし if (*s1 == '\0') { return 0; } } return *s1 > * s2 ? 1 : -1; }

のプログラムを使い文字列の一致するかどうかの処理を行おうとしました。
ですが、文字列一つならば判断できるのですが、文字列が2つ以上になると判断ができなくなります。
というのもif文で言う二つ目の好きですという単語は一つ目の単語の一致の時に関数が終了してしまうため2つ目の文字列の一致に行かないためではなないかと考えています。なので、入力した文字列をif文で書いた文字列すべてと一致するまでループしたいのですが、どのように 自作文字列比較関数を書き直せばいいでしょうか?
今現在のプログラムです。
コード

あの後、他の自作関数で書いてみたのですが、
なぜか映画、好きですで違う返事が返ってきます。
何がダメなのでしょうか?デバッグでは値に問題はありませんでした。
他の自作関数でのコード

今現在のコードを正しく書き直したコードです。
if (strstr(input.c_str(), "映画") == 0&& strstr(input.c_str(), "好きです") == 0) の部分が==0と書いてしまったため映画、好きです、等しくない、すなわち入ってないときが真になってしまうので正しく動いていませんでした。なので if (strstr(input.c_str(), "映画")&& strstr(input.c_str(), "好きです")) と直しました。
https://pastebin.com/zhWJjWGv

他の自作関数での正しく書いたコードです。
他の自作関数を以下のように修正しました。

int my_str2(const char* s1, const char* s2)//ここで入力した文字列と用意された文字列を引数として扱う。 { //s1, s2を比較する関数を使うためだけにs2の文字列のサイズが必要なので、変数aに用意した文字列の情報s2を文字列の長さを測るための関数strlenに引数として渡す。 const size_t a = strlen(s2); //無限ループする。 for (;;) { //関数memcmpの返り値が0の時は一致した時なので、==0とする。 if (memcmp(s1, s2, a) == 0) return 1;//入力した文字列にい指定された文字列が入っていた場合は1を返すように設定した。 //入力した文字列が最後の文字まで到達した場合は一致する文字列がないということなので0を返すようにした。 else if (*s1 == '\0') return 0;//入っていなかった //文字列が一致した場合でも一致する文字列がない場合でも入力した文字列の一文字分の文字コードのバイト数?が繰り上がるようにした。 else ++s1; } }

https://pastebin.com/LXvvumLs

ちなみに、あの後細かくコメントを書いたのですが、GetKeyInputString(buffer, InputHandle);に関するコメントは以下のように書いて合っていますでしょうか?

GetKeyInputString(buffer, InputHandle);//ここでInputHandleに入力された文字列の数値をGetKeyInputStringにより文字コードに変換したものを上でchar型で定義したbufferに入れる。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

問題ありません。ちゃんと動いてます。

C

1#include <stdio.h> 2 3// 自作文字列比較関数 4int my_strcmp(const char* s1, const char* s2) { 5 // 先頭から走査して差があればループ終了 6 for (; *s1 == *s2; s1++, s2++) { 7 // 終了前に終端文字が見つかったら差分なし 8 if (*s1 == '\0') { return 0; } 9 } 10 return *s1 > * s2 ? 1 : -1; 11} 12 13int main() { 14 printf("abc / abc %d\n", my_strcmp("abc", "abc")); 15 printf("abc / def %d\n", my_strcmp("abc", "def")); 16 printf("def / abc %d\n", my_strcmp("def", "abc")); 17 18 return 0; 19}

実行結果:

abc / abc 0 abc / def -1 def / abc 1

[追記] strstr の件:

#include <stdio.h> #include <string.h> int main() { const char* str = "私は映画が大好きです"; if ( strstr(str,"映画") && strstr(str,"好きです") ) { printf("僕も映画は好きですよ!\n"); } return 0; }

問題ありませんねぇ...

投稿2020/06/21 07:26

編集2020/06/21 08:09
episteme

総合スコア16612

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KZK13

2020/06/21 08:02

編集後に書いたように私のif文での書き方が問題の原因でした。 確認していただきありがとうございました。
episteme

2020/06/21 08:40

解決したんならcloseよろしく。
KZK13

2020/06/21 11:20

度々すいません。 c言語でのC++のinput.c_str()のような関数はないでしょうか?
KZK13

2020/06/21 11:56

if (my_str2(buffer, "映画") && my_str2(buffer, "好きです")) { // message = "どんな映画が好きなんですか?"; konnnitiwasound = LoadSoundMem("line-girl1-konnichiha1.mp3"); PlaySoundMem(konnnitiwasound, DX_PLAYTYPE_BACK); z = 0; ++mozicount; } 変数inputに入る前はchar型のbufferに文字列が入るので、my_str2はchar*型を引数にとるため、char*型は文字列を定義するので、関数my_str2にはそのまま文字列が使えるので、その文字列が入っているbufferを直接書いたところ正しいかどうかはわかりませんがうまくいきました。
KZK13

2020/06/21 13:37

ちなみに、あの後細かくコメントを書いたのですが、GetKeyInputString(buffer, InputHandle);に関するコメントは以下のように書いて合っていますでしょうか? GetKeyInputString(buffer, InputHandle);//ここでInputHandleに入力された文字列の数値をGetKeyInputStringにより文字コードに変換したものを上でchar型で定義したbufferに入れる。
episteme

2020/06/21 20:41

1. C言語での... 意味がわからん 2. if ( my_str2 ... 質問ですか? 報告ですか? 3. ちなみに... 合っているの”だろう”とは思うが、こんな冗長なコメントが必要か?
KZK13

2020/06/22 13:57

私のような人間には必要なんです。
episteme

2020/06/22 21:08

// InputHandleに入力された文字列をbufferに格納する では理解できんのか...
guest

0

my_strcmp の問題について、コメント欄ではコードが書きにくいのでここに書きます。

C

1#include <stdio.h> 2#include <string.h> 3 4// 自作文字列比較関数 5int my_strcmp(const char* s1, const char* s2) { 6 // 先頭から走査して差があればループ終了 7 for (; *s1 == *s2; s1++, s2++) { 8 // 終了前に終端文字が見つかったら差分なし 9 if (*s1 == '\0') { return 0; } 10 } 11 return *s1 > * s2 ? 1 : -1; 12} 13 14int main() { 15 puts("my_strcmp:"); 16 printf("abc / abc %d\n", my_strcmp("abc", "abc")); 17 printf("abc / アイウ %d\n", my_strcmp("abc", "アイウ")); 18 printf("アイウ / abc %d\n", my_strcmp("アイウ", "abc")); 19 20 puts("strcmp:"); 21 printf("abc / abc %d\n", strcmp("abc", "abc")); 22 printf("abc / アイウ %d\n", strcmp("abc", "アイウ")); 23 printf("アイウ / abc %d\n", strcmp("アイウ", "abc")); 24 25 return 0; 26}

実行結果

my_strcmp: abc / abc 0 abc / アイウ 1 アイウ / abc -1 strcmp: abc / abc 0 abc / アイウ -1 アイウ / abc 1

'a' は 0x61、'ア' は shift JIS の場合 0xb1。UTF-8 の場合 0xef 0xbd 0xb1。
0x61 より 0xb1 または 0xef のほうが大きい。
しかし、char で比較をすると、0xb1 や 0xef は負の値と解釈され、
大小関係が逆になります。
そして、それは規格書に書かれている strcmp の仕様とは異なります。

投稿2020/06/21 07:48

kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KZK13

2020/06/21 10:16 編集

ありがとうございます。 自分で書いて置きながら恥ずかしいのですがどのようなことが起きているかの理解があっているか確認したくて質問します。 const char* s1と書いたことでs1は文字列の入るメモリの位置を表し、 ++s1とすることで文字列の入ったメモリの位置が繰り上がるわけでしょうか? メモリの位置が繰り上がることでその時のs1のメモリの位置入っている文字列とs2のメモリの位置入っている文字列文字列が一致した時に1が返り値としてくるのでしょうか?
guest

0

まあまず、大抵やろうとしていることは自分で書かずともすでに標準ライブラリとか使おうとしているライブラリにありますからそれを探すことです。

文字列の部分一致がほしいならstd::basic_string_view::findを使うといいでしょう。

投稿2020/06/21 06:45

yumetodo

総合スコア5852

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yumetodo

2020/06/21 08:40

まあ文字列はstring_viewで持ち回すほうが、あちこちでstrlenするとかいう非効率的な作業をしなくて済むと思いますよ。まじで。 あと、グローバル変数は可能な限り削減しましょう。今回で言うところのzのような状態を持たないといけないものは、classを使うようにするとよいです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問