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

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

ただいまの
回答率

88.91%

bufferに入れた文章をmecabにより分解して、resultに代入してから、 memotxtを読み込み一致した文章を描画するようにしたい

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 705

KZK13

score -9

環境

  • Windows10
  • DXライブラリ
  • mecab

行いことと原因
bufferに入れた文章をmecabにより分解して、resultに代入してから、
memotxtを読み込み一致した文章を描画するようにしたいのですが、
なぜかうまく一致しません。
「タバコ」と入力すると
resultにはタバコの言葉が入るのは確認できました。
そのタバコの言葉がresultに入り、
else if (my_str2(buffer2, result) == 1) により、
buffer2に入るmemo.txtの「タバコ→体に悪い」という文章の含むタバコと一致して
「体に悪い」と描画されるはずが「タバコとは何ですか?」と表示されます。
なぜそうなるか原因がわかりません。

以下はコードです。
コード

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • episteme

    2020/07/21 08:55

    この質問が発せられたということは
    https://teratail.com/questions/278955
    こいつは解決したんですか?

    キャンセル

  • 退会済みユーザー

    2020/07/21 16:38

    複数のユーザーから「やってほしいことだけを記載した丸投げの質問」という意見がありました
    「質問を編集する」ボタンから編集を行い、調査したこと・試したことを記入していただくと、回答が得られやすくなります。

回答 2

checkベストアンサー

0

「タバコ」と入力すると
resultにはタバコの言葉が入るのは確認できました。

ホント?

#include <mecab.h>
#include <stdio.h>

int main() {
    char buffer[] = "タバコ";
    MeCab::Tagger* tagger = MeCab::createTagger("");
    const char* result = tagger->parse(buffer);
    printf("[%s]\n", result);
    return 0;
}


実行結果

[タバコ 名詞,一般,*,*,*,*,タバコ,タバコ,タバコ
EOS
]


resultに得られる結果は ("タバコ"を含みますが)"タバコ"ではありませんけど。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/21 16:38 編集

    つまり答えに窮したってことか、窮するよね当然。
    「KZK13は昨日教わったことすら活かせません」と公言することになるからね。

    あたしゃ誰の質問だろうが、答えられるなら答えるよ。
    それを受け入れるか否かは質問者の勝手だ。

    キャンセル

  • 2020/07/21 19:45 編集

    されどもう一度、
    episteme殿に答える義理はありませぬ。(所詮は推測なのでどうぞ勝手に考えてください。)
    引き取って頂きたい。(epistemeさんは、マゾなのかな?)

    キャンセル

  • 2020/07/21 20:13 編集

    ともかく、この質問をcloseする権限と責任はあなたにある。
    解決したならcloseしてください。

    ついでにこっちも
    https://teratail.com/questions/278952

    キャンセル

0

解決済みになっていますが、私の趣味でコードを書いてみました。
質問者には全く理解できないでしょう。

#pragma warning(disable: 4996)
#include "DxLib.h"
#include <mecab.h>
#pragma comment(lib, "libmecab.lib")

// drawString -- 文字列を一文字ずつ表示する
void drawString(int x, int y, int color, int* pos, const char* str)
{
    char c = str[*pos];  // *pos は pos[0] で表示文字位置
    if (pos[1] == 0 && c != '\0') *pos += IsDBCSLeadByte(c) ? 2 : 1;
    if (++pos[1] == 10) pos[1] = 0;  // pos[1] はフレームカウンタ
    DrawFormatString(x, y, color, "%.*s", *pos, str);
}

const char *setStr(const char *s, int *pos)
{
    pos[0] = pos[1] = 0;
    return s;
}

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
    SetGraphMode(1500, 780, 32);        // ウィンドウの大きさを指定
    ChangeWindowMode(TRUE);             // 全画面ではなくウインドウを使用
    if (DxLib_Init() == -1) return -1;  // DXライブラリの初期化
    SetFontSize(33);                    // フォントサイズを変更
    SetDrawScreen(DX_SCREEN_BACK);      // 描画先を裏にする
    int kih = MakeKeyInput(256, FALSE, FALSE, FALSE); // Key Input Handle
    SetActiveKeyInput(kih);             // キー入力をアクティブにする

    int memory = 0;          // 記憶モード(memory)
    int found = 0;           // 単語がメモ内で見つかったか(found)
    char kinbuf[256] = "";   // GetKeyInputString() で取得するキー入力バッファ
    char memobuf[256] = "";  // fgets() でメモを読み込む行バッファ
    char strbuf[256] = "";   // drawString() 用の文字列バッファ
    const char* str = "";    // str は drawString で表示する文字列を指すポインタ
    int pos[2] = { 0 };      // str の表示文字位置(pos)(初期値をゼロにする)
    const char* result = NULL;  // MeCab の parse() の結果(result)
    char resbuf[4096] = "";  // result のコピーバッファ
    char *words[100];        // 単語(word) 名詞、動詞、形容詞のみ
    int wcount = 0;          // 単語の個数(count)
    char wbuf[256] = "";     // words の表示用バッファ

    while (ProcessMessage() == 0) {
        ClearDrawScreen();                   // 画面の初期化

        DrawKeyInputModeString(1500, 0);     // 入力モードを描画
        DrawKeyInputString(100, 50, kih);    // 入力途中の文字列を描画
        if (CheckKeyInput(kih) != 0) {       // エンターキーが押された時
            GetKeyInputString(kinbuf, kih);  // 入力文字列を取得

            MeCab::Tagger* tagger = MeCab::createTagger("");
            result = tagger->parse(kinbuf);
            strcpy_s(resbuf, sizeof resbuf, result);
            delete tagger;
            wcount = 0;
            words[wcount] = strtok(resbuf, "\t\n");  // 単語
            char *p = strtok(NULL, "\t\n");          // 品詞
            while (wcount < 100 && p) {
                if ((strlen(words[wcount]) != 2 ||
                        (unsigned char)words[wcount][0] >= 0x88)
                    && (!strncmp(p, "名詞", 4) || !strncmp(p, "動詞", 4) ||
                        !strncmp(p, "形容詞", 6))
                ) wcount++;
                words[wcount] = strtok(NULL, "\t\n"); // 単語
                p = strtok(NULL, "\t\n");             // 品詞
            }
            p = wbuf;
            *p = '\0';
            for (int i = 0; i < wcount; i++) p += sprintf(p, "%s ", words[i]);

            if (kinbuf[0] == '\0') {
                str = setStr("文字列を入力してください。", pos);
            }
            else if (strstr(kinbuf, "覚えて")) {
                str = setStr("何を覚えますか?", pos);
                memory = 1;
            }
            else if (memory == 0) {
                FILE *fp = fopen("memo.txt", "r");
                if (fp == NULL) goto End; // オープンに失敗した場合、終了
                str = setStr("どうしましたか?", pos);
                found = 0;
                while (fgets(memobuf, 256, fp)) {
                    for (int i = 0; i < wcount; i++) {
                        if (strstr(memobuf, words[i])) {
                            found = 1;
                            break;
                        }
                    }
                    if (found) break;
                }
                fclose(fp);
                if (!found) {
                    memobuf[0] = '\0';
                    sprintf(strbuf, "申し訳ありません。「%s」とは何ですか?", kinbuf);
                    str = setStr(strbuf, pos);
                }
            }
            if (memory == 1) {
                if (strstr(kinbuf, "→")) {
                    FILE *fp = fopen("memo.txt", "a");
                    if (fp == NULL) goto End; // オープンに失敗した場合、終了
                    fprintf(fp, "%s\n", kinbuf);
                    fclose(fp);
                    sprintf(strbuf, "「%s」を記憶しました", kinbuf);
                    str = setStr(strbuf, pos);
                    memory = 0;
                } else {
                    str = setStr("→を含む文字列を入力してください", pos);
                }
            }
            SetActiveKeyInput(kih);     // 再度キー入力をアクティブにする
            SetKeyInputString("", kih); // キー入力文字列を初期化する
        }

        drawString(0, 0, GetColor(5, 255, 255), pos, str);  // 1文字ずつ表示
        DrawFormatString(0, 50, GetColor(255, 255, 255), memory ? "記憶:" : "入力:");
        DrawFormatString(100, 200, GetColor(5, 255, 0), "memobuf = [%s]", memobuf);
        DrawFormatString(100, 300, GetColor(175, 80, 100), "words = [%s]", wbuf);
        DrawFormatString(100, 400, GetColor(255, 255, 0), "kinbuf = [%s]",kinbuf);
        DrawFormatString(100, 500, GetColor(255, 255, 0), "result = [%s]", result);

        ScreenFlip(); // 裏画面の内容を表画面に反映させる
    }
End:
    DeleteKeyInput(kih); // 用済みのキー入力を削除する(バッファの解放)
    DxLib_End(); // DXライブラリの使用終了
    return 0;
}


追記
メモリーリークしないように delete tagger; を追加しました。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 88.91%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • トップ
  • Cに関する質問
  • bufferに入れた文章をmecabにより分解して、resultに代入してから、 memotxtを読み込み一致した文章を描画するようにしたい