_stprintf_s和_stscanf_s函数与UNICODE编码

_stprintf_s和_stscanf_s函数与UNICODE编码 
一、核心内容 
 该文档适用于微软的visual C++ 平台。  需要头文件: 
 MSDN上对stprintf_s和_stscanf_s函数的定义:  

TCHAR.H routine   

_stprintf_s  _stscanf_s  

_UNICODE & _MBCS not defined  sprintf_s  sscanf_s

_MBCS defined    sprintf_s sscanf_s

_UNICODE defined   swprintf_s    swscanf_s 

对应的代码为: 
#ifdef UNICODE 
#define _stprintf_s    swprintf_s #else 
#define _stprintf_s    sprintf_s 
 前面的t表示编码,后面的_s表示检查内存溢出,前面的_表示非标准库函数。 
 从上我们可以看出,_stprintf_s和_stscanf_s是为适应不同编码而定义的两个宏,在不同的编码环境下他们所表示的函数是不同的。  _s是security的意思,具体含义参见后面的Security Remarks部分。  

(1)

int   sprintf_s( char *buffer, size_t sizeOfBuffer, const char *format [, argument] ... );  //ANSI版本 

int   swprintf_s(wchar_t *buffer, size_t sizeOfBuffer, const wchar_t *format [,argument]...); //UNICODE版本

           这个函数的主要作用是将若干个argument按照format格式存到buffer中。  
            buffer:输出的字符 

            sizeOfBuffer:buffer的长度,以能存放的字符数计算,而不是已占用的字节数计算。非常关键。一个UNICODE字符占用2个字节。        

format:格式字符串,比如%s            

argument:可选参数 

(2)

int   sscanf_s( const char *buffer, const char *format [, argument ] ... ); 

int   swscanf_s( const wchar_t *buffer, const wchar_t *format [, argument ] ... ); 
 
函数具体细节参考http://msdn.microsoft.com/en-us/library/t6z7bya3(v=vs.80).aspx 。 
     这个函数的主要作用是从buffer中读取指定格式(format)的字符到相应的argument中。参数同上 Security Remarks: 
Unlike the less secure version sscanf, a buffer size parameter sizeOfBuffer is required when using the type field characters c, C, s, S and [. This parameter must be supplied as an additional parameter after each buffer which requires it. 用于检查内存是否溢出。 几个需要注意的细节: 
 为了让编译器识别Unicode字符串,必须以在前面加一个“L”, 定义宽字节类型方法如下:L“ABC”,表示字符串“ABC”是用UNICODE编码
的。 
 char与wchar_t的区别: char中存放的是单字节型的字符,wchar_t中存放的是双字节型的字符,TCHAR在定义了_UNICODE时等同于wchar_t,
在未定义_UNICODE时等同于char。 
 
例子1 (sscanf_s和printf_s,用于ANSI编码): 
// crt_sscanf_s.c 
// This program uses sscanf_s to read data items // from a string named tokenstring, then displays them.   

#include  
int main( void ) { 
   char  tokenstring[] = "15 12 14...";    char  s[81];    char  c;    int   i;    float fp;  
   // Input various data from tokenstring: 
   // max 80 character string plus NULL terminator 

   sscanf_s( tokenstring, "%s", s, sizeof(s) ); //对照上面的Security Remarks部分进行理解    

   sscanf_s( tokenstring, "%c", &c, sizeof(char) );    

   sscanf_s( tokenstring, "%d", &i );    

   sscanf_s( tokenstring, "%f", &fp );  

   // Output the data read 

   printf_s( "String    = %s\n", s );    

   printf_s( "Character = %c\n", c );    

   printf_s( "Integer:  = %d\n", i );    

   printf_s( "Real:     = %f\n", fp );    

   return 0; } 

 
例子2 (swscanf_s和wprintf_s,用于UNICODE编码): 

// crt_swscanf_s.c 
// This program uses swscanf_s to read data items // from a string named tokenstring, then displays them.   
#include  
int main( void ) { 
   wchar_t  tokenstring[] = L"15 12 14...";    wchar_t  s[81];    wchar_t  c;    int   i;    float fp;  
   // Input various data from tokenstring: 
   // max 80 character string plus NULL terminator    cout<    swscanf_s( tokenstring, L"%s", s, _countof(s));  

   swscanf_s( tokenstring, L"%c", &c, sizeof(wchar_t) );    

   swscanf_s( tokenstring, L"%d", &i );    

   swscanf_s( tokenstring, L"%f", &fp );  

   // Output the data read 

   wprintf_s( L"String    = %s\n", s );    

   wprintf_s( L"Character = %c\n", c );    

   wprintf_s( L"Integer:  = %d\n", i ); 

   wprintf_s( L"Real:     = %f\n", fp );    

   return 0; } 

 
例子3 (_stscanf_s和_tprintf_s,将例1和例2的代码统一处理): 
#include  
int main( void ) { 
   TCHAR  tokenstring[] = TEXT("15 12 14...");    TCHAR  s[81];    TCHAR  c;    int   i;    float fp;  
   // Input various data from tokenstring: 
   // max 80 character string plus NULL terminator    cout<

   _stscanf_s( tokenstring, TEXT("%s"), s, _countof(s));     

   _stscanf_s( tokenstring, TEXT("%c"), &c, sizeof(TCHAR) );    

   _stscanf_s( tokenstring, TEXT("%d"), &i );   

    _stscanf_s( tokenstring, TEXT("%f"), &fp );  

   // Output the data read 

   _tprintf_s( TEXT("String    = %s\n"), s );    

   _tprintf_s( TEXT("Character = %c\n"), c );

wchar_t *fgetws( wchar_t *string, int n, FILE *stream);   //UNICODE版本 
 其中,第二个参数n的值是最多可以读出的字符数目,该值不应该大于参数一所对应的字符数组的长度。 
 函数的作用是从第三个参数指定的文件流中读取文件的一行信息,存放到参数一string所对应的字符数组中,读出的字符数据包括换行符“\n”。这
一点需要注意。 
 如果想从键盘读入一行字符,第三个参数为 stdin . 例如,char buf[10];  fgets(buf, 10, stdin)   gets()函数已经过时了,用fgets()函数代替gets()函数。 
 _fgetts是一个宏,如果定义了UNICODE,就是fgetws函数;如果未定义UNICODE,就是fgets函数。  用TCHAR代替char,用_fgetts代替fgets或fgetws。就将ANSI和UNICODE函数编码统一起来了。 对这两个函数的更具体的讲解,请参考http://wenku.baidu.com/view/d66839f57c1cfad6195fa781.html 
3. ANSI和UNICODE字符和字符串处理函数,参考网页http://blog.sina.com.cn/s/blog_6b5a0745010108fh.html 
  统一ANSI和UNICODE字符和字符串处理函数的宏定义,在上述网页中没有列出,这些宏的规律是“把UNICODE字符和字符串处理函数中的w标识替换为t,并在前面加上一个下划线_”。例如, 
TCHAR.H routine 
_UNICODE defined 
_MBCS defined 
_UNICODE & _MBCS not defined 
_tcslen 
wcslen 
strlen 
strlen 
_fgetts fgetws fgets fgets _tcsncpy 
wcsncpy 
strncpy 
strncpy 
 
4. 注意:如果在程序中使用了TCHAR,那么就不应该使用ANSI的strXXX函数或者Unicode的wcsXXX函数了,而必须使用tchar.h中定义的_tcsXXX函数。 
5. 有人建议,不要再使用TCHAR和_T了!他分析了原因后总结:如果您正开始一个新的项目,请无论如何也要顶住压力,直接使用UNICODE编码!切记!您只需要对您的组员进行10分钟的培训,记住strcpy用 wcscpy,sprintf用swprintf代替,常数前加L,就可以了!它不会花您很多时间的,带给您的是稳定和安全!个人觉得有道理。



你可能感兴趣的:(VC,C++)