OHT*_*HTO 3 c++ windows macos qt utf-8
我正在尝试在包含非拉丁字符的 Qt/C++ 软件上加载文件。一个用户报告的问题是俄罗斯文件名,我试图用下面的代码快速修复它。
示例文件名是(我不会读或写俄语!):??????? ???.dgr
bool QDepthmapView::loadFile(const QString &fileName)
{
    m_open_file_name = fileName;
    m_redraw_all = 1;
    // this fixes the problem on a MacOSX but NOT on Windows!
    QByteArray ba = fileName.toUtf8(); 
    char *file = ba.data();
    // end of fix
    if(pDoc->OnOpenDocument(file)) // quick fix for weird chars (russian filename bug report)
    {
        // removed 
    }
    return false;
}
上面的修复是我在网上找到的一个快速的脏东西,它适用于我的 MacOSX10.8,但似乎 Windows 处理非 ASCII 字符有点不同,我不熟悉它。
我正在寻找用于加载非 ASCII 文件名的多平台解决方案(该软件在 Win、Mac 和 Linux 上运行)。
关于以下评论的编辑:
OnOpenDocument转到:
int QGraphDoc::OnOpenDocument(char* lpszPathName) 
{
   m_opened_name = QString(lpszPathName);
   int ok = m_meta_graph->read( lpszPathName );
// removed //
}
####
int read( const pstring& filename )
{
// cleared
#ifdef _WIN32
   ifstream stream( filename.c_str(), ios::binary | ios::in );
#else
   ifstream stream( filename.c_str(), ios::in );
#endif
//cleared
   stream.read( (char *) &version, sizeof( version ) );
// cleared
   }
####
template <class T>
istream& pmemvec<T>::read( istream& stream, streampos offset )
{
   if (offset != streampos(-1)) {
      stream.seekg( offset );
   }
   // READ / WRITE USES 32-bit LENGTHS (number of elements)
   // n.b., do not change this to size_t as it will cause 32-bit to 64-bit conversion problems
   unsigned int length;
   stream.read( (char *) &length, sizeof(unsigned int) );
   m_length = size_t(length);
   if (m_length >= storage_size()) {
      if (m_data) {
         delete [] m_data;
         m_data = NULL;
      }
      while (m_length >= storage_size())
         m_shift++;
      m_data = new T [storage_size()];
      if (!m_data)
         throw pexception( pexception::MEMORY_ALLOCATION, sizeof(T) * storage_size() );
   }
   if (m_length != 0) {
      stream.read( (char *) m_data, sizeof(T) * streamsize(m_length) );
   }
   return stream;
}
欢迎来到精彩的 Windows 本地编码世界。
Windows 内部在 UTF-16 中工作(也是QString如此),但它的“传统”窄字符 API 与“本地代码页”一起工作,这通常与系统代码页相同(尽管它可以在每个线程的基础上进行自定义 -但不,它不能设置为 UTF-8)。
这意味着大多数使用chars 的函数将它们直接传递给 Windows API(通常发生在 C/C++ 文件工具中)期望使用当前代码页编码的字符串。
QString确实支持toLocal8Bit在当前系统编码中提供其内容的窄字符表示的方法,这应该是 Windows 上的本地 CP 和任何配置合理的 UNIX 上的 UTF-8。
问题是,QString到 UTF-8 是一种无损转换,因为它们都可以表示所有的 Unicode 代码点;QString本地代码页不是那么多 - 例如,俄语字符不能在通常的 Windows-1252 CP 中编码。
出于这个原因,使用toLocal8Bit您可以以它期望的编码为流指定一个文件名,但您将无法打开包含当前代码页中未包含的字符的文件。
长话短说:通常避免了任何的问题是要始终保持路径,方式QString和打开文件用QFile。QFile通过使用 UTF-16 字符串调用 Windows API 的“widechar”版本,并在 UNIX 系统上适当地转换为 UTF-8,在内部处理这种疯狂。
如果您确实需要使用其他文件处理函数,您有两种选择:要么使用toLocal8Bit并放弃在 Windows 上处理具有“非本地”名称的文件,要么为使用wchar_ts 的Windows 提供单独的代码路径(直到C 库和 Windows API 函数的宽字符版本)。
| 归档时间: | 
 | 
| 查看次数: | 1886 次 | 
| 最近记录: |