常用的宽字符函数和安全CRT函数
作者:admin 日期:2009-12-12
宽字符类型和函数是C和C++标准(ANSI/ISO/IEC C 1999和ISO/IEC C++ 1998/2003)新增加的内容,它们是用来支持国际通用的Unicode(1993)字符集的。微软公司从Visual C++ 2005版起,开始严格执行C/C++的新标准。
安全CRT函数是微软公司对C/C++语言的扩展,其中的部分内容已于2003年提交给ISO作为C/C++标准下一版本的修改建议。在VC05/08中,如果不使用这些安全性函数,编译器会报告警告性错误。
1)常用的宽字符函数
由于Windows NT/2000/XP采用的是Unicode字符编码,字符都是双字节的。所以在MFC编程中,一般需要使用双字节的字符类型wchar_t和对应的字符串及其指针类型LPCWSTR和LPCTSTR,并在常数字符串前添加了L转换符,串长计算函数不能用strlen而改用wcslen,串格式打印函数也不能用sprintf,而是改用swprintf(字符和串格式符也从%c和%s改为%lc和%ls)。
wchar_t类型,在标准C++中为内置的数据类型和关键字;在C99标准中则为typedef类型,其等价的数据类型与具体的实现有关,在Win32和VC中定义为:
typedef unsigned short wchar_t; (双字节的无符号短整数)
下面是若干常用的宽字符函数(包含在ISO C99 / ISO C++的标准库中):
#include <wchar.h>
size_t wcslen(const wchar_t *s);
int wprintf(const wchar_t * format, ...);
int wscanf(const wchar_t * format, ...);
int swprintf(wchar_t * s, size_t n, const wchar_t * format, ...);
int swscanf(const wchar_t * s, const wchar_t * format, ...);
long int wcstol(const wchar_t * nptr, wchar_t ** endptr, int base);
float wcstof(const wchar_t * nptr, wchar_t ** endptr);
double wcstod(const wchar_t * nptr, wchar_t ** endptr);
#include <stdlib.h>
errno_t _itow_s( int value, wchar_t *buffer, size_t sizeInCharacters, int radix );
errno_t _ultow_s( unsigned long value, wchar_t *str, size_t sizeOfstr, int radix );
size_t mbstowcs( wchar_t *wcstr, const char *mbstr, size_t count );
size_t wcstombs( char *mbstr, const wchar_t *wcstr, size_t count );
2)常用的安全CRT函数
安全CRT(C Runtime Library = C运行时间库)函数,是微软公司对C/C++语言的扩展。它在原来函数名后添加了“_s”后缀;一般返回出错代码;并将原来的函数返回值,作为一个参数,添加到函数输入参数列表的最后;对带缓冲区参数的函数,还添加了表示缓冲区大小的输入参数,以防止内存溢出。
在VC05/08中,如果不使用这些安全性函数,编译器会报告警告性错误。
下面是若干常用的安全CRT函数:
char *gets_s( char *buffer, size_t sizeInCharacters); // <stdio.h>
wchar_t *_getws_s( wchar_t *buffer, size_t sizeInCharacters); // <stdio.h> or <wchar.h>
errno_t _itoa_s( int value, char *buffer, size_t sizeInCharacters, int radix ); // <stdlib.h>
errno_t _itow_s( int value, wchar_t *buffer, size_t sizeInCharacters, int radix ); // <stdlib.h>
errno_t _ultoa_s( unsigned long value, char *str, size_t sizeOfstr, int radix ); // <stdlib.h>
errno_t _ultow_s( unsigned long value, wchar_t *str, size_t sizeOfstr, int radix ); // <stdlib.h>
int printf_s( const char *format [, argument]... ); // <stdio.h>
int wprintf_s( const wchar_t *format [, argument]... ); // <stdio.h> or <wchar.h>
int scanf_s( const char *format [, argument]... ); // <stdio.h>
int wscanf_s( const wchar_t *format [, argument]... ); // <stdio.h> or <wchar.h>
int sprintf_s( char *buffer, size_t sizeOfBuffer, const char *format [, argument] ... ); // <stdio.h>
int swprintf_s( wchar_t *buffer, size_t sizeOfBuffer, const wchar_t *format [, argument]...); // <stdio.h> or <wchar.h>
int sscanf_s( const char *buffer, const char *format [, argument ] ...); // <stdio.h>
int swscanf_s( const wchar_t *buffer, const wchar_t *format [, argument ] ...); // <stdio.h> or <wchar.h>
int fprintf_s( FILE *stream, const char *format [, argument ]...); // <stdio.h>
int fwscanf_s( FILE *stream, const wchar_t *format [, argument ]... ); // <stdio.h> or <wchar.h>
int fscanf_s( FILE *stream, const char *format [, argument ]... ); // <stdio.h>
int fwscanf_s( FILE *stream, const wchar_t *format [, argument ]... ); // <stdio.h> or <wchar.h>
errno_t strcpy_s( char *strDestination, size_t sizeInBytes, const char *strSource ); // <string.h>
errno_t wcscpy_s( wchar_t *strDestination, size_t sizeInWords, const wchar_t *strSource ); // <string.h> or <wchar.h>
errno_t fopen_s( FILE** pFile, const char *filename, const char *mode ); // <stdio.h>
errno_t _wfopen_s( FILE** pFile, const wchar_t *filename, const wchar_t *mode ); // <stdio.h> or <wchar.h>
errno_t mbstowcs_s( size_t *pConvertedChars, wchar_t *wcstr, size_t sizeInWords, const char *mbstr, size_t count ); // <stdlib.h>
errno_t wcstombs_s( size_t *pConvertedChars, char *mbstr, size_t sizeInBytes, const wchar_t *wcstr, size_t count ); // <stdlib.h>
errno_t rand_s( unsigned int* randomValue); // <stdlib.h>
下面是若干安全函数原型用到的数据类型的定义:
#include <crtdefs.h>
typedef int errno_t;
typedef unsigned short wchar_t;
#ifdef _WIN64
typedef unsigned __int64 size_t;
#else
typedef _W64 unsigned int size_t;
#endif
3)[宽]字符串转换
可以利用L运算符和若干函数在[单字节/多字节的]普通字符串和[双字节的]宽字符串之间进行相互转换。
l char -> wchar_t
n L运算符
在串常量前加上L运算符,可以将普通字符串转换为宽字符串;例如:
wchar_t *wstr = L"A string to a wide character string.";
CString str = L"A string to a wide character string.";
MessageBox(L"创建位图出错!", L"错误");
n AllocSysString函数
可以利用CString类的AllocSysString()函数来将普通字符串转换成宽字符串:
BSTR AllocSysString() const;
其中BSTR相当于wchar_t *的typedef类型。例如:
CString str("A string to a wide character string.");
wchar_t *wstr = str.AllocSysString();
MessageBox(wstr);
说明:CString类是VC中定义的MFC/ATL共享模板类CStringT的一个实现:
template< typename BaseType, class StringTraits > class CStringT :
public CSimpleStringT <BaseType, _CSTRING_IMPL_ :: _MFCDLLTraitsCheck < BaseType, StringTraits > ::c_bIsMFCDLLTraits> // <cstringt.h>或<atlstr.h>
typedef ATL::CStringT< TCHAR, StrTraitMFC_DLL< TCHAR > > CString; // <afxstr.h>
n mbstowcs[_s]函数
可以用<stdlib.h>中定义的多字节字符串到宽字符串的C语言转换函数:
size_t mbstowcs( wchar_t *wcstr, const char *mbstr, size_t count );
// 成功返回被转换的字符数,失败返回-1
// 若wcstr = NULL,则返回所需宽字符串的大小(宽字符数)
errno_t mbstowcs_s( size_t *pConvertedChars, wchar_t *wcstr, size_t sizeInWords, const char *mbstr, size_t count ); // 成功返回0
来将普通[多字节]字符串转换为宽字符串。例如:
char *str = "A sample string.";
wchar_t wstr[80];
size_t cn = 0; // 输出参数,用于存放被转换的字符数,包括null结束符'\0'
if (!mbstowcs_s(&cn, wstr, 80, str, strlen(str))) MessageBox(wstr);
else MessageBox(L"转换字符串出错!");
l wchar_t -> char(只能用于西文串,不能用于中文串)
只能利用<stdlib.h>中定义的宽字符串到多字节字符串的C语言转换函数:(返回值同前)
size_t wcstombs( char *mbstr, const wchar_t *wcstr, size_t count );
errno_t wcstombs_s( size_t *pConvertedChars, char *mbstr, size_t sizeInBytes, const wchar_t *wcstr, size_t count );
来将宽字符串转换为普通[多字节]字符串。例如:
char str[80];
wchar_t *wstr = L"A sample string.";
size_t cn = 0; // 输出参数,用于存放被转换的字符数,包括null结束符'\0'
if (wcstombs_s(&cn, str, 80, wstr, wcslen(wstr))) MessageBox(L"转换字符串出错!");
又例如:
int m, n;
const size_t bufSize = 300;
char buf[bufSize];
wchar_t wbuf[bufSize];
CString fn = pDoc->GetPathName();
wcscpy_s(wbuf, bufSize, fn);
size_t cn = 0;
wcstombs_s(&cn, buf, bufSize, wbuf, bufSize);
FILE *stream;
if (!fopen_s(&stream, buf, "rt")) {
fscanf_s(stream, "%d %d", &m, &n);
//……
}
安全CRT函数是微软公司对C/C++语言的扩展,其中的部分内容已于2003年提交给ISO作为C/C++标准下一版本的修改建议。在VC05/08中,如果不使用这些安全性函数,编译器会报告警告性错误。
1)常用的宽字符函数
由于Windows NT/2000/XP采用的是Unicode字符编码,字符都是双字节的。所以在MFC编程中,一般需要使用双字节的字符类型wchar_t和对应的字符串及其指针类型LPCWSTR和LPCTSTR,并在常数字符串前添加了L转换符,串长计算函数不能用strlen而改用wcslen,串格式打印函数也不能用sprintf,而是改用swprintf(字符和串格式符也从%c和%s改为%lc和%ls)。
wchar_t类型,在标准C++中为内置的数据类型和关键字;在C99标准中则为typedef类型,其等价的数据类型与具体的实现有关,在Win32和VC中定义为:
typedef unsigned short wchar_t; (双字节的无符号短整数)
下面是若干常用的宽字符函数(包含在ISO C99 / ISO C++的标准库中):
#include <wchar.h>
size_t wcslen(const wchar_t *s);
int wprintf(const wchar_t * format, ...);
int wscanf(const wchar_t * format, ...);
int swprintf(wchar_t * s, size_t n, const wchar_t * format, ...);
int swscanf(const wchar_t * s, const wchar_t * format, ...);
long int wcstol(const wchar_t * nptr, wchar_t ** endptr, int base);
float wcstof(const wchar_t * nptr, wchar_t ** endptr);
double wcstod(const wchar_t * nptr, wchar_t ** endptr);
#include <stdlib.h>
errno_t _itow_s( int value, wchar_t *buffer, size_t sizeInCharacters, int radix );
errno_t _ultow_s( unsigned long value, wchar_t *str, size_t sizeOfstr, int radix );
size_t mbstowcs( wchar_t *wcstr, const char *mbstr, size_t count );
size_t wcstombs( char *mbstr, const wchar_t *wcstr, size_t count );
2)常用的安全CRT函数
安全CRT(C Runtime Library = C运行时间库)函数,是微软公司对C/C++语言的扩展。它在原来函数名后添加了“_s”后缀;一般返回出错代码;并将原来的函数返回值,作为一个参数,添加到函数输入参数列表的最后;对带缓冲区参数的函数,还添加了表示缓冲区大小的输入参数,以防止内存溢出。
在VC05/08中,如果不使用这些安全性函数,编译器会报告警告性错误。
下面是若干常用的安全CRT函数:
char *gets_s( char *buffer, size_t sizeInCharacters); // <stdio.h>
wchar_t *_getws_s( wchar_t *buffer, size_t sizeInCharacters); // <stdio.h> or <wchar.h>
errno_t _itoa_s( int value, char *buffer, size_t sizeInCharacters, int radix ); // <stdlib.h>
errno_t _itow_s( int value, wchar_t *buffer, size_t sizeInCharacters, int radix ); // <stdlib.h>
errno_t _ultoa_s( unsigned long value, char *str, size_t sizeOfstr, int radix ); // <stdlib.h>
errno_t _ultow_s( unsigned long value, wchar_t *str, size_t sizeOfstr, int radix ); // <stdlib.h>
int printf_s( const char *format [, argument]... ); // <stdio.h>
int wprintf_s( const wchar_t *format [, argument]... ); // <stdio.h> or <wchar.h>
int scanf_s( const char *format [, argument]... ); // <stdio.h>
int wscanf_s( const wchar_t *format [, argument]... ); // <stdio.h> or <wchar.h>
int sprintf_s( char *buffer, size_t sizeOfBuffer, const char *format [, argument] ... ); // <stdio.h>
int swprintf_s( wchar_t *buffer, size_t sizeOfBuffer, const wchar_t *format [, argument]...); // <stdio.h> or <wchar.h>
int sscanf_s( const char *buffer, const char *format [, argument ] ...); // <stdio.h>
int swscanf_s( const wchar_t *buffer, const wchar_t *format [, argument ] ...); // <stdio.h> or <wchar.h>
int fprintf_s( FILE *stream, const char *format [, argument ]...); // <stdio.h>
int fwscanf_s( FILE *stream, const wchar_t *format [, argument ]... ); // <stdio.h> or <wchar.h>
int fscanf_s( FILE *stream, const char *format [, argument ]... ); // <stdio.h>
int fwscanf_s( FILE *stream, const wchar_t *format [, argument ]... ); // <stdio.h> or <wchar.h>
errno_t strcpy_s( char *strDestination, size_t sizeInBytes, const char *strSource ); // <string.h>
errno_t wcscpy_s( wchar_t *strDestination, size_t sizeInWords, const wchar_t *strSource ); // <string.h> or <wchar.h>
errno_t fopen_s( FILE** pFile, const char *filename, const char *mode ); // <stdio.h>
errno_t _wfopen_s( FILE** pFile, const wchar_t *filename, const wchar_t *mode ); // <stdio.h> or <wchar.h>
errno_t mbstowcs_s( size_t *pConvertedChars, wchar_t *wcstr, size_t sizeInWords, const char *mbstr, size_t count ); // <stdlib.h>
errno_t wcstombs_s( size_t *pConvertedChars, char *mbstr, size_t sizeInBytes, const wchar_t *wcstr, size_t count ); // <stdlib.h>
errno_t rand_s( unsigned int* randomValue); // <stdlib.h>
下面是若干安全函数原型用到的数据类型的定义:
#include <crtdefs.h>
typedef int errno_t;
typedef unsigned short wchar_t;
#ifdef _WIN64
typedef unsigned __int64 size_t;
#else
typedef _W64 unsigned int size_t;
#endif
3)[宽]字符串转换
可以利用L运算符和若干函数在[单字节/多字节的]普通字符串和[双字节的]宽字符串之间进行相互转换。
l char -> wchar_t
n L运算符
在串常量前加上L运算符,可以将普通字符串转换为宽字符串;例如:
wchar_t *wstr = L"A string to a wide character string.";
CString str = L"A string to a wide character string.";
MessageBox(L"创建位图出错!", L"错误");
n AllocSysString函数
可以利用CString类的AllocSysString()函数来将普通字符串转换成宽字符串:
BSTR AllocSysString() const;
其中BSTR相当于wchar_t *的typedef类型。例如:
CString str("A string to a wide character string.");
wchar_t *wstr = str.AllocSysString();
MessageBox(wstr);
说明:CString类是VC中定义的MFC/ATL共享模板类CStringT的一个实现:
template< typename BaseType, class StringTraits > class CStringT :
public CSimpleStringT <BaseType, _CSTRING_IMPL_ :: _MFCDLLTraitsCheck < BaseType, StringTraits > ::c_bIsMFCDLLTraits> // <cstringt.h>或<atlstr.h>
typedef ATL::CStringT< TCHAR, StrTraitMFC_DLL< TCHAR > > CString; // <afxstr.h>
n mbstowcs[_s]函数
可以用<stdlib.h>中定义的多字节字符串到宽字符串的C语言转换函数:
size_t mbstowcs( wchar_t *wcstr, const char *mbstr, size_t count );
// 成功返回被转换的字符数,失败返回-1
// 若wcstr = NULL,则返回所需宽字符串的大小(宽字符数)
errno_t mbstowcs_s( size_t *pConvertedChars, wchar_t *wcstr, size_t sizeInWords, const char *mbstr, size_t count ); // 成功返回0
来将普通[多字节]字符串转换为宽字符串。例如:
char *str = "A sample string.";
wchar_t wstr[80];
size_t cn = 0; // 输出参数,用于存放被转换的字符数,包括null结束符'\0'
if (!mbstowcs_s(&cn, wstr, 80, str, strlen(str))) MessageBox(wstr);
else MessageBox(L"转换字符串出错!");
l wchar_t -> char(只能用于西文串,不能用于中文串)
只能利用<stdlib.h>中定义的宽字符串到多字节字符串的C语言转换函数:(返回值同前)
size_t wcstombs( char *mbstr, const wchar_t *wcstr, size_t count );
errno_t wcstombs_s( size_t *pConvertedChars, char *mbstr, size_t sizeInBytes, const wchar_t *wcstr, size_t count );
来将宽字符串转换为普通[多字节]字符串。例如:
char str[80];
wchar_t *wstr = L"A sample string.";
size_t cn = 0; // 输出参数,用于存放被转换的字符数,包括null结束符'\0'
if (wcstombs_s(&cn, str, 80, wstr, wcslen(wstr))) MessageBox(L"转换字符串出错!");
又例如:
int m, n;
const size_t bufSize = 300;
char buf[bufSize];
wchar_t wbuf[bufSize];
CString fn = pDoc->GetPathName();
wcscpy_s(wbuf, bufSize, fn);
size_t cn = 0;
wcstombs_s(&cn, buf, bufSize, wbuf, bufSize);
FILE *stream;
if (!fopen_s(&stream, buf, "rt")) {
fscanf_s(stream, "%d %d", &m, &n);
//……
}
评论: 0 | 查看次数: 10178