how to convert std::string to QString - c++

I have a problem:
std::string str("character/test/raw");
qDebug() << QString::fromStdString(str);
and the output is:
"]AIIIIIIIIIIIIIIIIIIIIIIIIIIIII"
I think the problem is in encoding but don't know how to fix it. Please help

string to const char*, then to qstring
std::string str("character/test/raw");
QString qstr(str.c_str());
qDebug() << qstr;

Is your QT compiled with STL compatible enabled option?
Maybe you can use fromUtf8 or one of other static functions of QString.

Related

How to convert JUCE string to STD::string

Hello is there any way to convert a JUCE string to a std::string? I cannot seem to figure out how to do it in any way.
string GetGate() { return (to_string(Gate.char)); };
juce::String Gate = "A1";
Seems pretty simple:
Gate.toStdString()
String::toStdString
According to the JUCE manual, there is the method std::string juce::String::toStdString() const.

Qt "tcpserver->write(string)"

i have a very simple question here, How can i send a string with
tcpserver->write(string);
I tried:
tcpserver->write("string")
and it works, but if i want to input a string in there, i get a "no matching function to call to 'QtcpSocket::write(QString)'"
error,
so i tried converting the string to "data" and then send it, but i got a ton of errors...
And my question is: How can i easly send a string thru my tcpserver?
(I should also mention, that i am very new to programming)
You need to convert string to QByteArray, for example:
tcpserver->write(string.toLocal8Bit());
tcpserver->write(string.toUtf8());
Try tcpserver->write((const char *)string.data(), string.length()*sizeof(QChar));
QTcpSocket has 3 overloads for write () function
qint64 write (const char *data);
qint64 write (const char *data, qint64 len);
qint64 write (const QByteArray &data);
So Convert QString to any of them. Just try
tcpserver->write (string.toLatin1 ());

Qt doesn't read a string properly in Linux

Well, I'll try to explain.
I have a Class named Calc that evaluate a string or const char* numeric expresion, like "2*(3/5)" or similars.
Now I am trying to build a calculator in Qt, using those class to evaluate the input of a QLineEdit.
The class works like that:
Calc(const std::string &sExpresion);
Calc(const char* cExpresion);
and
void anadirExpresion(const std::string &sExpresion);
void anadirExpresion(const char* cExpresion);
And I try to use it in Qt like that:
void Calculadora::evaluar()
{
QLocale locale;
QByteArray cadena = ui->pantalla->text().toLocal8Bit();
const char* expresionAEvaluar = cadena.data();
qDebug()<<"Cadena a evaluar: "<<cadena;
std::cout<<"Cadena: "<<expresionAEvaluar<<std::endl;
evaluador.anadirExpresion(expresionAEvaluar); //evaluador is the class Calc instance
float resultado=evaluador.CalcularExpresion();
qDebug()<<"Resultado: "<<resultado;
ui->pantalla->setText(QString::number(resultado));
}
This is a try to use the Class with a const char* expression
And this is the try with a std::string expression
void Calculadora::evaluar()
{
//std::string cadena = ui->pantalla->text().toStdString();
//qDebug()<<"Cadena a evaluar: "<<ui->pantalla->text();
std::cout<<"Cadena: "<<ui->pantalla->text().toStdString()<<std::endl;
evaluador.anadirExpresion(ui->pantalla->text().toStdString());
float resultado=evaluador.CalcularExpresion();
qDebug()<<"Resultado: "<<resultado;
ui->pantalla->setText(QString::number(resultado));
}
the problem is that I lose the data after "." character.
If I have "2.3" the calculator perfoms "2"
Furthermore, this problem is only in Linux, because in Qt under Windows it runs properly.
And it works fine in console mode under Linux and Windows.
Also, the output in Qt console of qDebug() and std::cout show a properly string.
Suggestions?
Sorry for my poor english and thanks in advanced.
***Updating:
Definitively, I think that this error is because the function atof() compiled under Qt under linux doesn't works properly. I can sound senseless but, I was following the "2.5" value to looking for where it was changed, and it changed after that (into a member function of Calc)
EP[t].OP.operando=atof(aux);
std::cout<<"changed? "<<aux<<std::endl;
std::cout<<"changed: "<<EP[t].OP.operando<<std::endl;
Under console, EP[t].OP.operando value is "2.5" after atof() function.
In Windows too.
But in Linux, I get "2" value.
Now I have another try:
char cad[]="2.5";
EP[t].OP.operando=atof(cad);
std::cout<<"changed: "<<EP[t].OP.operando<<std::endl;
Under console, EP[t].OP.operando value = 2.5 , but under Qt is 2
Maybe a bug? Anyone to confirm that?
Thank you
I'm suspecting that locale kicks in. Probably your system locale is some European language where decimal separator is a comma, not a dot.
To verify my suspensions you can:
try use comma (,) as decimal separator during testing or
temporarily change your system locale to US (or other language where dot is decimal separator) and then rerun your software.
you can print in logs value of this variable (see documentation):
qDebug() << "Decimal separator: " << localeconv()->decimal_point;
If I'm right then this is not a bug but a feature :).
I wrote some test application to verify my suspensions, and I was right, I wrote this slot:
void MainWindow::processText(const QString &txt)
{
std::string s = txt.toStdString();
std::stringstream stream(s);
double x;
x = std::atof(s.c_str());
emit atofResultString(QString::number(x));
if (stream >> x) {
emit stdstreamResult(QString::number(x));
}
}
I've tested this on Ubuntu 12.04 with Polish locale set. Result is that atof takes system locale into account.
Can you please tell whether the function evaluar() works fine when you have done:
QByteArray cadena = ui->pantalla->text().toLocal8Bit();
const char* expresionAEvaluar = cadena.data();
If it is working then I would suggest that you use same function for std::string also.
This can be done using std::string::c_str().
So you can write ui->pantalla->text().toStdString().c_str().
However, converting between QString and const char* works best when you use the toLocal8bit() function as you have already done once.
Thank you for you answer.
I tried to changed the environment of my program, adding a QLocale pointer and making that in the constuctor:
valor = new QLocale (QLocale::C,QLocale::UnitedStates);//valor is a QLocale pointer
I have changed this value for my country in explicit way:
valor = new QLocale (QLocale::Spanish,QLocale::Spain);
Also I tried to change between "." and "," for decimal points in both environment (Spain and USA)
After another headaches, you gave me the idea, for getting the float valor from a stringstream object, and not using atof() function.
std::stringstream ss(aux);
ss>>EP[t].OP.operando;
And now it works fine.
Actually I haven't solve the problem (the Locale problem) but I get around that for fix it.
Must I mark the post like SOLVED?
Thank you again!

Conflict type QString and std::string in a parameter

I think my problem is simple to solve, but due to my lack of knowledge, I can't find the answer.
I have this structure :
struct variableOutil {
std::string Nom;
float Valeur;
std::string Module;
std::string Unite;
std::string Format;
std::string Accesibilite;
std::string Description ;
};
And the problem come from here :
struct variableOutil ToleranceTensionAvion;
ToleranceTensionAvion.Nom = "ToleranceTensionAvion";
QTableWidgetItem* newItem = new QTableWidgetItem();
newItem->setText(ToleranceTensionAvion.Nom);
this->ui->variableTableWidget->setItem(1,0,newItem);
I've got this error :
No matching function for call to 'QTableWidgetItem::setText(std::string&)
The problem is that setText need a const QString &text and tell me that I put in parameter a std::string& , I don't understand why does the type don't match, and what's the difference, after all, this is a simple String.
Thank you.
You should convert std::string to QString by :
newItem->setText(QString::fromStdString(ToleranceTensionAvion.Nom));
Or
newItem->setText(QString::fromUtf8(ToleranceTensionAvion.Nom.c_str());
Try:
newItem->setText(QString::fromUtf8(ToleranceTensionAvion.Nom.c_str());
QString allows only Unicode.
std::string just stores the bytes and does not work with encodings. The best way to store your texts would probably be UTF-8 encoding.
They are completely different classes, and std::stringcan not be used in place of QString. You can build QString fromstd::string and pass it.
QString s =QString::fromStdString(ToleranceTensionAvion.Nom);
newItem->setText(s);
just use c._str() on your std::string and it will work for anything that expects a QString

Qt + protobuf, types?

I would like to dip into Google's protocol buffers in Qt development, but I am having trouble figuring out how to incorporate them best.
Ultimately, I want to send with QUdpSocket and QTcpSocket using protocol buffers.
What is the best method for going between a protocol buffer message to sending the data over a socket (QByteArray) and then back again at the other side?
Creating a QByteArray from a protobuf object:
Person person; // a protobuf object
person.set_id(123);
person.set_name("Bob");
person.set_email("bob#example.com");
std::ostringstream out;
person.SerializeToOstream(&out);
QByteArray byteArray(out.str().c_str());
sendSerializedPersonOverQTcpSocket(byteArray);
Reading back a protobuf object from a QByteArray:
QByteArray byteArray = readSerializedPersonFromQTcpSocket();
Person person;
if (!person.ParseFromArray(byteArray, byteArray.size())) {
std::cerr << "Failed to parse person.pb." << std::endl;
}
Instead of:
std::ostringstream out;
person.SerializeToOstream(&out);
QByteArray byteArray(out.str().c_str());
you can also write:
QByteArray byteArray(person.SerializeAsString().c_str());
EDIT: Above two gives the same result, but I'm not sure wether it's correct. This one seems to work better:
QByteArray byteArray(QString::fromStdString(person.SerializeAsString()));
EDIT2: OK, now I know how it works: first two ways are wrong if there are \0 char in serialization - everything after it it's then lost. To correct it one can write:
QByteArray byteArray(person.SerializeAsString().c_str(), person.ByteSize());
Using the code below is really dangerous
std::ostringstream out;
person.SerializeToOstream(&out);
QByteArray byteArray(out.str().c_str());
sendSerializedPersonOverQTcpSocket(byteArray);
You can find a good explanation here In protobuf-c, can optional uint32 variable have value 0
A right way to create a QByteArray from a protobuf message is
QByteArray byteArray;
byteArray.resize(message.ByteSize());
message.SerializeToArray(byteArray.data(), byteArray.size());
#James: You can use ParseFromArray(), for example, as below: (Please note that ParseFromArray() is available only on proto-buf-lite versions of the libs).
void convertQByteArrayToUser(QByteArray& aByteArray)
{
com::your::name_space::User user;
if(!user.ParseFromArray(aByteArray.data(), aByteArray.size()))
{
//could not parse
}
else { //yayyyyy
if(user.has_userid())
{
//...
}
}
}