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

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

ただいまの
回答率

90.50%

  • C++

    3457questions

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

c++ iniファイルで取得した文字列をMessageBeepメソッドの引数に指定したい

解決済

回答 2

投稿

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

konan1234

score 1

C++でiniファイルの文字列を取得し、取得した文字列をMessageBeepメソッドの引数に指定したいです。
GetPrivateProfileStringメソッドを使って、iniファイルの値は取得できたのですが、MessageBeepメソッドの引数に指定するとエラーが発生してしまいます。解決策が分からないです。お力を貸してください。

・iniファイルの中身(test.ini)
[test]
sound = MB_ICONHAND

■C++(test.cpp)
・iniファイルの取得処理
// 変数
TCHAR ret[MAX_PATH]
// testiniファイルの値を取得
GetPrivateProfileString(TEXT("test"),TEXT("sound"),TEXT("取得失敗"),ret,sizeof(ret),TEXT"c\\test.ini" ));
⇒retにMB_ICONHANDが格納される。この変数をMessageBeepの引数に指定

// MessageBeep
MessageBeep(ret);
⇒retの引数は型"UINT"のパラメータと互換性がないエラーが発生したので以下に修正

MessageBeep(int(ret));
⇒コンパイルは出来たが違う音が出る。

恐らく、MB_ICONHANDをint型に指定してもMessageBeep(MB_ICONHAND);になっていないと思っています。
ちなみにMessageBeep(MB_ICONHAND);※MB_ICONHANDは固定値で試したところ、上手く行っているのは確認しております。
iniファイルの値を取得してもTCHARの配列のため、[0]M,[1]B,[2]_,[3]I…となっており混乱しております。

iniファイルの値を取得後、何か処理が必要なのでしょうか。
何か解決策があれば教えてください。
よろしくお願いいたします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

+1

こんにちは。

iniファイルから文字列で "MB_ICONHAND" を取得するわけですね。MB_ICONHANDはマクロで定義されているUINT型リテラルです。

つまり、文字列→UINT型への変換が必要になります。
お手軽にやるなら、下記イメージです。

#include <iostream>
#include <map>
#include <string>

std::map<std::wstring, UINT> MessageBeepType =
{
    {L"MB_OK",              MB_OK},
    {L"MB_ICONHAND",        MB_ICONHAND},
    {L"MB_ICONQUESTION",    MB_ICONQUESTION},
    {L"MB_ICONEXCLAMATION", MB_ICONEXCLAMATION},
    {L"MB_ICONASTERISK",    MB_ICONASTERISK}
};

int main()
{
    // retへiniファイルから読み出し
    MessageBeep(MessageBeepType[ret]);
}


Windowsではコンパイルしてないのでエラーがでたらごめんなさい。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/12/19 10:15

    返信ありがとうございます。
    私が使用しているはC++10のため、この方法ではできないのがわかりました。
    ※教えていただいたのはC++11から可能みたいです。

    キャンセル

  • 2017/12/19 11:48

    その通りですね。
    ところで、C++11の前はC++03ですので2003年に規定されています。C++10という規格はありません。もしかして、お使いのコンパイラがVisual C++ 2010という意味でしょうか?

    サンプルのstd::mapの初期化がC++03では書けない筈です。
    しかし、std::map自体はC++のかなり初期からありますし、回答のポイントはstd::mapを使って変換すれば楽ですよという内容です。初期化方法にこだわる必要はありません。
    C++の初期からあるinsertで積んでいけば良ですよ。

    ↓Windowsではないですが、必要なスタブを定義して確認してみました。
    https://wandbox.org/permlink/KDWzzZ9m7vCMLaZm

    でも、古いVisual C++は規格への準拠がぬるいと聞きますので、そこは心配ですね。

    キャンセル

  • 2017/12/19 14:08

    返信ありがとうございます。
    使用しているコンパイラはおっしゃるとおり、Visula C++ 2010です。
    mapの定義、要素の追加は教えていただいた通り、成功しました。ありがとうございます。

    後は GetPrivateProfileStringメソッドを使用して取得したiniファイルの文字列を以下のようにしたのですがエラーが出て上手くいきません

    ・GetPrivateProfileStringメソッドの第4引数の変数をwchar_t ret[]に格納
    TCHAR ini[MAX_PATH];

    GetPrivateProFileString("セクション","カラム","読み込み失敗", ini, sizeof(ini), "test.ini");

    wchar_t ret[] = ini;
    MessageBeep(MessageBeepType[ret]);
    ↓以下のエラーが発生

    ・error C2440:初期化中 TCHAR[]からwchar_t[]に変換できない
    ・集約オブジェクトには{…}での初期化が必要

    GetPrivateProfileStringで取得したiniファイルの文字列をどうすればMessageBeepの引数にしてできるでしょうか。何度も申し訳ないです。

    キャンセル

  • 2017/12/19 14:30

    GetPrivateProfileStringメソッドを使用して取得したiniファイルの文字列の型はconst char型なので
    加工ができないという認識であっておりますでしょうか。

    キャンセル

  • 2017/12/19 14:47 編集

    あなた int a[10]; int b[] = a; とか書きますフツー?

    キャンセル

  • 2017/12/19 15:27

    そのTCHAR配列のiniをそのまま渡せる筈なのですが、もしかして、文字セットとしてUnicodeではなくマルチバイトを使ってますか? (Unicodeの場合TCHARはwchar_tと定義されており、マルチバイトの時はcharと定義されています。)
    マルチバイトの場合は、wchart_t → char、std::wstring → std::string、L"xxx" → "xxx" と書けば良いです。

    なお、TEXT()やTCHAR的な手法でUnicodeとマルチバイトの両者を共通で書く方法もあるかもしれません。(そちらは把握していないです。マイクロソフト独自なので他で通用しませんし、私はnarrow文字列しかサポートしないような制御用ライブラリをよく使うのですが、その時パニックになるので。)

    > wchar_t ret[] = ini;

    でエラーがでるのは上記問題とは無関係です。epistemeさんが言っている通り、単純にC++文法違反です。

    キャンセル

  • 2017/12/19 16:33

    Chironianさん
    回答ありがとうございます。おかげさまで実現したいことが出来ました。
    本当に助かりました。ありがとうございました。

    キャンセル

0

使うべきはGetPrivateProfileStringではなくGetPrivateProfileIntでは?

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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

  • C++

    3457questions

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