本篇介绍wchar.h头文件中的安全函数学习之wprintf_s,fwprintf_s,snwprintf_s,swprintf_s,vwprintf_s,vfwprintf_s,vswprint_s, _vsnwprintf_s。
实验环境window11, VS2022
wprintf / wprintf_s example
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <locale.h>
#include <wchar.h>
#include <limits.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdarg.h>
#include <wtypes.h>
#include <memory.h>
#pragma warning(disable:4996)
int main(void)
{
setlocale(LC_ALL, "");
int ret = wprintf(L"床前明月光,疑似地上霜。");
printf("ret = %d\n", ret);
int ret2 = wprintf(L"无敌风火轮");
printf("ret2 = %d\n", ret2);
//wprintf_s example
char ch = 'h', * string = "computer";
int count = -9234;
double fp = 251.7366;
wchar_t wch = L'w', * wstring = L"Unicode";
/* Display integers. */
printf_s("Integer formats:\n"
" Decimal: %d Justified: %.6d Unsigned: %u\n",
count, count, count);
printf_s("Decimal %d as:\n Hex: %Xh C hex: 0x%x Octal: %o\n",
count, count, count, count);
/* Display in different radixes. */
printf_s("Digits 10 equal:\n Hex: %i Octal: %i Decimal: %i\n",
0x10, 010, 10);
/* Display characters. */
printf_s("Characters in field (1):\n%10c%5hc%5C%5lc\n", ch, ch, wch, wch);
wprintf_s(L"Characters in field (2):\n%10C%5hc%5c%5lc\n", ch, ch, wch, wch);
/* Display strings. */
printf_s("Strings in field (1):\n%25s\n%25.4hs\n %S%25.3ls\n",
string, string, wstring, wstring);
wprintf_s(L"Strings in field (2):\n%25S\n%25.4hs\n %s%25.3ls\n",
string, string, wstring, wstring);
/* Display real numbers. */
printf_s("Real numbers:\n %f %.2f %e %E\n", fp, fp, fp, fp);
/* Display pointer. */
printf_s("\nAddress as: %p\n", &count);
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/io/fwprintf
https://www.standards.wiki/c/c_library_wchar_function_wprintf.html
https://www.standards.wiki/c/c_appendix_secure_function_wprintf_s.html
https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/printf-printf-l-wprintf-wprintf-l?view=msvc-170
https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/printf-s-printf-s-l-wprintf-s-wprintf-s-l?view=msvc-170
fwprintf / fwprintf_s example
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <locale.h>
#include <wchar.h>
#include <limits.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdarg.h>
#include <wtypes.h>
#include <memory.h>
#pragma warning(disable:4996)
int main(void)
{
setlocale(LC_ALL, "");
wchar_t wStr[100];
fwprintf(stdout, L"我的座右铭:\n");
fgetws(wStr, 100, stdin);
fwprintf(stdout, L"%ls", wStr);
//fwprintf_s example
FILE* stream;
int i = 10;
double fp = 1.5;
wchar_t fwps[] = L"this is a string";
fopen_s(&stream, "fwprintf_s.out", "w");
if (stream)
{
int ret = fwprintf_s(stream, L"%ls\n", fwps);
printf("ret = %d\n", ret);
ret = fwprintf_s(stream, L"%d\n", i);
printf("ret = %d\n", ret);
ret = fwprintf_s(stream, L"%f\n", fp);
printf("ret = %d\n", ret);
fclose(stream);
system("type fwprintf_s.out");
}
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/io/fwprintf
https://www.standards.wiki/c/c_library_wchar_function_fwprintf.html
https://www.standards.wiki/c/c_appendix_secure_function_fwprintf_s.html
https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/fprintf-fprintf-l-fwprintf-fwprintf-l?view=msvc-170
https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/fprintf-s-fprintf-s-l-fwprintf-s-fwprintf-s-l?view=msvc-170
swprintf / swprintf_s example
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <locale.h>
#include <wchar.h>
#include <limits.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdarg.h>
#include <wtypes.h>
#include <memory.h>
#pragma warning(disable:4996)
int main(void)
{
setlocale(LC_ALL, "");
wchar_t wStr[16];
swprintf(wStr, 12, L"先天下之忧而忧,后天下之乐而乐。");
wprintf(L"%ls\n", wStr);
//swprintf_s example
wchar_t buf[100];
int len = swprintf_s(buf, 100, L"%s", L"Hello world");
wprintf(L"%ls\n", buf);
printf("wrote %d characters\n", len);
len = swprintf_s(buf, 100, L"%s", L"Hello\xffff world");
wprintf(L"%ls\n", buf);
// swprintf_s fails because string contains WEOF (\xffff)
printf("wrote %d characters\n", len);
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/io/fwprintf
https://www.standards.wiki/c/c_library_wchar_function_swprintf.html
https://www.standards.wiki/c/c_appendix_secure_function_swprintf_s.html
https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/sprintf-sprintf-l-swprintf-swprintf-l-swprintf-l?view=msvc-170
https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/sprintf-s-sprintf-s-l-swprintf-s-swprintf-s-l?view=msvc-170
_snwprintf / _snwprintf_s example
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <locale.h>
#include <wchar.h>
#include <limits.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdarg.h>
#include <wtypes.h>
#include <memory.h>
#pragma warning(disable:4996)
int main(void)
{
wchar_t narrow_str[] = L"z\u00df\u6c34\U0001f34c";
// 或 "zß水🍌"
// 或 "\x7a\xc3\x9f\xe6\xb0\xb4\xf0\x9f\x8d\x8c";
wchar_t warr[29]; // 期待的字符串为 28 字节加 1 个空终止符
setlocale(LC_ALL, "en_US.utf8");
//setlocale(LC_ALL, "");
//int __CRTDECL _snwprintf(
// _Out_writes_opt_(_BufferCount) _Post_maybez_ wchar_t* _Buffer,
// _In_ size_t _BufferCount,
// _In_z_ _Printf_format_string_ wchar_t const* _Format,
// ...)
_snwprintf(warr, sizeof warr / sizeof * warr, L"从 UTF-8 转换: %ls", narrow_str);
wprintf(L"%ls\n", warr);
//int __CRTDECL _snwprintf_s(
// _Out_writes_opt_(_BufferCount) _Always_(_Post_z_) wchar_t* const _Buffer,
// _In_ size_t const _BufferCount,
// _In_ size_t const _MaxCount,
// _In_z_ _Printf_format_string_ wchar_t const* const _Format,
// ...)
wchar_t warrs[29];
wchar_t srcs[] = L"长江长城黄山黄河";
_snwprintf_s(warrs, sizeof warrs / sizeof * warrs, 6, L"%ls", srcs); //取srcs前面6个放到warrs中
wprintf(L"%ls\n", warrs);
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/io/fwprintf
https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/snprintf-snprintf-snprintf-l-snwprintf-snwprintf-l?view=msvc-170
https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/snprintf-s-snprintf-s-l-snwprintf-s-snwprintf-s-l?view=msvc-170
vwprintf / vwprintf_s example
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <locale.h>
#include <wchar.h>
#include <limits.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdarg.h>
#include <wtypes.h>
#include <memory.h>
#pragma warning(disable:4996)
void vwprintf_test(const wchar_t* format, ...)
{
static int vwp = 0;
wprintf(L"档案%d\n", ++vwp);
va_list args;
va_start(args, format);
vwprintf(format, args);
va_end(args);
putwchar('\n');
}
void vwprintf_s_test(const wchar_t* format, ...)
{
static int vwps = 0;
wprintf_s(L"档案%d\n", ++vwps);
va_list args;
va_start(args, format);
vwprintf_s(format, args);
va_end(args);
putwchar('\n');
}
int main(void)
{
setlocale(LC_ALL, "");
vwprintf_test(L"vwprintf 姓名: %ls\n", L"张三");
vwprintf_test(L"vwprintf 姓名: %ls\n性别:%lc\n", L"李四", L'男');
vwprintf_test(L"vwprintf姓名: %ls\n性别:%lc\n年龄:%d\n", L"王五", L'男', 25);
//vwprintf_s example
vwprintf_s_test(L"vwprintf_s 姓名: %ls\n", L"张三");
vwprintf_s_test(L"vwprintf_s 姓名: %ls\n性别:%lc\n", L"李四", L'男');
vwprintf_s_test(L"vwprintf_s 姓名: %ls\n性别:%lc\n年龄:%d\n", L"王五", L'男', 25);
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/io/vfwprintf
https://www.standards.wiki/c/c_library_wchar_function_vwprintf.html
https://www.standards.wiki/c/c_appendix_secure_function_vwprintf_s.html
https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/vprintf-vprintf-l-vwprintf-vwprintf-l?view=msvc-170
https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/vprintf-s-vprintf-s-l-vwprintf-s-vwprintf-s-l?view=msvc-170
vfwprintf / vfwprintf_s example
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <locale.h>
#include <wchar.h>
#include <limits.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdarg.h>
#include <wtypes.h>
#include <memory.h>
#pragma warning(disable:4996)
void vfwprintf_test(const wchar_t* format, ...)
{
static int vfwp = 0;
wprintf(L"档案%d\n", ++vfwp);
va_list args;
va_start(args, format);
vfwprintf(stdout, format, args);
va_end(args);
putwchar('\n');
}
void vfwprintf_s_test(const wchar_t* format, ...)
{
static int vfwps = 0;
wprintf_s(L"档案%d\n", ++vfwps);
va_list args;
va_start(args, format);
vfwprintf_s(stdout, format, args);
va_end(args);
putwchar('\n');
}
int main(void)
{
setlocale(LC_ALL, "");
vfwprintf_test(L"vfwprintf 姓名: %ls\n", L"张三");
vfwprintf_test(L"vfwprintf 姓名: %ls\n性别:%lc\n", L"李四", L'男');
vfwprintf_test(L"vfwprintf 姓名: %ls\n性别:%lc\n年龄:%d\n", L"王五", L'男', 25);
//vfwprintf_s example
vfwprintf_s_test(L"vfwprintf_s 姓名: %ls\n", L"张三s");
vfwprintf_s_test(L"vfwprintf_s 姓名: %ls\n性别:%lc\n", L"李四s", L'男');
vfwprintf_s_test(L"vfwprintf_s 姓名: %ls\n性别:%lc\n年龄:%d\n", L"王五s", L'男', 35);
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/io/vfwprintf
https://www.standards.wiki/c/c_library_wchar_function_vfwprintf.html
https://www.standards.wiki/c/c_appendix_secure_function_vfwprintf_s.html
https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/vfprintf-vfprintf-l-vfwprintf-vfwprintf-l?view=msvc-170
https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/vfprintf-s-vfprintf-s-l-vfwprintf-s-vfwprintf-s-l?view=msvc-170
vswprintf / vswprintf_s example
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <locale.h>
#include <wchar.h>
#include <limits.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdarg.h>
#include <wtypes.h>
#include <memory.h>
#pragma warning(disable:4996)
void vswprintf_test(const wchar_t* format, ...)
{
static int vswp = 0;
wchar_t wArr[100];
wprintf(L"档案%d\n", ++vswp);
va_list args;
va_start(args, format);
vswprintf(wArr, 100, format, args);
va_end(args);
fputws(wArr, stdout);
}
void vswprintf_s_test(const wchar_t* format, ...)
{
static int vswps = 0;
wchar_t wArr[256];
wprintf_s(L"档案%d\n", ++vswps);
va_list args;
va_start(args, format);
vswprintf_s(wArr, 256, format, args);
va_end(args);
fputws(wArr, stdout);
}
int main(void)
{
setlocale(LC_ALL, "");
vswprintf_test(L"vswprintf 姓名: %ls\n\n", L"张三");
vswprintf_test(L"vswprintf 姓名: %ls\n性别:%lc\n\n", L"李四", L'男');
vswprintf_test(L"vswprintf 姓名: %ls\n性别:%lc\n年龄:%d\n\n", L"王五", L'男', 25);
//vswprintf_s example
vswprintf_s_test(L"vswprintf_s 姓名: %ls\n\n", L"张三s");
vswprintf_s_test(L"vswprintf_s 姓名: %ls\n性别:%lc\n\n", L"李四s", L'男');
vswprintf_s_test(L"vswprintf_s 姓名: %ls\n性别:%lc\n年龄:%d\n\n", L"王五s", L'男', 35);
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/io/vfwprintf
https://www.standards.wiki/c/c_library_wchar_function_vswprintf.html
https://www.standards.wiki/c/c_appendix_secure_function_vswprintf_s.html
_vsnwprintf / _vsnwprintf_s example
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <locale.h>
#include <wchar.h>
#include <limits.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdarg.h>
#include <wtypes.h>
#include <memory.h>
#pragma warning(disable:4996)
void _vsnwprintf_test(LPCWSTR formatstring, ...)
{
int nSize = 0;
wchar_t buff[10];
memset(buff, 0, sizeof(buff));
va_list args;
va_start(args, formatstring);
//int __CRTDECL _vsnwprintf(
// _Out_writes_opt_(_BufferCount) _Post_maybez_ wchar_t* _Buffer,
// _In_ size_t _BufferCount,
// _In_z_ _Printf_format_string_ wchar_t const* _Format,
// va_list _ArgList
//)
nSize = _vsnwprintf(buff, 10 - 1, formatstring, args); // C4996
wprintf(L"nSize: %d, buff: %ls\n", nSize, buff);
va_end(args);
}
void vsnwprintf_s_test(LPCSTR formatstring, ...)
{
int nSize = 0;
wchar_t buff[30];
memset(buff, 0, sizeof(buff));
va_list args;
va_start(args, formatstring);
//int __CRTDECL _vsnwprintf_s(
// _Out_writes_opt_(_BufferCount) _Always_(_Post_z_) wchar_t* const _Buffer,
// _In_ size_t const _BufferCount,
// _In_ size_t const _MaxCount,
// _In_z_ _Printf_format_string_ wchar_t const* const _Format,
// va_list _ArgList
//)
nSize = _vsnwprintf_s(buff, _countof(buff), _TRUNCATE, formatstring, args);
wprintf(L"nSize: %d, buff: %s\n", nSize, buff);
va_end(args);
}
int main() {
_vsnwprintf_test(L"%ls %ls", L"Hi", L"there");
_vsnwprintf_test(L"%ls %ls", L"Hi", L"there!");
_vsnwprintf_test(L"%ls %ls", L"Hi", L"there!!");
vsnwprintf_s_test(L"%s %s", L"Hi", L"vsnwprintf_s_test");
vsnwprintf_s_test(L"%s %s", L"Hi", L"vsnwprintf_s_test!!");
vsnwprintf_s_test(L"%s %s", L"Hi", L"vsnwprintf_s_test!!!");
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/io/vfwprintf
https://www.standards.wiki/c/c_library_wchar_function_vswprintf.html
https://www.standards.wiki/c/c_appendix_secure_function_vswprintf_s.html