Loss of non ascii characters from QString to char * - c++

I have a QString with non ascii characters . I am passing this QString to another process . However when I debug the receiving process the argv arguments do not receive a correct string that was intended from the source . My pseudo code would be
process.start( proc, QStringList() << "-a" <<param );
process.waitForFinished(m_timeout);
Here param is the QString that contains the non ascii text

I solved the problem with the following code
LPWSTR *szArglist;
int argC;
szArglist = CommandLineToArgvW(GetCommandLineW(),&argC);
if(NULL==szArglist) {
throw;
}
QString qstrConvertFile = QString::fromUtf16((const ushort*)(szArglist[4]));

Related

How to add arabic characters in a middle of a file using C++?

I am building an application that will need to add arabic characters in the middle of english file, I build the function as follow:
int main(void) {
std::ifstream mySource("Test2.txt", std::ios::out);
std::filebuf* pbuf = mySource.rdbuf();
std::size_t size = pbuf->pubseekoff(0, mySource.end, mySource.in);
pbuf->pubseekpos(0, mySource.in);
char* buffer = new char[size];
pbuf->sgetn(buffer, size);
mySource.close();
wchar_t* wbuffer = new wchar_t[size];
wbuffer = GetWC(buffer);
setlocale(LC_ALL, "en_GB.utf8");
wbuffer[79] = {0x0041};
std::wofstream outdata2;
outdata2.open("Test6.xml"); // opens the file
outdata2 << wbuffer;
outdata2.close();
return 0;
}
for a text file as follows:
$ cat dat/rbgtst.txt
400,280: (234,163,097) #EAA361
400,300: (000,000,000) #000000
400,320: (064,101,160) #4065A0
400,340: (220,194,110) #DCC26E
and expecting to receive
$ cat dat/rbgtst.txt
400,280: (234,163,097) #EAA361
400,300: (000,000,000) #A00000
400,320: (064,101,160) #4065A0
400,340: (220,194,110) #DCC26E
although when I put the arabic letter ASCII like:
...
wbuffer[79] = {0x0628};
...
I receive the following:
$ cat dat/rbgtst.txt
400,280: (234,163,097) #EAA361
400,300: (000,000,000) #
don't know why?!
The function you are using for output will terminate at a null character. Instead you should use ostream::write for the output
outdata2.write(wbuffer, size);
Also since you are doing binary I/O all your files should be opened with the std::ios::binary bit set.
std::ifstream mySource("Test2.txt", std::ios::out|std::ios::binary);
etc.

Convert char to bytearray with hex-data 0x31

I work with QT Creator (MinGW 5.3.0 C++, Windows) and want to write some serial-connection hex-data.
I found a way but there is something wrong. Only one hex-data he convert wrong.
I hope my code will help to understand.
static const unsigned char mytestUC[] = {0x04,0x31,0xD2,0x01, 0xA1};
enum { NBYTES = sizeof(mytestUC) };
const char *mytest = reinterpret_cast<const char*>(mytestUC);
QByteArray testdata = QByteArray::fromRawData(mytest, sizeof(mytest)+1);
qDebug()<<"testdata "<<testdata;
I would think the output should be:
testdata "\x04\31\xD2\x01\xA1"
But in real it looks like this:
testdata "\x04""1\xD2\x01\xA1"
I tried some other way to write my hex-data directly in the QBytearray with append.
testdata .append((char) 0x04);
testdata .append((char) 0x31);
testdata .append((char) 0xD2);
testdata .append((char) 0x01);
testdata .append((char) 0xA1);
Why does the Programm convert only the the 0x31 in the wrong way and how can I make it better?
Is there some easier way to write hex-data in QBytearray?
Whe you print the QByteArray it tries to convert all characters to ASCII, but the numerical value is the 0x31. In serial port data is send in binary, so character '1' will be send as 0x31. To see data in hexa from a QByteArray you can use the function toHex(), example:
QByteArray ba;
ba.append((char) 0x31);
ba.append((char) 0x32);
ba.append((char) 0x33);
ba.append((char) 0x34);
qDebug() << "char: " << ba;
qDebug() << "hexa: " << ba.toHex();
The output will be:
char: "1234"
hexa: "31323334"
There is a function qint64 QIODevice::write(const QByteArray &byteArray) in QSerialPort class.

Embarcadero: How to use TBase64Encoding's EncodeBytesToString method

I am attempting to convert an array of bytes to a base64 encoded String using the EncodeBytesToString method of the TBase64Encoding class. The documentation for EncodeBytesToString states:
"Returns a string with the input array of bytes encoded up to the specified number of bytes."
Therefore, I attempted to encode my byte array like so:
TFile * File = new TFile();
TBytes Bytes = File->ReadAllBytes("D:\\Sample.pdf");
TBase64Encoding * Encoder = new TBase64Encoding();
String EncodedBytes = Encoder->EncodeBytesToString(Bytes, Bytes.Length);
However, I get the following error:
E2285 Could not find a match for 'TNetEncoding::EncodeBytesToString(TByteDynArray,int)'
I am confused, as the documentation seems to say that I should pass a TBytes object and an int into this function. What am I missing here?
Try this:
//------------------------------------------------------------------------------
String __fastcall BytesToBase64( TByteDynArray _ArrayIn )
{
TBase64Encoding * Encoding = new TBase64Encoding( 64, '\n' );
String Result = Encoding->EncodeBytesToString( &_ArrayIn[0], _ArrayIn.High );
delete Encoding;
return Result;
}
//------------------------------------------------------------------------------
TByteDynArray __fastcall Base64ToBytes( String _64String )
{
TByteDynArray My64Bytes = _64String.BytesOf();
return TNetEncoding::Base64->Decode(&My64Bytes[0], My64Bytes.High);
}
//------------------------------------------------------------------------------
System.NetEncoding.TNetEncoding provides the static property Base64 to retrieve an instance of TNetEncoding for base64 encoding.
So this will also work:
String __fastcall BytesToBase64(TByteDynArray _ArrayIn)
{
return TNetEncoding::Base64->EncodeBytesToString(&_ArrayIn[0], _ArrayIn.High);
}

unpredictable runtime behavior while converting QString to const char*

I have these following codes set up-
class ID3{
const char* fileName;
TagLib::FileRef *file;
public:
ID3(const char *);
QImage* artwork();
}
ID3::ID3(const char* fileNameStr){
this->fileName = fileNameStr;
this->file = new TagLib::FileRef(fileNameStr);
qDebug()<<fileNameStr; //OUTPUT 2
}
QImage* ID3::artwork(){
QString str = QString::fromLocal8Bit(this->fileName);
qDebug()<<str; //OUTPUT 3
//MORE CODES-------
}
const char * QstrTocChar(QString str){
QByteArray ba = str.toLocal8Bit();
qDebug()<<ba.constData(); //OUTPUT 1
return ba.constData();
}
int main(int argc, char *argv[]){
.
.
.
QString fileName = "C:/Qt/Qt5.0.2/Projects/taglib_test/music files/Muse_-_Madness.mp3";
file = new ID3(QstrTocChar(fileName));
QImage *image = file->artwork();
}
Now when I run the program, I get these strange outputs
OUTPUT 1
C:/Qt/Qt5.0.2/Projects/taglib_test/music files/Muse_-_Madness.mp3
OUTPUT 2
????p???e'2/
OUTPUT 3
"°í³àpµ˜Æe'2/"
Not sure about OUTPUT 2 but I expect OUTPUT 3 to be same as OUTPUT 1. I am a Qt newbie. Would really appreciate advice/help in understanding, these strange character encoding issues and how to get OUTPUT 3 fixed.
Thanks!
ba.constantData() is returning a pointer to data which will be invalid when QstrToChar finishes executing (the 8-bit converted QByteArray), when QstrToChar completes, all you have left is free'd junk.
What if you just did:
file = new ID3(fileName.toLocal8Bit().constData());
in your main routine?
Actually, you still probably need to keep your own copy of this data in your private ID3 char *, since it can go away with the destruction of these temporaries.
Your code should be this, instead:
class ID3{
std::string fileName;
std::smart_ptr<TagLib::FileRef> file;
public:
ID3(std::string);
QImage* artwork();
}
ID3::ID3(std::string fileNameStr) {
this->fileName = fileNameStr;
this->file.reset(new TagLib::FileRef(fileNameStr));
qDebug()<<fileNameStr; //OUTPUT 2
}
QImage* ID3::artwork(){
QString str = QString::fromLocal8Bit(this->fileName);
qDebug()<<str; //OUTPUT 3
//MORE CODES-------
}
std::string QstrToCppString(QString str){
QByteArray ba = str.toLocal8Bit();
qDebug()<<ba.constData(); //OUTPUT 1
return std::string(ba.constData());
}
int main(int argc, char *argv[]){
.
.
.
QString fileName = "C:/Qt/Qt5.0.2/Projects/taglib_test/music files/Muse_-_Madness.mp3";
file = new ID3(QstrToCppString(fileName));
QImage *image = file->artwork();
}
Notice that I've wrapped your TagLib::FileRef in a smart_ptr as well, since you are new-ing it, you'll need to manage the memory. An alternative would be to write a proper destructor for your ID3 class. You're definitely leaking these currently (unless you just didn't share your destructor code).

How can i convert entity character(Escape character) to HTML in QT?

I want to convert entity character(Escape character) to HTML in QT, please help me....
i.e: I want to replace " with ", > with >
=====This is my code that not worked====
QString MyApp::ReplaceString(const QString Data, const QString &Before, const QString &After)
{
QString Result = Data;
Result.replace(Before, After, Qt::CaseInsensitive);
return Result;
}
========
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
QByteArray data=pReply->readAll();
QString str = codec->toUnicode((const char *)data);
str = Qt::escape(str);
str = ReplaceString(str, """, "\"");
str = ReplaceString(str,">", ">");
I'm not sure I understand what you want, just guessing. You can use QTextDocument. Try something like this:
QTextDocument text;
text.setHtml("<>"");
QString plain = text.toPlainText();
qDebug("%s.", qPrintable(plain));
Remember that QTextDocument needs the gui module.
I think this will solve your problem.
QString escaped=
QString(myhtml).replace("&","&").replace(">",">").replace("<","<");
Test escape() function:
QString plain = "#include <QtCore>"
QString html = Qt::escape(plain);
// html == "#include <QtCore>"
and convertFromPlainText() function:
QString Qt::convertFromPlainText ( const QString & plain, WhiteSpaceMode mode = WhiteSpacePre )
Hello to convert non ASCII character to &#XXX; (where XXX is a number):
/***************************************************************************//*!
* #brief Encode all non ASCII characters into &#...;
* #param[in] src Text to analyze
* #param[in,opt] force Force the characters "list" to be converted.
* #return ASCII text compatible.
*
* #note Original code: http://www.qtforum.org/article/3891/text-encoding.html
*
* #warning Do not forget to use QString::fromUtf8()
*/
QString encodeEntities( const QString& src, const QString& force=QString() )
{
QString tmp(src);
uint len = tmp.length();
uint i = 0;
while( i<len )
{
if( tmp[i].unicode() > 128 || force.contains(tmp[i]) ){
QString rp = "&#"+QString::number(tmp[i].unicode())+";";
tmp.replace(i,1,rp);
len += rp.length()-1;
i += rp.length();
}else{
++i;
}
}
return tmp;
}
/***************************************************************************//*!
* #brief Allows decode &#...; into UNICODE (utf8) character.
* #param[in] src Text to analyze
* #return UNICODE (utf8) text.
*
* #note Do not forget to include QRegExp
*/
QString decodeEntities( const QString& src )
{
QString ret(src);
QRegExp re("&#([0-9]+);");
re.setMinimal(true);
int pos = 0;
while( (pos = re.indexIn(src, pos)) != -1 )
{
ret = ret.replace(re.cap(0), QChar(re.cap(1).toInt(0,10)));
pos += re.matchedLength();
}
return ret;
}
Basic usage:
qDebug() << encodeEntities(QString::fromUtf8("éà#<>hello the world €"),QString("<>"));
// Will print: éà#<>hello the world €
qDebug() << decodeEntities("aßéplopéàçê€");
// Will print: hello world