首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Linux中打开包含非Ascii字符串的wchar_t*文件?

问如何在Linux中打开包含非Ascii字符串的wchar_t*文件?
EN

Stack Overflow用户
提问于 2011-01-13 10:49:21
回答 6查看 19.5K关注 0票数 6

运行环境: Gcc/G++ Linux

我在文件系统中有一个非ascii文件,我要打开它。

现在我有了一个wchar_t*,但是我不知道怎么打开它。(my trusted fopen仅打开char*文件)

请帮帮忙。非常感谢。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-01-13 12:11:59

有两种可能的答案:

如果您希望确保所有Unicode文件名都是可表示的,则可以对文件系统使用UTF-8文件名这一假设进行硬编码。这就是“现代”的Linux桌面应用程序方法。只需使用库函数(iconv会工作得很好)或您自己的实现(但请查看规范,这样您就不会像谢尔文那样弄错),将字符串从wchar_t (UTF-32)转换为UTF-8,然后使用fopen。

如果您希望以更面向标准的方式进行操作,则应该使用wcsrtombs将wchar_t字符串转换为区域设置编码中的多字节char字符串(在任何现代系统上都希望是UTF-8 ),并使用fopen。请注意,这要求您事先使用setlocale(LC_CTYPE, "")或setlocale(LC_ALL, "")设置区域设置。

最后,不是一个确切的答案,而是一个建议:

将文件名存储为wchar_t字符串可能是一个可怕的错误。相反,您应该将文件名存储为抽象的字节字符串,并且只将它们及时转换为wchar_t,以便在用户界面中显示它们(如果有必要的话;许多UI工具包本身使用纯字节字符串,并将其解释为字符)。通过这种方式,您可以消除许多可能的令人讨厌的情况,并且您永远不会遇到某些文件由于名称而无法访问的情况。

票数 15
EN

Stack Overflow用户

发布于 2011-01-13 11:40:19

Linux不是UTF-8,但无论如何它是文件名的唯一选择

(文件中可以包含您想要的任何内容。)

关于文件名,linux实际上并不需要担心字符串编码。文件名是需要以null结尾的字节字符串。

这并不意味着Linux是UTF-8,但它确实意味着它与宽字符不兼容,因为它们可能在不是结束字节的字节中有零。

但是UTF-8保留了除末尾以外的无空值模型,所以我必须相信实用的方法是将文件名“转换为UTF-8”。

文件的内容是Linux内核级别以上的标准的问题,所以这里没有任何Linux-y可以或想要做的事情。文件的内容将只由读取和写入它们的程序关注。Linux只是存储和返回字节流,它可以包含您想要的所有嵌入式nuls。

票数 4
EN

Stack Overflow用户

发布于 2011-01-13 11:14:19

将wchar字符串转换为utf8字符串,然后使用fopen。

代码语言:javascript
复制
typedef unsigned int   uint;
typedef unsigned short word;
typedef unsigned char  byte;

int UTF16to8( wchar_t* w, char* s ) {
  uint  c;
  word* p = (word*)w;
  byte* q = (byte*)s; byte* q0 = q;
  while( 1 ) {
    c = *p++;
    if( c==0 ) break;
    if( c<0x080 ) *q++ = c; else 
      if( c<0x800 ) *q++ = 0xC0+(c>>6), *q++ = 0x80+(c&63); else 
        *q++ = 0xE0+(c>>12), *q++ = 0x80+((c>>6)&63), *q++ = 0x80+(c&63);
  }
  *q = 0;
  return q-q0;
}

int UTF8to16( char* s, wchar_t* w ) {
  uint  cache,wait,c;
  byte* p = (byte*)s;
  word* q = (word*)w; word* q0 = q;
  while(1) {
    c = *p++;
    if( c==0 ) break;
    if( c<0x80 ) cache=c,wait=0; else
      if( (c>=0xC0) && (c<=0xE0) ) cache=c&31,wait=1; else 
        if( (c>=0xE0) ) cache=c&15,wait=2; else
          if( wait ) (cache<<=6)+=c&63,wait--;
    if( wait==0 ) *q++=cache;
  }
  *q = 0;
  return q-q0;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4676327

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档