Can't convert QString to Const Char* - c++

I'm new to QT so please excuse me if I'm blatantly doing something wrong here, but I've looked at all the questions here on the matter but can't seem to find something that works. I'm trying to have the user create a folder by entering a name for it, and it 'creates' a folder with the name. I say 'create' because it's not exactly creating one, it makes a folder first called "project" before you enter the name, and when you enter a name it renames it. However, when I try and rename the folder with the inputted name it gives me
error:C2664: 'int rename(const char *,const char *)' : cannot convert
argument 1 from 'QString' to 'const char *'
Here's my code:
void MainWindow::on_actionNew_Project_triggered(const char *parameter)
{
//Create project folder
QString projectPath = "D:/Project";
QDir dir(projectPath);
if (!dir.exists()) {
dir.mkpath(projectPath);
}
//Get project name from user
bool result;
QString name = QInputDialog::getText(0, "New Project",
"Enter in project name", QLineEdit::Normal,
"", &result);
if(result && !name.isEmpty()) {
//Rename project folder to user created name
QDir dir(projectPath);
if (dir.exists()) {
rename(projectPath, name); //Gives me error HERE
}
}
}
I would appreciate it if you guys could help, I've been stuck on this for hours.

You could call QString::toStdString(), and then call c_str() to retrieve the const char* from the std::string.
Your code would look something like this:
if (dir.exists()) {
rename(projectPath.toStdString().c_str(), name);
}

Try dir.rename(dir.dirName(), name);
You are trying to invoke a member function without an instance.
Since rename() is a member function of QDir, you need a QDir instance in order to invoke it. So rather than just calling rename() which invokes who knows what, you need to dir.rename().
QDir::rename() actually takes 2 QStrings as parameters, but that other function you are invoking takes two raw strings, so you don't really need to convert the strings, you were just calling the wrong function.
bool QDir::rename(const QString & oldName, const QString & newName)
You are most likely calling rename() from <stdio.h>, which could also work given that the parameters are correct and the OS can rename the directory, in that case you will need to convert to "raw" C-style strings via yourString.toLatin1().constData(). But since you are using Qt, you might as well use the QDir API, which works directly with QString.
If it still doesn't work, then either your input parameters are wrong, or there is something preventing the OS from rename the directory, for example a file currently in use.

Qt FAQ says:
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QString str1 = "Test";
QByteArray ba = str1.toLatin1();
const char *c_str2 = ba.data();
printf("str2: %s", c_str2);
return app.exec();
}

Related

const char* returns true in C++ CLI

since yesterday I have been struggling to turn text into label with code from another class, I came to this:
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
TestApp::UI_Error form("test", "test");
Application::Run(% form);
Using the above code, i display a winapi form that receives "test", "test" as 2x const char* on loading, the problem appears when im trying to set the text in labels using these variables
The code looks like this:
public:
UI_Error(const char* errorText, const char* errorCode)
{
InitializeComponent();
this->testLabel->Text = System::Convert::ToString(errorText);
}
For some reason, each time the return value shown in the win forms window is "true", although it should be "test" here, does anyone know the solution?
I tried to use std::string instead of const char*, unfortunately for some reason i get the error code that a static variable is required :(
Maybe I am wrong here, but System::Convert::ToString() seems not to have a method that accepts a const char* pointer. It looks like it gets cast to something else.
Try this instead:
Text = gcnew System::String(errorText);

Is this correct point to free char*

I have this code
{
char *filename = createFilename(file, extension);
...
...
delete[] filename;
}
inline char *DataSet::createFilename(LPCSTR file, LPCSTR extension)
{
char *path = new char[strlen(file) + strlen(extension) + 1];
strcpy(path, file);
strcat(path, extension);
return path;
}
Am I right to delete "filename" in the main function? I get ERROR_INVALID_NAME on delete. I have checked the filename and that is correct.
I know I should be using std::string but this is existing code. Please help
If it's existing code and you can't change createFilename to return a std::string, then how about changing the call site to use std::unique_ptr. It is specialized for arrays and would be a much safer bet than doing delete on your own. See this answer.
An error of type ERROR_INVALID_NAME usually occurs when the directory name, file name or volume label is incorrect. On Windows, you might have to take care of escape sequences. For example, if the path to the file is C:\Folder\File.ext you should use the string C:\\Folder\\File.ext. In addition, some characters may not be accepted by the API you're using even though Windows allows them to be used in file and directory names. See this.

Problems transforming QString to _bstr_t

I am trying to transform a QString to _bstr_t type as follows:
QString mFilename="C:/agatebo/amahoro.doc";
QByteArray srcBa1 = mFilename.toLocal8Bit();
const char *srcString1 = srcBa1.data();
CString myStringSrc(srcString1,srcBa1.size());
BSTR bstrUser = myStringSrc.AllocSysString();
_bstr_t user(bstrUser,TRUE);
but when I pass the _bstr_t I get to this function:
pdfObject->cPrintFile(user);
PDFCreator ,a program whose COM interface I am using just crashes .I suspect this has something to do with unicode but can’t figure out what yet.I should mention that when I directly pass a path to the file like this:
pdfObject->cPrintFile(L"c:\\agatebo\\amahoro.doc");
all is ok ,I simply want to be able to use QStrings that come from other modules of my Qt application.I am compiling with Qt 4.8 msvc2010 if this matters. I would appreciate any
You should be able to use QString.utf16()
void ProcedureThatTakesWChar(const wchar_t* s) {
std::wcout<<s<<L'\n';
}
void ProcedureThatTakesBstr(const BSTR& s) {
std::wcout<<s<<L'\n';
}
int main(int argc, char *argv[]) {
QString qs("this is a qstring");
//pass directly
ProcedureThatTakesWChar(qs.utf16());
//if you really want to use a _b_str initialise it with .utf16()
//_b_str will handle SysAllocString and SysFreeString. QString
//does not have to stay in scope.
{
_bstr_t bs(qs.utf16());
ProcedureThatTakesBstr(bs);
}
return 0;
}
Since you're on Windows and the method call works when you pass in a wide string, that means you're compiling in Unicode mode. This means that TCHAR,_bstr_t etc. are typedefed to wchar_t. You can learn more about Unicode support in Windows here.
The good news is that QString and Microsoft's Unicode implementation both use the same character encoding, UTF-16.
To get the raw QString data you simply call QString's utf16() method. This returns a pointer to an array of null-terminated unsigned shorts -- the same type as wchar_t on Windows!
So in all you should have to do here is this:
pdfObject->cPrintFile(mFilename.utf16());

Qt 5: const char * QString cast

In Qt 4 it is possible to automatically cast a QString to a "const char *", e.g. I could pass a QString to a function that expected a "const char *".
void myFunction(const char *parameter);
QString myString;
myFunction(myString); //works in QT4
In Qt 5 I would however get an "error C2440: 'type cast' : cannot convert from 'QString' to 'const char *'" (that is the Visual C++ 2008 compiler, other compilers would throw something similar). If I understand the documentation correctly, it is because the Qt 3 compatibility layer is not included anymore in QT5.
Of course, I could change the function call from
myFunction(myString);
to
myFunction(myString.toLatin1().data());
However, I have a huge code base that compiles fine with Qt 4 and I would really like to have my old code compile with Qt 5 without modifying it. Is there any way to achieve this?
You could create a macro or inline function for your purpose to minimize the changes, but since that would also require a grep alike operation, there is not much difference.
#define QString2charp(myString) myString.toLatin1().data()
or
inline char* QString2charp (const QString &myString)
{
return myString.toLatin1().data();
}
and then:
myFunction(QString2charp(myString));
BUT
of course, in an ideal world, it would be nice if your "myFunction" could get an overload expecting a QString argument.
void myFunction(const char *parameter);
void myFunction(QString parameter);
and then the overload would be implemented like this:
void myFunction(const QString &parameter)
{
myFunction(myString.toLatin1().data());
}
of course, this would require the constructor being explicit so that no implicit conversion can happen, otherwise the compiler will complain about ambiguity in presence of both when trying to pass const char*, but if you always use QString, it should just work with Qt 5.
This is somewhat equal to rewriting the original function to a different signature expecting QString though because unfortunately the corresponding constructor is not explicit. I imagine that was not changed in Qt 5 for compatibility as it would have broken too much code.
As you can see, you do not need to change anything in your code this way, other than adding a one-liner overload. It is neat, isn't it?
You could either
Change the signature of your function to MyFunction( const QString & parameter ) (of course that works only if you don't need the one that takes char * any more)
Overload MyFunction:
void myFunction(const char *parameter); //this is your normal function
void myFunction( const QString & parameter )
{
char * c_str = nullptr;
<convert parameter to char * in any way that suits you>
myFunction( c_str );
}
If the above is impossible for some reason, the best approach is probably to write a similar wrapper:
void MyFunctionWrapper( const QString & parameter )
{
<same as above>
}
It is no longer possible to cast QString to const char* in >= Qt 5, because QString is UTF-16 and no longer has an entry for caching the result of converting to ASCII.
The way to achieve your aim is
a) Add overloads to the functions expecting const char* which can handle QStrings,
b) Add the explicit conversion code to the call-site, or
c) Go to some char-based string, like std::string.
None of those fulfill your aim of nearly no changes though.
I found this on QT forum
const QByteArray byteArray = mytext = textBox.text().toUtf8();
const char *mytext = byteArray.constData();
This resolved my issue

Heap error in for loop using const type variable?

For just practice, using QT library I am trying to select a folder and list the name of the dicom files in that folder. The following is code for that:
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
QString fileName = QFileDialog::getExistingDirectory();
if (fileName.isEmpty())
{
std::cout << "Got an empty file!\n";
}
else
{
QStringList nameFilter;
QDir dir(fileName);
nameFilter << "*.dcm";
QFileInfoList list = dir.entryInfoList( nameFilter, QDir::Files );
int numberOfFiles=list.count();
for(int i=0;i<numberOfFiles;i++)
{
QString filena=list[i].fileName();
string a=filena.toStdString();
cout<<a<<endl;
}
}
return 0;
}
Here I have found out that the function toStdString, which is actually std::string QString::toStdString () const, gives Heap error. I know the replacement to get rid of this error is to use toLocal8Bit().constData(), but I'm curious what's the main reason behind the heap error provided by toStdString. Is it because it is const type and my for loop is trying overwrite the const variable everytime?
Your code looks good - make sure your Qt's dll files are compiled with the same compiler (and with same Debug/Release configuration) you are using.
To answer some of your questions:
Is it because it is const type and my for loop is trying overwrite the const variable everytime?
No, your for loop is not trying to overwrite const variable. Const variable is on the right side of the assingment operator, so your for loop is reading from const variable, and it doesn't overwritting anything (your a variable is local variable visible inside for loop's block, so a is different in each pass of the loop).
Even if you try to overwrite const variable, that would not compile - trying to change const will break in compile-time, and not in runtime.
This code works for me.
You'd better not convert strings to std::string and use std::cout, but rather use QTextStream for output:
QTextStream out(stdout);
//...
QString filena=list[i].fileName();
out << filena << endl;
My money would be on mixing Debug versions of the Qt Framework with Release versions of your compiled program.
Especially under Windows a different heap manager is used in debug and release builds.
Try recompiling in debug mode and seeing what happens.