QStringからchar *への変換


94

次の方法でQStringをchar *型に変換しようとしましたが、動作しないようです。

//QLineEdit *line=new QLineEdit();{just to describe what is line here}

QString temp=line->text();
char *str=(char *)malloc(10);
QByteArray ba=temp.toLatin1();
strcpy(str,ba.data());

この方法で起こりうる欠陥を詳しく説明できますか、それとも別の方法を提供できますか?


あなたの例は私にとってうまくいきますが、どこに問題がありますか?
Viesturs

3
私の英語で申し訳ありませんが、なぜそのようなアプローチを使用することが正しくないのですか? QString s("some"); printf(reinterpret_cast<char *>(s.data()));
bartolo-otrit 2012

回答:


114

よく、Qt FAQは言います:

int main(int argc, char **argv)
{
 QApplication app(argc, argv);
  QString str1 = "Test";
  QByteArray ba = str1.toLocal8Bit();
  const char *c_str2 = ba.data();
  printf("str2: %s", c_str2);
  return app.exec();
}

おそらくあなたは他の問題を抱えているでしょう。これはどのように機能しませんか?


11
const char*char*同じタイプではありません。
オービットのライトネスレース

3
@LightnessRacesinOrbit:知らずにQStringのコンテンツに書き込むのは恐ろしい考えです。したがって、もちろんconst char*実際に取得できるものです。ユーザーはデータを書き込み可能なバッファに自由にコピーできます。
Eli Bendersky、2012年

1
同意します。ただし、質問では、char*ではなくchar const*、について尋ねられました。あなたの回答は、言及せずにその事実を単に無視しています。
オービットのライトネスレース

4
@LightnessRacesinOrbit:時々、最良の答えは質問を尋ねないことです。つまり、正しいことを尋ねているのではないことを指摘します。この回答は質問の投稿者に受け入れられたので、目標を達成したと思います
Eli Bendersky

2
FAQが使用するように更新されているようtoLocal8Bit()です。
ラリー

52

多分

my_qstring.toStdString().c_str();

またはフェデリコが指摘するように、より安全:

std::string str = my_qstring.toStdString();
const char* p = str.c_str();

それは最適とはほど遠いですが、仕事をします。


3
これはUnicode文字を台無しにしてしまいます。Unicode対応のソリューション:stackoverflow.com/a/4644922/238387
jlstrecker 2012

21
このメソッドは非常に危険なので使用しないでください。toStdString()新しいstd::stringオブジェクトを返し、内部データへのポインタをconst char *取得します。ただし、文字列オブジェクトはこのステートメントの直後に破棄されるため、後続のステートメントで使用した場合、結果ポインタにはおそらく有効なアドレスがありません。
RicoRico 2016年

@RicoRico toStdString()危険な方法ではありません。それは生のポインタの使用です。または、より具体的には、スコープがよく理解されていないオブジェクトからの生のポインタの使用。
notlesh

具体的には、C ++一時ファイルは通常、それらを作成するステートメントの終わりまで存在します。したがって、答えの最初の形式は、関数呼び出しでインラインで使用される場合は問題ありません(関数が将来の使用のためにポインターを格納しない場合)、変数に割り当てられる場合は問題があります。
プラグウォッシュ

46

QStringchar *に変換する最も簡単な方法は、qPrintable(const QString&str)です。これは、に展開するマクロstr.toLocal8Bit().constData()です。


なぜこれがより一般的な答えではないのですか?Qtのソースをざっと見て、偶然これについて知りました、まさにそれが彼らのしていることです。
プルーシャス2016年

6
@Phluciousは、理由:1)qPrintableを返しconst char*ていないchar*str.toLocal8Bit().data()リターンをchar*。2)が使用さconst char*れたステートメントでセミコロンを押すとすぐに、へのポインタが無効になりますqPrintable。したがってconst char* c_ptr = s.toLocal8Bit().constData();、意味がありません。
WindyFields 2017

1
@Phluciousおかげで、あなたはこれらの、質問がcharについての投票答えが間違っているすべてのトップである:)命の恩人であり、彼らはのconstのchar *戻ってきている
user889030

qPrintable出力はゼロ終端されることが保証されていますか?
Giovanni Cerretani

@WindyFields- qPrintable()説明で警告したように:「qPrintable()が使用されているステートメントの後、charポインタは無効になります。」
ジェレミー

6

Davidの答えは、ファイルへの出力または画面への表示にのみ使用している場合は問題なく機能しますが、関数またはライブラリが解析にchar *を必要とする場合は、この方法が最適です。

// copy QString to char*
QString filename = "C:\dev\file.xml";
char* cstr;
string fname = filename.toStdString();
cstr = new char [fname.size()+1];
strcpy( cstr, fname.c_str() );

// function that requires a char* parameter
parseXML(cstr);

4

編集済み

この方法でも機能します

QString str ("Something");

char* ch = str.toStdString().C_str();

これは、求められるものではなく、別の変換(std::stringQString)のように見えます。
Toby Speight 2018年

3

文字列にLatin1以外の文字が含まれていると、データが未定義になる可能性があります。それはあなたが「それはうまくいかないように見える」とはどういう意味かによって異なります。


2

正しい解決策は次のようになります

   QString k;
   k = "CRAZYYYQT";
   char ab[16];
   sprintf(ab,"%s",(const char *)((QByteArray)(k.toLatin1()).data()) );
   sprintf(ab,"%s",(const char *)((QByteArray)(k.toStdString()).data()));  
   sprintf(ab,"%s",(const char *)k.toStdString().c_str()  );
   qDebug()<<"--->"<<ab<<"<---";

Cスタイルのキャストを使用することを忘れてください。
kyb 2017

2

文字列に非ASCII文字が含まれている場合-次の方法で行うことをお勧めします:( s.toUtf8().data()またはs->toUtf8().data()


0

これは、std :: vectorを中間コンテナーとして使用する実行可能な方法です。

QString dataSrc("FooBar");
QString databa = dataSrc.toUtf8();
std::vector<char> data(databa.begin(), databa.end());
char* pDataChar = data.data();

0

Qtは最も単純なAPIを提供します

const char *qPrintable(const QString &str) and const char *qUtf8Printable(const QString &str)

非constデータポインターが必要な場合

str.toLocal8Bit().data() or str.toUtf8().data()
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.