Qtの文字列変換について

このQ&Aのポイント
  • C++言語でQtを使用して文字列変換を行う際に、同じコードでも異なる結果が得られる問題が発生しています。
  • 特に、QVariantMapを使用して文字列を取得する場合に、toLocal8Bit()関数を使用すると、一部の変数で正しい結果が得られず、初期値のままとなってしまいます。
  • この問題の原因は、文字列の変換手順にある可能性があります。適切な変換手順を使用することで、問題を解決できる可能性があります。
回答を見る
  • ベストアンサー

Qtの文字列変換について

初めて質問させて頂きます。 現在下記の環境にて開発をしております。 OS:Windows7 言語:C++(VS2005) Qt:4.7.3 下記のコードを試すと、違う結果となってしまっております。 私には、なぜ違う結果となるかわかりません。 C++の基本的な動作の話でしたら申し訳ありませんが、是非ご教授下さい。 ----- QVariantMap test; test.insert( "STR_TEST", "abcde" ); QByteArray hogehoge = test.value("STR_TEST").toString().toLocal8Bit(); char* hoge1 = hogehoge.data(); char* hoge2 = (test.value("STR_TEST").toString().toLocal8Bit()).data(); ----- これでhoge1とhoge2の内容が違ってしまいます。 hoge1は"abcde"がとれています。 hoge2は失敗しているようで、初期値のままのようです。 なにか変換の手順等の問題があるのでしょうか? 宜しくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • heburusu
  • ベストアンサー率85% (140/164)
回答No.2

こんにちわ。 >その手前のQStringからQByteArrayへの変換時(toLocal8Bit()実行時)、QStringの一時オブジェクトは同じように開放されないのでしょうか? >失敗しているのであれば、hoge1のパターンも変換失敗となりそうな気がしています。 はい、QStringの一時オブジェクトは開放されます。 toLocal8Bitの関数内部でQByteArrayが生成され返されますが、QByteArrayのコンストラクタで内部に別の配列を作成し、文字列自体をコピーしているのだと思います。 (= QString内部の配列とQByteArray内部の配列は別物 = QStringが開放されてもQByteArrayは無関係) また、参考URLのコンストラクの説明に"QByteArray makes a deep copy of the string data"とありますので、"deep copy"などのキーワードで検索されるとまた宜しいかと思います。 長々と説明が上手くできず申し訳ないのですが・・・、コードでなら以下のように確認できると思います。 -- QString* hoge = new QString("hoge"); QByteArray hogehoge = hoge->toLocal8Bit(); delete hoge; printf("%s\n", hogehoge.data()); ★QByteArray内部の別の配列に文字列がコピーされているので、hogeが解放されても表示されるはず

参考URL:
http://qt-project.org/doc/qt-4.8/qbytearray.html#QByteArray-2
yasukana
質問者

お礼

お礼が遅くなりました。 わかりやすい説明有難うございます。 大変わかりやすく、理解する事ができました。 有難うございます。

その他の回答 (1)

  • heburusu
  • ベストアンサー率85% (140/164)
回答No.1

data()でQByteArray が内部に持つポインタがhoge2に渡されますが、 その直後にQByteArrayのデストラクタが実行され、そのポインタが無効なアドレスを指しているために内容が異なっているのではないかと思います。 説明がわかりにくいかもしれませんので、わかりやすく下記と以下のような感じで挙動がことなっている状態です。 参考URLの"一時オブジェクト"に関する記事を読んで頂くとより理解いただけるかと思います。 ■hoge1 QByteArray* hogehoge = new QByteArray(); char* hoge1 = hogehoge ->data(); printf("%s\n", hoge1); ■hoge2 QByteArray* hogehoge = new QByteArray(); char* hoge2 = hogehoge ->data(); delete hogehoge; ★ここでhoge2は無効なアドレスとなる printf("%s\n", hoge2);

参考URL:
http://codezine.jp/article/detail/276?p=4
yasukana
質問者

補足

heburusu様 丁寧なご回答感謝いたします。 とてもわかりやすいです。 ただこの場合、QByteArrayが開放されているとすると、 その手前のQStringからQByteArrayへの変換時(toLocal8Bit()実行時)、QStringの一時オブジェクトは同じように開放されないのでしょうか? 失敗しているのであれば、hoge1のパターンも変換失敗となりそうな気がしています。 補足情報ですが、下記でも同じ状況(失敗)となります。 char* hoge2 = test.value("STR_TEST").toString().toLocal8Bit().data(); 私の理解不足かもしれませんが、なんとなく気になっております。 もし宜しければ、ご回答をお願いいたします。

関連するQ&A

  • 文字列変換ついて

    開発環境  XP Home Edtion Microsoft Visual C++ 2008 Express Edition Microsoft SQL Server 2005 Express Edition Visual C++で入力フォームから数字の入力文字列でのInsert文を実行してそのまま反映させることはできたの ですが、日本語やアルファベットが入らないのですがどうしたらよいでしょうか? PSTR strText; String^ data; char *ree; ree=(char*)strText; String^ data; data=gcnew String(ree); SqlConnection^ sqlConn = gcnew SqlConnection("Data Source=.\\SQLEXPRESS;AttachDbFilename=C:\\SOUTUKEN\\test.mdf;Integrated Security=True;User Instance=True"); sqlConn->Open(); str= "INSERT INTO table1 (test) VALUES("+data+")"; SqlCommand^ sqlCmd = gcnew SqlCommand(str,sqlConn); SqlDataReader^ exeReader = sqlCmd->ExecuteReader(); sqlConn->Close(); 何卒よろしくおねがいします。

  • ostringstreamからCの文字列を得る方法

    ostringstreamからCの文字列を得る方法について質問です。 ostringstreamのstr()メソッドを使えば、string型が得られると思うのですが、 以下の様にすると期待する様な結果が得られません。 ostringstream hoge; hoge << "HOGE" << "FUGA"; const char* p; p = hoge.str().c_str(); // NG str()メソッドで取得した結果を一旦string型に入れると期待する文字列を得る事が出来ます。 string tmp = hoge.str(); p = tmp.c_str(); // OK なぜp = hoge.str().c_str();では期待する結果("HOGEFUGA")を得る事が出来ないのでしょうか? コンパイラはVC++ 2010 Express Editionです。 よろしくお願いします。

  • 文字列の関数引渡しについて

    呼び出す関数が int sample(char *moji)となります。 呼び出しもとで1、2と記載するのは正しいのでしょうか? 1. char *c[SIZE]; *c = DialogBox1->FileName.c_str(); /*FileNameは abcde */ sample(*c); 2. sample("abcde"); 3. char *c[SIZE]="abcde"; sample(c); 4. char *c[SIZE]; c = "abcde"; sample(c); 呼び出す関数にはアドレスを渡すものと思っているのですが 3や4は正しいのでしょうか? また間違っているものやおかしい使い方などが あれば教えていただけないでしょうか。 それぞれの番号の処理について教えていただければ 幸いです。

  • sprintf の使い方について

    C 言語の超初心者につき,おろかな質問をお許しください。 sprintf 関数について char str[40]; sprintf(str, "hogehoge %d", hoge_int); という文法はよく目にするのですが char *str; sprintf(str, "hogehoge %d", hoge_int); という文法はあまり見たことがありません。 両方ともちゃんと動くのですが,後者は文法的に正しいのでしょうか? char str[40] とした場合でも char *str とした場合でも, str は文字列の最初の文字のアドレスを表すんだったと思うんですが。 違いが分からず,混乱しています。 初心者につき,間抜けな質問をしているかもしれませんが,ご教授くださると幸いです。

  • C初心者です。配列に文字列を代入の仕方

    C言語の初心者です。質問なのですが、 配列の、ある位置に文字列を加える時はどうしたら言いのでしょうか? char str[100]; str[10]から文字列 "ABCDE"というのを加えたいのです。 自分が考えられるのは str[10] = 'A'; str[11] = 'B'; str[12] = 'C'; str[13] = 'D'; str[14] = 'E'; と入れていく方法しか思いつきません。 他にもっと見やすい方法等御座いませんでしょうか? 宜しくお願いします。

  • 文字列の変換について

    PHPを用いて、リファラーから検索文字列を取得するスクリプトを作成しています。下記のような感じです。ただ、検索文字列にスペースが連続していたり、「ホテル、予約」「時刻表・東京」などのように「、」や「・」があると文字列が連続してしまい、うまくいきません。 よろしくお願いします。 $ref=split('\?','http://hogehoge.com?q=リファラー'); mb_parse_str($ref[1],$q); foreach($q as $key => $value){ if($key=='p' or $key=='q'){ // yahooとgoogleだけ調べると仮定 $value=mb_convert_kana($value,'rnKs'); $keyword=split(' ',$value); foreach($keyword as $k){ echo $k; } } }

    • ベストアンサー
    • PHP
  • 文字列を逆転させて表示するには

    Java超初心者です。 タイトルの通りJavaで文字列を逆転させたいのです(出力まで含む)。 文字列abcdefgをgfedcbaみたいな感じでです。 以下に自分が分かる範囲で書いてみました(分からない部分が多いので未完成です、すいません)。 //の部分のコメントアウトした箇所はJavaの方で元々逆転させる文法があるらしく、それを検索して書きました(今回は無視してください)。 しかしもっと基本的な文法を用いた方法が出来ないと駄目だと思い、今回はreverse等の既存の文法を使わず、繰り返しのfor文とchar型で文字を1つ1つ連結して文字列を逆転した形にしたい訳です。 私の作成した文は関係ない文があったり、おかしいところが多々あると思いますが、どうしたらよいか教えてください(実際以下のプログラムの出力結果が目標とかけ離れているのは承知してます、恥ずかしいですがあえて状況を把握して欲しいので載せます)。 よろしくお願いします。 public class hantai { public static void main(String[] args) { String str = "abcdefg"; int length = str.length(); System.out.println("length " + length); System.out.println("charAt(0)=" + str.charAt(0)); String value =""; for(int i = 0; i < str.length(); i++) { char c = str.charAt(i); value = value + c; System.out.println(value); //StringBuffer sbrev = new StringBuffer(str); //String strrev = sbrev.reverse().toString(); //System.out.println(strrev); } } } ホント、こんなレベルなんで暇なときにでも解答お願いします、ハハ・・・orz

    • ベストアンサー
    • Java
  • C言語で文字列をかえす正しい書き方が知りたいです?

    C言語で次の警告が表示されます。 文字列を返したいのですが、正しい書き方はどのようにすれば良いのでしょうか? jci.h(20) : warning C4172; ローカル変数またはテンポラリのアドレスを返します。 char *test(char *a, int b) { char str[BUFSIZ]; return str; <------ }

  • 文字列のコピー

    C言語で、文字列をコピーする関数で、処理が止まってしまいます。 以下が実行したプログラムです。 #include<stdio.h> #include<string.h> void copy(char *str2 ,char *str3){ strcpy(str2,str3); } void input(char* str){ scanf("%s",str); } int main (void){ char *a; char *b="TEST"; printf("%s\n",b); input(a); copy(b,a); printf("%s",b); return(0);} copy(b,a);で処理が止まってしまいます。入力した文字列を表示できるように、御指摘お願いします。

  • 文字列リテラルの比較について

    下記のプログラムの疑問点を教えて頂きたい。 (1)mainの実引数(ch[0]は、str_chr関数を呼ぶ場合、intの型変更する理由、 (2)cをキヤストしてchar 型変更した後、再度int C に代入する理由 (3)char型*Sとint 型Cでは、型が違うのに何故比較できる理由 char *str_chr(const char *s, int c) { c = (char)c; while (*s != c) { } main { char ch[2]; str_chr(G,ch[0]) main {

専門家に質問してみよう