当我的程序尝试stat()
包含特定UTF-8字符的文件时,stat()
函数会返回错误。例如,我可以使用vi打开文件/tmp/surgateDlpMgQure/Özkul Gazete
,但将同一文件传递给stat()
会产生错误。系统区域设置为:
LANG =的en_US.UTF-8
LC_CTYPE = “的en_US.UTF-8”
LC_COLLATE = C
LC_TIME = “的en_US.UTF-8”
LC_NUMERIC = “的en_US.UTF-8”
LC_MONETARY = “的en_US.UTF-8”
LC_MESSAGES = “的en_US.UTF-8”
LC_ALL =
我应该为stat()
了解UTF-8字符做些什么吗?
以下是代码:
int main ()
{
struct stat s;
if (stat("/tmp/surgateDlpMgQure/Özkul Gazete", &s) == -1)
perror("stat");
switch (s.st_mode & S_IFMT) {
case S_IFBLK: printf("block device\n"); break;
case S_IFCHR: printf("character device\n"); break;
case S_IFDIR: printf("directory\n"); break;
case S_IFIFO: printf("FIFO/pipe\n"); break;
case S_IFLNK: printf("symlink\n"); break;
case S_IFREG: printf("regular file\n"); break;
case S_IFSOCK: printf("socket\n"); break;
default: printf("unknown?\n"); break;
}
return 0;
}
答案 0 :(得分:0)
问题可能是文件名的编码不是
与您在程序中内部使用的编码相同。钥匙
这里的问题是谁创建了文件(并给它这个名字),和
代码中的字符串来自哪里。大多数Unix都是不可知的
关于编码,只要几个特殊字符就好
'/'
,具有预期的编码。因此,独立于您的
当前语言环境,文件名可以是Latin-1,Latin-5(只是猜测,
但这个名字看起来像土耳其语)或UTF-8。在Unix中几乎没有任何关心,
但你必须确保在程序中使用相同的编码
用于创建文件,或名称不匹配。 (在实践中,
我发现最简单的策略是限制字符中的字符
文件名到一个非常小的集合:ASCII字母数字字符,数字,
'_'
,可能还有'-'
。)
如果您不确定磁盘上文件名的实际编码,
您可以使用ls | od -t x1 -tc
找出实际值
其中的字节。如果Ö
为0xD6,则编码为Latin-1
或拉丁语-5(它可能不会有太大的区别),和
您必须确保传递的文件名为stat
(或open
,或
采用文件名的任何其他函数都在其中一个中编码
编码。相反,如果你有两个字节序列0xC3,0x96,那么
文件名是UTF-8。
如果您确实想支持ASCII子集之外的字符,那么
我强烈建议您确保所有文件名都已编码
在UTF-8中。假设您可以 - 编码将由
创建文件的程序,如果它不是你的程序(或如果
你从另一个系统接收文件),你可能无法
做任何事情。在最糟糕的情况下,您甚至可能必须这样做
使用opendir
和readdir
与某种匹配算法进行查找
实际文件名(无论编码如何),并使用它。
答案 1 :(得分:0)
我认为由于该文件名名称中的空格而存在问题...
你可以尝试更改没有空格的文件名
Özkul Gazete -> Özkul_Gazete
在Linux上,我通常不会在文件名或目录名中使用空格
答案 2 :(得分:-1)
简单的方法来解决它:
使用该unicode字符的转义表示:
"/tmp/surgateDlpMgQure/\x00\xF6zkul Gazete"
我没有测试,但它应该工作。虽然这不是用C语言中的unicode字符串的方式。
很奇怪,你的代码可以在我的系统上运行,但不适用于我的系统:)