(精华版)_stprintf_s和_stscanf_s函数与UNICODE编码
- 格式:doc
- 大小:78.50 KB
- 文档页数:8
sprintf⽤法⼤全与实例(转载)sprintf格式Ruby的sprintf格式与C语⾔的sprintf(3)基本相同。
但还是有些差别: 它没有针对C特有类型的修饰符,如short或long等; 它包含2进制数的指⽰符(%b); 它不⽀持sprintf的⽅⾔式的语法。
下⾯就对ruby的sprintf格式进⾏详细的说明。
sprintf格式的规格如下所⽰。
[]中的部分是可选的。
%[指定参数$][标识符][宽度][.精度]指⽰符若想输出`%'本⾝时, 请这样`%%'处理。
下⾯就分别介绍⼀下各元素的⽤法。
标识符包括`#', `+', ` '(空格), `-'和`0'这5个。
使⽤2进制、8进制、16进制的指⽰符(`b', `o', `x', `X')时, 会分别添加"0b", "0", "0x", "0X"前缀。
p sprintf("%#b", 10) # => "0b1010"p sprintf("%#o", 10) # => "012"p sprintf("%#x", 10) # => "0xa"p sprintf("%#X", 10) # => "0XA"对于浮点数 (`f', `e', `E', `g', `G'), 则必定在输出中添加"."。
p sprintf("%.0f", 10) # => "10"p sprintf("%#.0f", 10) # => "10."p sprintf("%.0e", 10) # => "1e+01"p sprintf("%#.0e", 10) # => "1.e+01"`g', `G'除了具有上述特性外, 还会在末尾添加多余的0。
sscanf正则规则
sscanf是C语言中用于解析字符串的函数之一,它可以根据指定的格式规则将字符串解析成所需的数据类型。
它的正则规则包括以下几个方面:
1. 数字格式
在解析数字时,sscanf使用以下格式规则:
%d 表示解析十进制整数
%u 表示解析无符号十进制整数
%o 表示解析八进制无符号整数
%x 表示解析十六进制无符号整数
%f 表示解析浮点数
%e 表示解析科学计数法浮点数
%c 表示解析字符
%s 表示解析字符串
%[] 表示解析字符集
%n 表示计算已解析的字符数
2. 字符串格式
在解析字符串时,sscanf使用以下格式规则:
%s 表示解析字符串,将忽略空格字符,直到遇到下一个非空格字符为止。
3. 宽度限定
在宽度限定中,可以使用数字指定要解析的字符数,例如:
%2s 表示解析最多包含2个字符的字符串
%.*s 表示解析任意宽度的字符串,并将宽度保存在参数中。
4. 精度限定
在精度限定中,可以使用数字指定要解析的精度的位数或小数位数,例如:
%.2f 表示解析浮点数时保留两位小数
%.5s 表示解析字符串时最多解析5个字符
5. 符号格式
在符号格式中,可以使用以下格式规则:
%+ 表示要求必须是有符号的数值
%- 表示要求必须是有符号的数值,并且需要从低位到高位解析。
6. 特殊格式
除了上述格式规则之外,还有一些特殊的格式规则:
%n 表示计算已解析的字符数,并将该值存储在参数中。
%t 表示跳过一个字符。
宽字符处理函数函数与普通函数对照表字符分类:宽字符函数普通C函数描述iswalnum()isalnum()测试字符是否为数字或字母iswalpha()isalpha()测试字符是否是字母iswcntrl()iscntrl()测试字符是否是控制符iswdigit()isdigit()测试字符是否为数字iswgraph()isgraph()测试字符是否是可见字符iswlower()islower()测试字符是否是小写字符iswprint()isprint()测试字符是否是可打印字符iswpunct()ispunct()测试字符是否是标点符号iswspace()isspace()测试字符是否是空白符号iswupper()isupper()测试字符是否是大写字符iswxdigit()isxdigit()测试字符是否是十六进制的数字大小写转换:宽字符函数普通C函数描述towlower()tolower()把字符转换为小写towupper()toupper()把字符转换为大写字符比较:宽字符函数普通C函数描述wcscoll()strcoll()比较字符串日期和时间转换:宽字符函数描述strftime()根据指定的字符串格式和locale设置格式化日期和时间wcsftime()根据指定的字符串格式和locale设置格式化日期和时间,并返回宽字符串strptime()根据指定格式把字符串转换为时间值,是strftime的反过程打印和扫描字符串:宽字符函数描述fprintf()/fwprintf()使用vararg参量的格式化输出fscanf()/fwscanf()格式化读入printf()使用vararg参量的格式化输出到标准输出scanf()从标准输入的格式化读入sprintf()/swprintf()根据vararg参量表格式化成字符串sscanf()以字符串作格式化读入vfprintf()/vfwprintf()使用stdarg参量表格式化输出到文件vprintf()使用stdarg参量表格式化输出到标准输出vsprintf()/vswprintf()格式化stdarg参量表并写到字符串数字转换:宽字符函数普通C函数描述wcstod()strtod()把宽字符的初始部分转换为双精度浮点数wcstol()strtol()把宽字符的初始部分转换为长整数wcstoul()strtoul()把宽字符的初始部分转换为无符号长整数多字节字符和宽字符转换及操作:宽字符函数描述mblen()根据locale的设置确定字符的字节数mbstowcs()把多字节字符串转换为宽字符串mbtowc()/btowc()把多字节字符转换为宽字符wcstombs()把宽字符串转换为多字节字符串wctomb()/wctob()把宽字符转换为多字节字符输入和输出:宽字符函数普通C函数描述fgetwc()fgetc()从流中读入一个字符并转换为宽字符fgetws()fgets()从流中读入一个字符串并转换为宽字符串fputwc()fputc()把宽字符转换为多字节字符并且输出到标准输出fputws()fputs()把宽字符串转换为多字节字符并且输出到标准输出串getwc()getc()从标准输入中读取字符,并且转换为宽字符getwchar()getchar()从标准输入中读取字符,并且转换为宽字符None gets()使用fgetws()putwc()putc()把宽字符转换成多字节字符并且写到标准输出putwchar()putchar()把宽字符转换成多字节字符并且写到标准输出None puts()使用fputws()ungetwc()ungetc()把一个宽字符放回到输入流中字符串操作:宽字符函数普通C函数描述wcscat()strcat()把一个字符串接到另一个字符串的尾部wcsncat()strncat()类似于wcscat(),而且指定粘接字符串的粘接长度.wcschr()strchr()查找子字符串的第一个位置wcsrchr()strrchr()从尾部开始查找子字符串出现的第一个位置wcspbrk()strpbrk()从一字符字符串中查找另一字符串中任何一个字符第一次出现的位置wcswcs()/wcsstr()strchr()在一字符串中查找另一字符串第一次出现的位置wcscspn()strcspn()返回不包含第二个字符串的的初始数目wcsspn()strspn()返回包含第二个字符串的初始数目wcscpy()strcpy()拷贝字符串wcsncpy()strncpy()类似于wcscpy(),同时指定拷贝的数目wcscmp()strcmp()比较两个宽字符串wcsncmp()strncmp()类似于wcscmp(),还要指定比较字符字符串的数目wcslen()strlen()获得宽字符串的数目wcstok()strtok()根据标示符把宽字符串分解成一系列字符串wcswidth()None 获得宽字符串的宽度wcwidth()None 获得宽字符的宽度另外还有对应于memory操作的wmemcpy(),wmemchr(),wmemcmp(),wmemmove (),wmemset().操作ANSI串函数Unicode 串函数Length strlen wcslen Concatenate strcat, strncat wcscat, wcsncat, RtlAppendUnicodeStringT oString, RtlAppendUnicodeToStringCopy strcpy, strncpy, RtlCopyString wcscpy, wcsncpy, RtlCopyUnicodeStringReverse _strrev _wcsrev Compare strcmp, strncmp, _stricmp, _strnicmp, RtlCompareString, RtlEqualString wcscmp, wcsncmp, _wcsicmp, _wcsnicmp, RtlCompareUnicodeString, RtlEqualUnicodeString, RtlPrefixUnicodeStringInitialize _strset, _strnset, RtlInitAnsiString, RtlInitString _wcsnset, RtlInitUnicodeStringSearch strchr, strrchr, strspn, strstr wcschr, wcsrchr, wcsspn, wcsstrUpper/lowercase _strlwr, _strupr, RtlUpperString _wcslwr, _wcsupr, RtlUpcaseUnicodeStringCharacter isdigit, islower, isprint, isspace, isupper, isxdigit, tolower, toupper, RtlUpperChar towlower, towupper, RtlUpcaseUnicodeCharFormat sprintf, vsprintf, _snprintf, _vsnprintf,_splitpath swprintf, _snwprintf,_wsplitpathString conversion atoi, atol, _itoa _itow, RtlIntegerToUnicodeString, RtlUnicodeStringToIntegerType conversion RtlAnsiStringToUnicodeSize, RtlAnsiStringToUnicodeString RtlUnicodeStringToAnsiStringMemory release RtlFreeAnsiString RtlFreeUnicodeString用C函数来转换Unicode和ANSI文字char sChar[MAX_PATH];const WCHAR wChar[] = L"我的朋友";// 把wChar这个Unicode字符串转换成ANSI字符串,保存到sChar,并且返回ANSI的字符串大小,如果失败,则返回-1wcstombs(sChar, wChar, MAX_PATH);这样是运行不过不去的,总是返回-1。
sscanf_s函数的用法sscanf_s函数是C语言标准库中的一个函数,用于将字符串解析为指定的格式,可以用来读取字符串中的数据,类似于scanf函数,但是sscanf_s函数相比于scanf函数更加安全,提供了更多的错误检测机制。
```cint sscanf_s(const char *str, const char *format, ...);```其中,str是要解析的字符串,format是格式字符串,用于指定解析的格式,...是格式字符串中的转换说明符对应的参数。
下面是sscanf_s函数的具体用法和一些注意事项:1.基本用法可以使用sscanf_s函数来解析字符串中的各种数据类型,如整数、浮点数、字符等。
```c#include <stdio.h>int maichar str[] = "hello world 123 3.14";char data[20];int num;float pi;printf("data: %s\n", data);printf("num: %d\n", num);printf("pi: %f\n", pi);return 0;```输出结果为:```data: hellonum: 123```通过格式字符串"%s %d %f"来指定解析的格式,%s表示字符串,%d 表示整数,%f表示浮点数。
可以通过&运算符获取变量的地址传递给sscanf_s函数。
2.安全性检查```c#include <stdio.h>int maichar str[] = "hello world 123 3.14";char data[5];int num;float pi;printf("data: %s\n", data);printf("num: %d\n", num);printf("pi: %f\n", pi);return 0;```输出结果为:```data: hellnum: 123```在上面的例子中,将data的最大宽度设置为4,所以只读取了字符串"hell",省略了末尾的字符"o"。
`fprintf_s`是C++中的安全版本的文件写入函数,它比标准的`fprintf`函数更加安全,因为它对输入的格式化字符串进行了验证和清理。
`fprintf_s`函数的原型如下:```c++int fprintf_s(FILE *stream, const char *format, ...);```其中,`stream`是指向要写入的文件的指针,`format`是包含格式说明符的格式化字符串,后面跟着要写入文件的数据。
与标准的`fprintf`函数类似,`fprintf_s`将数据写入指定的文件流中。
但是,`fprintf_s`会检查格式化字符串中的每个格式说明符,以确保它们都是合法的,并且不会发生缓冲区溢出。
如果发现无效的格式说明符或缓冲区溢出,函数将返回一个负值,并设置`errno`为`EILSEQ`或`ERANGE`。
下面是一个使用`fprintf_s`函数的示例:```c++#include <stdio.h>#include <errno.h>#include <string.h>int main() {FILE *fp = fopen("file.txt", "w");if (fp == NULL) {perror("Error opening file");return 1;}char format[] = "%s %d %f"; // 格式化字符串,其中包含三个格式说明符char *str = "Hello"; // 要写入文件的字符串int num = 42; // 要写入文件的整数double pi = 3.14159; // 要写入文件的浮点数int result = fprintf_s(fp, format, str, num, pi); // 将数据写入文件if (result < 0) {perror("Error writing to file");return 1;}fclose(fp); // 关闭文件流return 0;}```在上面的示例中,我们使用`fprintf_s`函数将一个字符串、一个整数和一个浮点数写入一个文件中。
fscanf和fprintf函数fscanf和fprintf函数是C语言中用来处理文件的输入输出函数之一。
fscanf函数用于从文件中读取数据,而fprintf函数则用于将数据写入到文件中。
这两个函数都是非常常用的文件操作函数,几乎所有的C 语言程序都会用到它们。
fscanf函数的使用步骤如下:1.打开文件:使用fopen函数打开需要读取的文件。
2.使用fscanf函数读取文件中的数据。
fscanf函数可以根据需要读取不同类型的数据,包括整数、浮点数、字符等。
3.使用fclose函数关闭文件。
下面是一个读取整数数据的示例代码:```FILE *fp;int n;fp = fopen("data.txt", "r");if(fp == NULL) {printf("无法打开文件\n");return 1;}fscanf(fp, "%d", &n);fclose(fp);```这段代码会尝试打开名为"data.txt"的文件,如果成功打开,则使用fscanf函数读取文件中的一个整数数据,读取的数据会存储到变量n 中。
最后,使用fclose函数关闭文件。
与fscanf函数类似,fprintf函数的使用步骤如下:1.打开文件:使用fopen函数打开需要写入的文件。
2.使用fprintf函数将数据写入文件中。
fprintf函数可以根据需要写入不同类型的数据,包括整数、浮点数、字符等。
3.使用fclose函数关闭文件。
下面是一个将整数数据写入文件的示例代码:```FILE *fp;int n = 123;fp = fopen("data.txt", "w");if(fp == NULL) {printf("无法打开文件\n");return 1;}fprintf(fp, "%d", n);fclose(fp);```这段代码会尝试打开名为"data.txt"的文件,并使用fprintf函数将变量n中的整数数据写入到文件中,最后关闭文件。
sprintf、vsprintf、sprintf_s、vsprintf_s、_snprin。
看了题⽬中的⼏个函数名是不是有点头晕?为了防⽌以后总在这样的细节⾥纠缠不清,今天我们就来好好地辨析⼀下这⼏个函数的异同。
实验环境:Windows下使⽤VS2017Linux下使⽤gcc4.9.4为了验证函数的安全性我们设计了如下结构const int len = 4;#pragma pack(push)#pragma pack(1)struct Data{char buf[len];char guard;Data(){for (int i = 0; i < len; ++i){buf[i] = '*';}guard = 0xF;}void Display(){std::cout << "sizeof(Data) = " << sizeof(Data) << std::endl;std::cout << "buf = " << buf << std::endl;std::cout << "guard = " << (unsigned int)guard << std::endl;if (guard != 0xF){std::cout << "memory has been broken." << std::endl;}std::cout << "---------------" << std::endl;}};#pragma pack(pop)当我们把数据写到Data.buf字段中去的时候,如果发⽣了内存越界的情况,Data.gurad字段的内存会被修改。
strcpy是一个字符串拷贝的函数,它的函数原型为strcpy(char *dst, const char *src);将src开始的一段字符串拷贝到dst开始的内存中去,结束的标志符号为'\0',由于拷贝的长度不是由我们自己控制的,所以这个字符串拷贝很容易出错。
具备字符串拷贝功能的函数有memcpy,这是一个内存拷贝函数,它的函数原型为memcpy(char *dst, const char* src, unsigned int len);将长度为len的一段内存,从src拷贝到dst中去,这个函数的长度可控。
但是会有内存叠加的问题。
这个问题很多公司的笔试题都有出现。
sprintf,snprintf都是格式化函数。
将一段数据通过特定的格式,格式化到一个字符串缓冲区中去。
sprintf和snprintf的区别是sprintf格式化的函数的长度不可控,有可能格式化后的字符串会超出缓冲区的大小,造成溢出。
而snprintf对于长度可控。
但是,无论是sprintf还是snprintf,格式化字符串的时候,都是使用'\0'作为格式化结束符号,例如char buf[1024];char *a="hello\0world";int b = 10;sprintf(buf, "%s%d",a,b);格式化后buf的内容为hello10,二不是hello\0world10,这是因为\0是一个字符串结束符号。
在特定情况下,如果我们想格式化后的内容为hello\0world10的话,就要使用到内存拷贝函数了。
memcpy(buf, a, 11);//拷贝11个字节sprintf(buf+11, "%d",b); //从buf的第十一位开始,不加11的话又复制到第一位了,覆盖了hello中的前几位接着格式化一个整型,就可以得到想要的数据了。
swprintf函数用法一、概述swprintf函数是C/C++中的一个宽字符函数,用于将格式化的数据写入一个数组。
swprintf函数与printf函数类似,区别在于前者将结果输出到一个宽字符数组中,而后者输出到标准输出流中。
swprintf函数能够格式化一系列不同类型的数据,并提供了丰富的格式化选项。
二、函数原型swprintf函数的函数原型如下:int swprintf(wchar_t* str, size_t size, const wchar_t* format, ...);其中: - str是指向宽字符数组的指针,用于存放格式化后的字符串; - size是目标数组的大小,确保不会发生溢出; - format是一个格式化字符串,指定了要输出的数据和格式化选项; - ...是可变参数列表,根据format中的格式化选项传入相应的参数。
三、使用示例下面是一个使用swprintf函数的示例:#include <stdio.h>#include <wchar.h>int main() {wchar_t buffer[100];int count = swprintf(buffer, 100, L"Hello, %s! Today is %d-%d-%d.", L"John ", 2022, 10, 1);wprintf(L"%ls\n", buffer);wprintf(L"Number of characters written: %d\n", count);return 0;}运行上述代码,将会输出:Hello, John! Today is 2022-10-1.Number of characters written: 29上述示例中,首先定义了一个宽字符数组buffer,大小为100。
fprintf_s函数的用法
fprintf_s函数是C语言中的一个输出函数,用来将格式化的数据输出到指定的文件中。
它的用法基本上与printf函数相同,只是
在输出数据时需要指定一个文件指针。
fprintf_s函数的语法如下:
int fprintf_s(FILE* stream, const char* format, …);
其中,stream是指向要输出的文件的指针,format是格式化字
符串,用来指定输出的格式,后面的省略号表示可变参数列表,用来指定要输出的数据。
和printf函数一样,fprintf_s函数也支持很多格式化符号,如%d、%f、%s等等。
此外,还可以使用一些特殊的格式化符号,如%*.*f,用来指定浮点数的输出精度。
需要注意的是,fprintf_s函数是安全的输出函数,它会检查输出的数据是否超过了指定的缓冲区大小,以避免缓冲区溢出的情况发生。
如果输出的数据超过了缓冲区大小,fprintf_s函数会返回一个非零值,表示输出失败。
综上所述,fprintf_s函数是一个非常常用的C语言输出函数,它可以将格式化的数据输出到指定的文件中,并且具有一定的安全性。
在实际的编程过程中,我们可以根据需要灵活地使用它来完成数据输出的任务。
- 1 -。
版权所有。
转载请注明出处。
_stprintf_s和_stscanf_s函数与UNICODE编码一、核心内容⏹该文档适用于微软的visual C++ 平台。
⏹需要头文件:<TCHAR.H>⏹MSDN上对stprintf_s和_stscanf_s函数的定义:TCHAR.H routine _UNICODE & _MBCS not defined _MBCS defined _UNICODE defined_stprintf_s sprintf_s sprintf_s swprintf_s_stscanf_s sscanf_s sscanf_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:格式字符串,比如%sargument:可选参数(2)int sscanf_s( const char *buffer, const char *format [, argument ] ... );int swscanf_s( const wchar_t *buffer, const wchar_t *format [, argument ] ... );函数具体细节参考/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 <stdio.h>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 terminatorsscanf_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 readprintf_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 <stdio.h>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 terminatorcout<<sizeof(wchar_t)<<" "<<_countof(s)<<endl;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 readwprintf_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 <stdio.h>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 terminatorcout<<sizeof(TCHAR)<<" "<<_countof(s)<<endl;_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 );_tprintf_s( TEXT("Integer: = %d\n"), i );_tprintf_s( TEXT("Real: = %f\n"), fp );return 0;}例子4(_stprintf_s ):TCHAR szText[32] = {0};_stprintf_s(szText, 32,TEXT("%d"),100); // 可以将int 型转化为宽字节同时也可以将若干个变量整合为一个_stprintf_s(szText, 32,TEXT("%d"),char[0], char[1],.......);用法总结:1. 用TCHAR代替char2. 用TEXT(“%s%d”)代替“%s%d”3. 用_stscanf_s、_tprintf_s、_stprintf_s代替sscanf、printf、sprintf函数。