上面下指令說要做多國語言版的程序,這可是個不小的改動呀。于是我就拿當前的程序運行,一系列的問題隨之出現了。
話分兩頭,先說跑在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.
至此終于解決了多國語言的問題,接著我無法想象還有什么問題會出來,但我準備好了。