我QFileDialog::getOpenFileName()曾經讓用戶選擇一個檔案,但我需要將結果作為 C 字串,因為我必須將它傳遞給用 C 撰寫的使用fopen(). 我無法改變這一點。
我發現的問題是,在 Windows/MinGWtoStdString()上,使用結果QString不適用于 Unicode/非 ASCII 檔案名。嘗試基于std::string失敗打開檔案,因為似乎正在發生某些字符集轉換。有時toLocal8Bit()用于轉換作業,但有時它沒有。
考慮以下(MinGW)程式:
#include <cstdio>
#include <iostream>
#include <QApplication>
#include <QFileDialog>
#include <QFile>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
auto filename = QFileDialog::getOpenFileName();
QFile f(filename);
std::cout << "fopen: " << (std::fopen(filename.toStdString().c_str(), "r") != nullptr) << std::endl;
std::cout << "fopen (local8bit): " << (std::fopen(filename.toLocal8Bit().data(), "r") != nullptr) << std::endl;
std::cout << "Qt can open: " << f.open(QIODevice::ReadOnly) << std::endl;
}
- 對于名為 的檔案
?.txt,toStdString()有效,local8Bit()無效。 - 對于名為 的檔案
?.txt,toStdString()不起作用,local8Bit()確實如此。 - 對于名為 的檔案
?.txt,兩者都不起作用。
但是,在所有情況下,QFile都能夠打開檔案。我想它可能在 C 代碼使用時使用 Unicode Windows 函式,據fopen()我了解,這是 Windows 上所謂的 ANSI 函式。但是有什么方法可以從QString? 我不關心檔案名的編碼,我只想要可以傳遞的東西fopen()來打開檔案。
我發現使用GetShortPathName從中獲取短檔案名filename.toWCharArray()似乎可行,但這非常麻煩,而且我的理解是 NTFS 檔案系統可以被告知不支持短名稱,因此無論如何這不是一個可行的解決方案。
uj5u.com熱心網友回復:
Windows 的非 unicode API 中的檔案路徑要么在當前的 ANSI(Microsoft 編解碼器)代碼頁中決議,要么在 OEM 代碼頁中決議(另請參見https://docs.microsoft.com/en-us/cpp/c-runtime -庫/參考/fopen-wfope)。ANSI 是默認值。
所以您的問題轉化為:如何將 UTF-8 或 UTF-16 字串轉換為 ANSI 或 OEM?
ANSI轉換有一個答案:How to convert from UTF-8 to ANSI using standard c
無論如何,重要的是要意識到并非所有 UTF 字串都可以在這些更窄的編解碼器中表示......
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/429956.html
下一篇:QTEXE執行失敗
