UNICODE, only?

来源:互联网 发布:笑笑淘宝店倒闭 编辑:程序博客网 时间:2024/05/21 18:43

前一阵因为要把我自己的一个通用函数库转为UNICODE,才发现原来WINDOWS/VC的解决方式也不完全好用。基本上,如果你定义了UNICODE/_UNICODE,所有的函数默认都是UNICODE的了。但是往往我还需要做一些ANSI字符串的操作,譬如从非UNICODE的文件里读取string,有些变量还必须是stl::string或者char*,就会遇到一些不便之处。举例来说,我有一个函数把一块内存存为文件:

 

bool SaveToFile(const string& filename, const char* data, int size)

{

       FILE* f = fopen(filename.c_str(), “bw”);

       if (f == NULL) return false;

       bool res = fwrite(data, 1, size, f) == size;

       fclose(f);

       return res;

}

 

现在想使这个函数转为在UNICODE/ANSI下都能用,怎么办呢?如果按照WINDOWS的标准办法,可能是:

 

#ifdef UNICODE

typedef string tstring;

#else

typedef wstring tstring;

#endif

bool SaveToFile(const tstring& filename, const char* data, int size)

{

       FILE* f = _tfopen(filename.c_str(), _T(“bw”));

       ...

}

 

但是这样的话,在编译选项为UNICODE时,如果想传入一个ANSI的文件名,就必须在调用之前进行转换,增加一道麻烦。

想了一想,决定用template来解决问题。于是定义函数如下:

 

template<class _S, class _E> bool SaveToFile(const _S& filename, const _E* data, int size)

 

不过这样一来,C++ runtimefopen就不知道该用哪个了。如果还是用_tfopen,用UNICODE编译时就只能传UNICODE的文件名,仍然不能解决问题。到这时就感觉到_tfopen的局限了,就是它的参数完全由编译选项决定了,不能任意选择。

再想了一想,没有办法,只好再用template写一个fopenwrapper如下:

 

template<class _Char> __inline FILE* my_fopen(const _Char *, const _Char *) { assert(false); }

template<> __inline FILE* my_fopen<char>(const char* fileName, const char* attr)

{ return fopen(fileName, attr); }

template<> __inline FILE* my_fopen<wchar_t>(const wchar_t* fileName, const wchar_t* attr)

{ return _wfopen(fileName, attr); }

 

这样不管用const char*或者const wchar_t*都可以调my_fopen。于是前面的函数可以重写如下:

 

template<class _S, class _E> bool SaveToFile(const _S& filename, const _E* data, int size)

{

       _S attr;      attr += 'w';       attr += 'b';

       FILE* f = my_fopen(filename.c_str(), attr.c_str());

       if (f == NULL) return false;

       bool res = fwrite(data, sizeof(_E), size, f) == size;

       fclose(f);

       return res;

}

 

现在这个SaveToFile就可以传入任意类型的字符串了。

 

回顾一下,如果标准头文件里有这样的wrapper,或者_tfopen本身不是#define而是template function,用户就没有这么麻烦了。当然,这种想法或许不符合当时的历史情况。

原创粉丝点击