上面下指令说要做多国语言版的程序,这可是个不小的改动呀。于是我就拿当前的程序运行,一系列的问题随之出现了。
话分两头,先说跑在Windows上的,最基本的就是读各种语言的文件名,正常英文还是正常的,但遇到俄文,法文,德文时就出现问题,正常的字符都变成了"?",跟踪内存发现读入内存的字符已经变成了3f00,也就是"?"的unicode,可见是读入目录到内存的函数出了问题,如下代码:
long filehandle;
//the structure of file
struct _finddata_t entry;
//"*" means get all the file and directory
// Get the first file
if((filehandle = _findfirst( "*", &entry )) != -1) //-1 means the directory is null
{
tree* child;
do{
if(entry.attrib&FILE_ATTRIBUTE_DIRECTORY){
if ( strcmp("..", entry.name) != 0 && strcmp(".", entry.name) != 0){
//printf("%*s%s\\\n", depth, "", entry.name);
if(treenode)
{
char name[MAX_LOCALPATH_FOLDERNAME_LENGTH+1];
strncpy(name,entry.name,MAX_LOCALPATH_FOLDERNAME_LENGTH-1);
strcat(name,"\\");
child=new tree(name);
treenode->AddChild(child);
}
//Recursively processes directories
//printdir(entry.name, depth + 4,child);
}
} else{
//printf("%*s%s\n", depth, "", entry.name);
if(treenode)
{
child=new tree(entry.name);
treenode->AddChild(child);
}
}
}while( (_findnext(filehandle,&entry)) ==0 );
}
chdir("..");
_findclose(filehandle);
通过查证MSDN得知类似于_findfirst,findnext都是针对ASCII码的,要读unicode(windows默认字符集),就得用_wfindfirst,_wfindnext等读宽字符的操作函数,最终解决问题,但我没有松气,因为程序主要是运行在linux中的,Linux真不知道怎么整了。
Linux上读多国语言的文件和目录就需要对Linux系统深入了解,因为我要读的文件是usb上的文件,所以得先挂载到一个目录,
mount -t vfat /dev/sda1 /mnt/usb,然后readdir读入文件,与Windows上同样的错,读入的是"?",我想和windows一样去找一个类似wreaddir,但是没有。于是应该从挂载着手,目前在NTFS和FAT32/VFAT下的文件系统上都使用了Unicode,这就需要系统在读取这些文件名时动态将其转换为相应的语言编码,也就是说挂载的时候要把usb上的编码转化成16位的Unicode编码,改命令如下后成功。
mount -o iocharset = utf8 /dev/sda1 /mnt/usb.
Linux对iocharset的解释如下:
Character set to use for converting between 8 bit characters and 16 bit unicode charaters.The default is iso8859-1. Long filenames are stored on disk in Unicode format.
至此终于解决了多国语言的问题,接着我无法想象还有什么问题会出来,但我准备好了。