PDA

View Full Version : Qstring conversion UTF8



harleyskater
24th June 2010, 09:54
I am trying to convert a Qstring to UTF8 for a mysql query. I am getting the following error.

1>.\thewge.cpp(54) : error C2039: 'utf8' : is not a member of 'QString'
1> c:\qt\4.6.2\include\qtcore\../../src/corelib/tools/qstring.h(91) : see declaration of 'QString'
1>.\thewge.cpp(55) : error C2039: 'utf8' : is not a member of 'QString'
1> c:\qt\4.6.2\include\qtcore\../../src/corelib/tools/qstring.h(91) : see declaration of 'QString'


QString Qstr1 = ui.usrLineEdit->text();
QString Qstr2 = ui.pwdLineEdit->text();

char *acsUserName = Qstr1.utf8();
char *acsPassword = Qstr2.utf8();


I also tried this.


QString Qstr1 = ui.usrLineEdit->text();
QString Qstr2 = ui.pwdLineEdit->text();

char *acsUserName = Qstr1.toUtf8();
char *acsPassword = Qstr2.toUtf8();

and got these errors:

1>.\thewge.cpp(53) : error C2440: 'initializing' : cannot convert from 'QByteArray' to 'char *'
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1>.\thewge.cpp(54) : error C2440: 'initializing' : cannot convert from 'QByteArray' to 'char *'
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

borisbn
24th June 2010, 10:19
toUtf8() is a QByteArray, created temporary, that's why you can't do like this:


const char *acsUserName = Qstr1.toUtf8().constData();

because at the next line acsUserName pointer will point to memory of destroyed temporary object.
you only can send this construction to a function by argument like this:


void foo( const char * userName, const char * password )
{
...
}
...
foo( Qstr1.toUtf8().constData(), Qstr2.toUtf8().constData() );

or you should make new memory for this C-style string like this:


char *acsUserName = new char[ Qstr1.length() + 1 ]; // + 1 for zero in the end of string
memcpy( acsUserName, Qstr1.toUtf8().constData() );
char *acsPassword = new char[ Qstr2.length() + 1 ]; // + 1 for zero in the end of string
memcpy( acsPassword, Qstr2.toUtf8().constData() );
foo( acsUserName, acsPassword );
delete []acsUserName;
delete []acsPassword;

Lesiok
24th June 2010, 12:38
Can You show code generating Yours SQL ? It is some strange what You are doing.
I think that You want to insert record into SQL table.

harleyskater
24th June 2010, 19:17
Lesiok, I am using mysqlpp to do a select statement.

query << "SELECT username, password FROM db_user WHERE username = '" << acsUserName << "' and password = '" << md5(acsPassword) << "'";

Borisbn, I will give your solution a try now :)

The first solution I ran into a problem with the function and then chars inside the function not visable to the query string.

the second solution i get this error:

error C2660: 'memcpy' : function does not take 2 arguments



QString Qstr1 = ui.usrLineEdit->text();
QString Qstr2 = ui.pwdLineEdit->text();

//char *acsUserName = Qstr1.toUtf8();
//char *acsPassword = Qstr2.toUtf8();

char *acsUserName = new char[ Qstr1.length() + 1 ]; // + 1 for zero in the end of string
memcpy( acsUserName, Qstr1.toUtf8().constData() );
char *acsPassword = new char[ Qstr2.length() + 1 ]; // + 1 for zero in the end of string
memcpy( acsPassword, Qstr2.toUtf8().constData() );


/* std::string acsUserName1 = Qstr1.toLatin1();
std::string acsPassword1 = Qstr2.toLatin1();

const int kInputBufSize = 100;
char acsUserName[kInputBufSize];
char acsPassword[kInputBufSize];

ToUTF8(acsUserName, kInputBufSize, acsUserName1);
ToUTF8(acsPassword, kInputBufSize, acsPassword1); */


query << "SELECT username, password FROM db_user WHERE username = '" << acsUserName << "' and password = '" << md5(acsPassword) << "'";



I will research memcopy to see if I can find the a problem

squidge
24th June 2010, 20:08
memcpy() requires the length, so use strcpy() which doesn't as long as your string does not contain embedded nulls (which username and password should not anyway)

harleyskater
24th June 2010, 20:18
QString Qstr1 = ui.usrLineEdit->text();
QString Qstr2 = ui.pwdLineEdit->text();

char *acsUserName = new char[ Qstr1.length() + 1 ]; // + 1 for zero in the end of string
memcpy( acsUserName, Qstr1.toUtf8().constData(),Qstr1.length() + 1 );
char *acsPassword = new char[ Qstr2.length() + 1 ]; // + 1 for zero in the end of string
memcpy( acsPassword, Qstr2.toUtf8().constData(), Qstr2.length() + 1 );

this compiles but my code still isn't working properly. I'm kind of annoyed because I can not create breakpoints in Visual Studios when using QT. It makes it difficult to problem solve but I know its not executing properly because I am checking the number of rows returned from my query is not greater than zero





if (res.num_rows() > 0)
{
qApp->exit(0);
//goodlogin
}
else
{
//badlogin
}

squidge
24th June 2010, 20:53
If you can't do breakpoints in Visual Studios when using QT then your VS installation is broken.

Secondly, since your converting to UTF8, the number of bytes to copy might be more than the number of characters in the string, so you can't use Qstr1.length() (one character could be upto 4 bytes in the output). This is why a QString is an array of QChar and not Char.

try and use qDebug for your string

harleyskater
24th June 2010, 21:11
I will reinstall my VS 2005, the breakpoints work great in non-qt apps, I also opened up a thread in the newbie qt to get some help with this issue.

is QT compatible with 2008 express?

ChrisW67
24th June 2010, 23:36
Since you are using Qt and making a single atomic use of the UTF8 strings I think that:


char *acsUserName = new char[ Qstr1.length() + 1 ]; // + 1 for zero in the end of string
memcpy( acsUserName, Qstr1.toUtf8().constData() );
char *acsPassword = new char[ Qstr2.length() + 1 ]; // + 1 for zero in the end of string
memcpy( acsPassword, Qstr2.toUtf8().constData() );
foo( acsUserName, acsPassword );
delete []acsUserName;
delete []acsPassword;

is probably more elegantly put without intervening temporary variables and manual memory shuffle:


foo( Qstr1.toUtf8().constData(), Qstr2.toUtf8().constData() );
The temporary QByteArray object scope extends to the end of the foo() call. If you need to make multiple uses of the UTF8 string:


QByteArray username = QStr1.toUtf8();
QByteArray password = QStr2.toUtf8();
foo( username.constData(), password.constData() );
bar( username.constData() );
and let QByteArray worry about NUL termination, memory allocation, and necessary size.

squidge
25th June 2010, 00:19
is QT compatible with 2008 express?Qt is, but Express editions of VS have no support for plugins, so you will have to do everything yourself.

Lesiok
25th June 2010, 08:56
Because I'm lazy all SQL queries I have making like this :

QSqlQuery query( *db );

query.prepare("SELECT username, password FROM db_user WHERE username = :uname and password = :passwd";
query.bindValue( ":uname", uname );
query.bindValue( ":passwd", passwd );
query.exec();

where uname and passwd are QString. With this SQL driver is worrying about correct building of query.

squidge
25th June 2010, 09:51
If you don't know if the query is being build correctly, send it to the debug console using query.lastQuery()

Lesiok
25th June 2010, 12:59
If you don't know if the query is being build correctly, send it to the debug console using query.lastQuery()

I know if the query is build correctly or no :p . What I want to say is that using QSqlQuery::prepare is a good solution for problems with ie. string coding. I don't need to know about code page used by connection to server.