So I've been using SFML lately and I was wondering how I could "add" to sf::String.
For example:
sf::String exampleText;
exampleText.SetText("I say: ");
exampleText += "Blah";
Result: "I say: Blah"
sf::string doesn't offer an append method which makes sense as it's intended to be a class for the graphical display of text rather than a traditional string class.
So you have to perform your string manipulation/append operations behind the scenes using your usual char array/string/stringstream classes and then call sf::string::SetText to update it.
sf::String exampleText;
exampleText.SetText("I say: ");
std::wstring toAppend(L"Blah");
exampleText.SetText(exampleText.GetUnicodeText() + toAppend);
Try that. I have never used sf though.
GetUnicodeText returns std::wstring. And by using the + it may work. Try it.
OR (now that I saw the sf docs better)
exampleText.SetText(exampleText.GetText() + "Blah");
GetText() returns std::string
SetText() Accepts both wstring and string
Related
I have a jsoncpp value that I want to serialize. The most straightforward way is like this:
Json::Value val; // population is left as an exercise for the reader
std::string str = Json::FastWriter().write(val);
The problem is that FastWriter is deprecated, and I can't tolerate compiler warnings. According to the less-than-intuitive documentation, I'm supposed to use StreamWriterBuilder instead:
Json::StreamWriterBuilder builder;
builder["commentStyle"] = "None";
builder["indentation"] = "";
std::unique_ptr<Json::StreamWriter> writer( builder.newStreamWriter() );
std::ostringstream os;
writer->write(val, &os);
std::string str = os.str();
Surely this can't be "better"? I'm assuming the fault lies with me and there is a straightforward way to perform minimal serialization (without extraneous whitespace).
This shows a slightly more compact form (although it appears to simply wrap the above in a function call).
Json::StreamWriterBuilder builder;
builder["indentation"] = ""; // assume default for comments is None
std::string str = Json::writeString(builder, val);
Is that the right way now?
You're doing it the right way.
The second example is just a shorthand for the first — in both instances, a builder dynamically allocates a writer, the writer is used and then the writer is freed.
Why the older FastWriter implementation was deprecated I could not say. Personally I miss it a bit. But a factory is more flexible and permits different implementations slotting into the same suite of functions. You'd have to ask the JsonCpp developers whether that was the core of their decision.
If you always want to write with the same settings (e.g. your ["indentation"] = ""), you can supply a Json::Value representing the settings to Json::StreamWriterBuilder::setDefault, then writing strings doesn't need to name Json::StreamWriterBuilder again (but does default construct one)
Startup
Json::Value streamWriterSettings{R"({ "indentation" : "" })"};
Json::StreamWriterBuilder::setDefault(&streamWriterSettings);
Usage
std::string str = Json::writeString({}, val);
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.
Hello everyone I am trying to get to know pointers better and I stumbled into a Qt type change. I have made a QString array and gave the pointer to the array to a method. But when I try to use a QString functions it give a error and says that it is a QCharRef which does not have the member function isEmpty().
The code:
QString data_array[2][3] =
{
{"11:28:8","Room 1","Presence detected"},
{"11:38:8","Room 1","No presence"}
}
bool method(QString *_data_array)
{
QString *data_array = _data_array;
return data_array[0][1].isEmpty(); /* changed to QCharRef */
}
My question is why does this happen and how can I prevent it or change it?
The reason for which you are getting QCharRef is due to how QString is built. The [] operator returns one character from a QString (QString is built up from QChars, much like strings in C/C++ are character arrays). From the Qt documentation:
The return value is of type QCharRef, a helper class for QString. When you get an object of type QCharRef, you can use it as if it were a QChar &. If you assign to it, the assignment will apply to the character in the QString from which you got the reference.
So what that means for you is that when you use the lovely square bracket operators, you are no longer using a QString, you are using a QChar reference.
As for how to change it, QChar's isNull() seems like it would fit your uses. so instead try return data_array[0][1].isNull(); and that should work.
I would also look into QStringList if you're doing things with lists of strings
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!
I'm currently working on a larger project, where the "logic" is implemented in standard C++ with all strings being handled with std::wstring and the UI part is implemented using Qt and thus necessarily QString (Bonus question: is this true?).
What is the best way to connect those two worlds?
I know I can use something like
std::wstring wideString;
QString qtString = QString::fromStdWString(wideString);
but I'm wondering if there is a nicer way with less typing involved. A user defined operator came to my mind, but I'm not experienced enough to tackle that on my own.
Would be glad if anyone could point me in the right direction.
It's a good idea to use QString::fromStdWString but (!!!) if Qt was compiled with exactly the same STL headers as your project. If not - you can get a lot of fun, catching a bug.
If you don't sure that both STL headers are the same use QString::fromWCharArray:
std::wstring wideString;
QString qtString = QString::fromWCharArray( wideString.c_str() );
Update: answering to #juzzlin:
Lets imagine that Qt was build with the STL containing the following std::wstring:
class wstring { // I know, that there's no such class, but I'm shure you'll understand what I want to say
wchar_t * m_ptr;
size_t m_length;
...
};
and you have the STL containing the following std::wstring:
class wstring {
wchar_t * m_ptr;
wchar_t * m_the_end;
...
};
If you'll give your std::wstring to Qt, it will interpret m_the_end pointer as the length of the string, and
you can get a lot of fun, catching a bug
I think a user defined conversion is what you're looking for, and from what I can gather, it should look something like this:
class foo
{
public:
operator QString(std::wstring& ws)
{
return QString::fromStdWString(ws);
}
}
maybe make a inline function QString toQString(std::wstring string) to make it 'less to type' ...
but to be honest ... thats not the big effort at all to write it from time to time ;)
soo long zai