|
From: tuitfun <tu...@ya...> - 2007-08-21 13:15:35
|
hello, i am trying to write a program that will work with unicode filenames in both windows & unix. in unix, it just works -- the regular c functions work just fine. in windows, it's been suggested in another list (thanks Tor Lillqvist) that i should use _w* functions instead. since this list should be more appropriate, i'll ask questions here instead. :) after some more searching, i've found tchar.h in mingw which can be used in both unicode & non-unicode systems. is tchar.h still the proper way to accomplish this? i am using ffmpeg libraries in this program. so i cannot modify all code to use tchar.h. i need to call funtions that expect regular char * arguments. so, before calling those functions, i need to convert the wchar_t * to utf-8 and pass as char *. the code at the end of this email is what i've got so far. there're still a few problems though: - unix doesn't have tchar.h, so i'll need a header file that maps _t* functions back to the normal ones. is there such a header file? - i cant get mbstowcs() & wcstombs() to convert to utf-8. what am i doing wrong? - in the code below, i need to declare a buffer for the string conversions. can this be done in a less intrusive way? - how to get argv[] in utf-8? thanks a lot for your help. :) please also tell me if i am going in the wrong direction. tuit ps. movie thumbnailer (mtn) is the program i am working on. it's quite usable now. http://moviethumbnail.sourceforge.net/ :) /* to enable unicode: gcc -W -Wall -o tchartest tchartest.c -D_UNICODE -DUNICODE */ #include <stdio.h> #include <errno.h> #include <dirent.h> #include <sys/stat.h> #include <fcntl.h> #ifdef WIN32 unsigned int _CRT_fmode = _O_BINARY; // default binary file including stdin, stdout, stderr #include <tchar.h> #include <windows.h> #ifdef _UNICODE // mbstowcs() & wcstombs() dont seem to work. no utf-8 locale? #define MS_UTF8_2_WC(wdst, src, size) MultiByteToWideChar(CP_UTF8, 0, (src), -1, (wdst), (size)) #define MS_WC_2_UTF8(dst, wsrc, size) WideCharToMultiByte(CP_UTF8, 0, (wsrc), -1, (dst), (size), NULL, NULL) #else #define MS_UTF8_2_WC(dst, src, size) ((dst) = (src)) #define MS_WC_2_UTF8(dst, src, size) ((dst) = (src)) #endif #else //#include "fake_tchar.h" #define MS_UTF8_2_WC(dst, src, size) ((dst) = (src)) #define MS_WC_2_UTF8(dst, src, size) ((dst) = (src)) #endif void process_dir(char *dir) { // convert utf8 to wc #if defined(WIN32) && defined(_UNICODE) wchar_t dir_w[FILENAME_MAX]; #else char *dir_w; #endif MS_UTF8_2_WC(dir_w, dir, FILENAME_MAX); // open _TDIR *dp = _topendir(dir_w); if (NULL == dp) { _ftprintf(stderr, _TEXT("_topendir '%s' failed\n"), dir_w); return; } /* read directory */ struct _tdirent *d; while ((d = _treaddir(dp))) { if (_tcscmp(d->d_name, _TEXT(".")) == 0 || _tcscmp(d->d_name, _TEXT("..")) == 0) { continue; } _tprintf(_TEXT("found: '%s'\n"), d->d_name); TCHAR child[FILENAME_MAX]; _tcscpy(child, dir_w); _tcscat(child, _TEXT("/")); _tcscat(child, d->d_name); struct _stat statbuf; int ret = _tstat(child, &statbuf); if (0 != ret) { // error _tprintf(_TEXT("_tstat '%s' failed\n"), child); continue; } if (S_ISDIR(statbuf.st_mode)) { _tprintf(_TEXT("%s is a directory\n"), child); // convert wc to utf8 #if defined(WIN32) && defined(_UNICODE) char child_utf8[FILENAME_MAX]; #else char *child_utf8; #endif MS_WC_2_UTF8(child_utf8, child, FILENAME_MAX); // call other functions that expect char * process_dir(child_utf8); } else { _tprintf(_TEXT("%s is not a directory\n"), child); } } _tclosedir(dp); } int main(int argc, char *argv[]) { if (2 == argc) { process_dir(argv[1]); } else { process_dir("."); } return 0; } ____________________________________________________________________________________ Be a better Globetrotter. Get better travel answers from someone who knows. Yahoo! Answers - Check it out. http://answers.yahoo.com/dir/?link=list&sid=396545469 |