Search code examples
qtutf-8character-encodingqurl

QUrl, right coding for paths


I have a problem with coding. I'm using drag and drom inside my application but some text files I can not open, after some searching I find that the path is with wrong coding. The real file is 'Some_file - 01.txt' but when I try print this path (after drop) to the stdout I will get 'Some_file – 01.txt'. What I miss:

void MainWindow::dropEvent(QDropEvent *event) {
  QList<QUrl> urls = event->mimeData()->urls();
  ...
  cout << paths[1].toLocalFile() << endl; /* Some_file – 01.txt */
  cout << paths[1].toEncoded() << endl; /* Some_file%20%E2%80%93%2001.txt */
}

I also try QString::fromLatin1 or fromUtf8 but without success. I'm using QT 4.7.0 and Windows 7.

Edit:

This is my main setup:

QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));

And unfortunately even this is not working for me:

QString fileName = QFileDialog::getOpenFileName(this, tr("Load EEPROM from HEX file"), "", tr("HEX file (*.hex)"));
ifstream hexFile(fileName.toStdString().c_str());

I'm not able to open files where the char '-' is part of file name.

EDIT2:

If I change the file name manualy from 'file.txt' to 'file-.txt' everything is working well. But when I (the same file) copy and paste this file to the same folder, windows will generate new name with postfix: 'file - copy.txt' and this file I can NOT open. So the Windows is using different character for '-' vz. '–'.

What I can do ?

Solution:

void openFile(string fileName) {
  ifstream fileio(fileName.c_str());
}

QString qtFileName = QFileDialog::getOpenFileName(...)
openFile(qtFileName.toLocal8Bit().constData());

Solution

  • std::cout is encoded with some local encoding. What you need is to convert the QString returned by the toLocalFile() into a local 8 bit encoding.

    For example:

    QUrl url = ...;
    QString filePath = url.toLocalFile();
    QByteArray filePath8 = filePath.toLocal8Bit();
    std::cout << filePath8.constData();
    

    But really, the whole exercise is not necessary, since to access the files you should be using QFile, which takes a QString directly, and console output can be done using QTextStream. To wit:

    #include <cstdio>
    #include <QTextStream>
    #include <QFile>
    QTextStream out(stdout);
    
    void test() {
      out << filePath;
    
      QFile file(filePath);
      if (file.open(QIODevice::ReadOnly)) {
        ...
      }
    }