QString para conversão char *

93

Eu estava tentando converter um QString para o tipo char * pelos seguintes métodos, mas eles não parecem funcionar.

//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());

Você pode elaborar a possível falha desse método ou fornecer um método alternativo?

Mawia
fonte
Seu exemplo funciona bem para mim, onde está o problema?
Viesturs
3
Desculpe pelo meu inglês, mas por que não é certo usar essa abordagem? QString s("some"); printf(reinterpret_cast<char *>(s.data()));
Bartolo-otrit

Respostas:

114

Bem, o Qt FAQ diz:

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();
}

Então, talvez você esteja tendo outros problemas. Como exatamente isso não funciona?

Eli Bendersky
fonte
11
const char*e char*não são do mesmo tipo.
Lightness Races in Orbit
3
@LightnessRacesinOrbit: escrever no conteúdo do QString sem que ele saiba é uma ideia horrível, portanto, const char*é claro que é o que realmente pode ser obtido. O usuário está livre para copiar os dados para um buffer gravável.
Eli Bendersky
1
Eu concordo completamente. No entanto, a pergunta feita sobre char*, não char const*, e sua resposta simplesmente ignora esse fato sem mencionar.
Lightness Races in Orbit
4
@LightnessRacesinOrbit: às vezes, a melhor resposta é desfazer a pergunta. Em outras palavras, para apontar que não é pedir a coisa certa. Esta resposta foi aceita pelo autor da pergunta, então suponho que atingiu seu alvo
Eli Bendersky
2
parece que o FAQ foi atualizado para uso toLocal8Bit()?
Larry
50

Talvez

my_qstring.toStdString().c_str();

ou mais seguro, como Federico aponta:

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

Está longe de ser o ideal, mas fará o trabalho.

davidnr
fonte
3
Isso vai bagunçar os caracteres Unicode. Uma solução compatível com Unicode: stackoverflow.com/a/4644922/238387
jlstrecker
21
Este método é muito perigoso e não deve ser usado: toStdString()retorna um novo std::stringobjeto e então o ponteiro para os dados internos const char *é obtido. No entanto, o objeto string é destruído imediatamente após essa instrução, portanto, o ponteiro do resultado provavelmente não terá um endereço válido se você usá-lo em uma instrução subsequente.
RicoRico
@RicoRico Não é o método toStdString()que é perigoso; é o uso de ponteiros brutos. Ou, mais especificamente, o uso de ponteiros brutos de objetos cujos escopos não são bem compreendidos.
notlesh
Especificamente, os temporários de C ++ normalmente vivem até o final da instrução que os cria. Portanto, a primeira forma na resposta está ok se for usada in-line em uma chamada de função (assumindo que a função não armazena o ponteiro para uso futuro), mas não está ok se for atribuída a uma variável.
plugwash de
46

A maneira mais fácil de converter um QString em char * é qPrintable (const QString & str) , que é uma macro que se expande para str.toLocal8Bit().constData().

Robert
fonte
Por que esta não é uma resposta mais popular? Eu acabei de aprender sobre isso por acidente enquanto vasculhava o código-fonte do Qt, e é exatamente o que eles fazem.
Phlucious
6
@Phlucious, porque: 1) qPrintableretorna const char*não char*, str.toLocal8Bit().data()retornos char*. 2) O ponteiro para const char*torna - se inválido assim que você atinge um ponto-e-vírgula na instrução em que qPrintablefoi usado. Então const char* c_ptr = s.toLocal8Bit().constData();não faz sentido.
WindyFields de
1
@Phlucious, obrigado, você salva a vida :) todas as respostas mais votadas estão erradas, a questão é sobre char e estão retornando const char *
user889030
A qPrintablesaída é garantida como terminada em zero?
Giovanni Cerretani
@WindyFields - Como avisado na qPrintable()descrição: "O ponteiro char será inválido após a instrução em que qPrintable () é usado."
Jeremy
6

A resposta de David funciona bem se você estiver usando apenas para enviar para um arquivo ou exibir na tela, mas se uma função ou biblioteca requer um char * para análise, então este método funciona melhor:

// 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);
Alex
fonte
4

EDITADO

dessa forma também funciona

QString str ("Something");

char* ch = str.toStdString().C_str();
Shanks
fonte
Parece uma conversão diferente ( std::stringQString), não o que foi pedido.
Toby Speight
3

Sua string pode conter caracteres não Latin1, o que leva a dados indefinidos. Depende do que você quer dizer com "parece não funcionar".

Gregseth
fonte
2

a solução correta seria assim

   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<<"<---";
sam
fonte
Esqueça de usar fundição de estilo C.
kyb
2

Se sua string contém caracteres não ASCII - é melhor fazer desta forma: s.toUtf8().data()(ou s->toUtf8().data())

AlexDarkVoid
fonte
0

É uma maneira viável de usar std :: vector como um contêiner intermediário:

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

Qt fornece a API mais simples

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

Se você quiser um ponteiro de dados não constante, use

str.toLocal8Bit().data() or str.toUtf8().data()
user2042397
fonte