QByteArray to QString to std::stringstream doesn't work - c++

anyone know why
QString Lulu ( data ); //data is a QByteArry ( from a QNetworkrequest )
std::stringstream streamedJson ;
// QString Lulu ( data.data() );
qDebug()<< "Lulu:" << Lulu; // here it views the right string
streamedJson << Lulu.toStdString();
qDebug() << "streamedJson: "<< streamedJson ; // here it views 0x7fffc9d46568
doesn't works ?
why it dont view the String here ?
finally i would parse it and give the parsed string out
boost::property_tree::ptree propertyTree;
try
{
boost::property_tree::json_parser::read_json(streamedJson, propertyTree);
}
catch(boost::property_tree::json_parser::json_parser_error& ex)
{
qDebug() << "ex: "<< ex.what(); // this and Lulu views the same (unparsed) string
qDebug ("propertyree error");
}
at the moment it only views "propertyree error". but it should print the parsed String in my console

std::stringstream cannot be directly used with QDebug::operator<<. You can explicitly convert it to QString. For example,
qDebug() << "streamedJson: " << QString::fromStdString(streamedJson.str());
The streamedJson.str() returns an std::string, and then converted to QString using QString::fromStdString.
Your program prints 0x7fffc9d46568 probably because the streamedJson is converted to a qDebug-printable object implicitly. Or maybe there is an operator<< function somewhere in your program that takes std::stringstream as input.

Try initialization of the QString variable as explained below and try putting the value into a std::string variable before pushing it into the std::stringstream.
QString Lulu = QString(data);
std::stringstream streamedJson ;
std::string strLulu = Lulu.toStdString();
streamedJson << strLulu;
qDebug() << "streamedJson: "<< streamedJson;
Hope this helps.

Class QString has function std::string toStdString() const. Maybe you should use it this way:
streamedJson << Lulu.toStdString();
If it will not work you can try
streamedJson << Lulu.toStdString().c_str();
If it will not work too we would find another possible solution. Good luck!
EDIT:
I've read several documents and I guess I've solved your problem. Class std::stringstream has inner representation of string. In order to get std::string from this class you should use its function str():
http://www.cplusplus.com/reference/sstream/stringstream/str/
Then your code should be looking like this:
string myString = streamedJson.str();
std::cout << myString;
I believe it will work.

Related

QTextStream write data in file

I'm learning QtCreator and having troubles writing data in file. Here's some code :
char *str;
int i = 1;
QFile outFile("path/to/file/out.txt");
outFile.open(QIODevice::ReadWrite);
QTextStream out(&outFile);
while (i < rows * 2) {
str = dynamic_cast<QLineEdit *>(this->getItem(i))->text().toLocal8Bit().data();
std::cout << str << std::endl;
out << str << "\n";
i += 2;
}
getItem returns a QWidget * from a QFormLayout filled with QLineEdit (that explains the dynamic cast). Anyway, when I pass str into std::cout it works fine, the data is printed, but when I pass str into out, it writes only the first char of str in the file.
I don't get what I'm doing wrong, I really would appreciate any tips.
This line is a problem: str = dynamic_cast<QLineEdit *>(this->getItem(i))->text().toLocal8Bit().data();
dynamic_cast<QLineEdit *>(this->getItem(i))-> is OK
->text() creates a temporary QString
.toLocal8Bit() creates a temporary QByteArray
.data() returns a pointer to the internal data of the QByteArray
As soon as the line is passed the QByteArray will be destroyed and you have a dangling pointer. str points to invalid data.
Everything you do with this pointer afterwards (except letting it point to somewhere else) is undefined behaviour.
Try to use something like this:
int i = 1;
QFile outFile("path/to/file/out.txt");
outFile.open(QIODevice::ReadWrite);
QTextStream out(&outFile);
while (i < rows * 2)
{
QLineEdit* lineEdit = dynamic_cast<QLineEdit *>(this->getItem(i));
if (lineEdit)
{
QByteArray str = lineEdit->text().toLocal8Bit();
std::cout << str.data() << std::endl;
out << str.data() << "\n";
i += 2;
}
else
{
std::cerr << "Item at " << i << " is no QLineEdit*" << std::endl;
}
}
out.close();
Also please check whether QFile is actually open and whether QTextStream reports some errors when writing.

String stream comes up empty [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 7 years ago.
I've been trying to append an integer to a string, and I've tried several solutions here, including:
std::stringstream ss;
ss << gvHours << "\'" << gvMinutes << "\"" << gvSeconds << ":" << gvTicks;
std::string output(ss.str());
return output.c_str();
and
std::stringstream ss;
std::string output = "";
ss << gvHours << "\'" << gvMinutes << "\"" << gvSeconds << ":" << gvTicks;
output = ss.str();
return output.c_str();
The first one gives me an empty string, and the second gives me an unreadable character that Notepad++ displays as "SOH" in a black box. Does anyone have any idea what I'm doing wrong?
Yes, this part
return output.c_str();
is broken.
When you take c_str() from a std::string, you are just getting a c-style pointer to the contents of that string. But you are not getting ownership of the data underlying that string. As soon as you return from the function, that stringstream and string are destroyed (as they are local variables) and the c_str() is a dangling pointer. So the whole thing is undefined behavior.
I fixed it. Here's the code I got that works:
std::stringstream ss;
std::string output;
ss << gvHours << "\'" << gvMinutes << "\"" << gvSeconds << ":" << gvTicks;
output = ss.str();
return output;
And in the function where it was needed:
fprintf(gvLog, ">: %s\n", timeString().c_str());

Stock bytes in QVariantMap

I'm getting the bytes data from a QImage in a QByteArray and i want to write the datas from the QByteArray in a QVariantMap, but after stocking the bytes, the bytes are changed and the image is not valid...
I tried to stock the QByteArray directly but the thing is i'm going to receive QVariantMap (as a JSON) from Windows phone, android and iOS. And the QByteArray will not exist on those OS so i doubt that the .toByteArray function will work...
Here is an example of what i tried using a QString but the bytes are changed when the QString is filled...
QFile tmp("default_profile.jpg");
tmp.open(QIODevice::ReadOnly);
if (tmp.exists() == true)
{
QByteArray tab;
tab = tmp.read(tmp.size());
int i = 0;
char *data = tab.data();
QString str;
while (i != tmp.size())
{
if (i < 100)
qDebug() << "AVANT = " << " i = " << i << "[" << *data + '0' << "]";
i++;
str.append(*data);
++data;
}
QVariantMap *tmp = new QVariantMap();
(*tmp)["name"] = "test.jpg";
(*tmp)["data"] = str;
(*tmp)["size"] = tab.size();
(*tmp)["type"] = "PhonePic";
this->fileReceived("", "", tmp);
}
And here is the fileReceived:
QFile tmp((*src)["name"].toString());
tmp.open(QIODevice::ReadWrite | QIODevice::Truncate);
char *test = (char *)malloc((*src)["size"].toInt());
QString str;
str = (*src)["data"].toString();
int i = 0;
char *data = const_cast<char *>(str.toStdString().c_str());
while (i != 8143)
{
if (i < 100)
qDebug() << "AFTER = " << " i = " << i << "[" << *data + '0' << "]";
i++;
++data;
}
qDebug() << tmp.write(str.toStdString().c_str(), (*src)["size"].toInt());
The size of the "AFTER" QString is good, but the values are not good...
Does someone know what i'm doing wrong ? or maybe have an idea of how i get do it ?
Thanks for people who will try to help me.
You load binary data into a QByteArray. Then you append the data in this QByteArray byte by byte to a QString, which converts every single byte into unicode. And last but not least you you just try to cast this back into raw data? No way. So pointing you to what you are doing wrong was easy.
Helping you is much more difficult. Why do you think you can use QString, when QByteArray is not available? When QVariantMap is available, then you have a complete Qt. So using QByteArray should not be a problem. But I must admit, I don't fully understand your post and your problem, so I might overlook something.
You can send a QImage directly in a QVariant or QVariantMap. How the particular json library that you use will deal with the json-to-Qt interface, that's a whole another story.
Since QVariant is in Qt Core and not Qt Gui, you have to use QVariant::value() or the qvariant_cast() template function when working with GUI types such as QImage.

TTF_RenderText with integer

Is it posible to use the TTF_Render_TextSolid controlled with one integer? I try to use stringstreams like this:
stringstream _minutes;
stringstream _seconds;
stringstream _miliseconds;
_minutes << minutes << ":";
_seconds << seconds << ":";
_miliseconds << miliseconds;
(the variable minutes, seconds and miliseconds was already scoped)
But when I compile this, compile well but then, I run and this says : core dumped. So the error is in the memory part. mmh what happens?
Doing something along the lines of:
stringstream ss;
ss << minutes << ":" << seconds << ":" << miliseconds;
const string str = ss.str();
SDL_Surface* surf = TTF_RenderText_Solid(textFont, str.c_str(), textColor);
Should work without a problem.
Do not store the const char* that comes out of it though! As soon as your str goes out of scope, your const char* won't be valid anymore.

Visual Studio - How can I output debug information to debug window?

OutputDebugString method seems rather tedious and seems only limited to string and not polymorphic. What should I do if I want to output some integer or other variable type ?
Hope some function like std::cout exists !
I'm pretty sure you could write a streambuf implementation that outputs via OutputDebugString. It's not entirely straight forward, but possible.
It would certainly be possible to use something like this:
std::stringstream ss;
ss << something << another << variable << here << endl;
OutputDebugString(ss.str().c_str());
You may need to use MultiByteToWideChar to convert the c_str() to a wide string, if you have "UNICODE" enabled in your project.
Since the accepted answer doesn't really provide a working version:
If you're not concerned with unicode - though you probably should be if you're shipping anything, I'll assume you won't be shipping it with OutputDebugString included - you can use one of the other versions, such as OutputDebugStringA:
stringstream ss;
ss << "Hello World\n";
OutputDebugStringA(ss.str().c_str());
Use a class like this:
class stringbuilder
{
public:
stringbuilder()
{
}
template< class T >
stringbuilder& operator << ( const T& val )
{
os << val;
return *this;
}
operator std::string () const
{
return os.str();
}
private:
std::ostringstream os;
};
And pass the output to a wrapper around OutputDebugString (or anything else that logs strings only):
void MyOutputDebugString( const std::string& s )
{
::OutputDebugString( s.c_str() );
}
//usage:
MyOutputDebugString( stringbuilder() << "integer " << 5 );
A macro for Mats Petersson's answer, with unicode support:
#define odslog(msg) { std::wstringstream ss; ss << msg; OutputDebugStringW(ss.str().c_str()); }
Usage:
odslog("A string " << 123123 << L"A wide string" << "\n");
In addition, if you use MFC then you can use TRACE TRACE1 TRACE2 ... macros that work like printf to the debug output.