本篇介绍wchar.h头文件的安全函数学习之wscanf_s, fwscanf_s, swscanf_s, vwscanf_s, vfwscanf_s, vswscanf_s。
实现环境:window11, VS2022
wscanf / wscanf_s example
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <locale.h>
#include <wchar.h>
#include <limits.h>
#pragma warning(disable:4996)
int main(void)
{
setlocale(LC_ALL, "");
wchar_t wArr[100];
wprintf(L"输入一段文字(不超过%d个字符): ", 99);
wscanf(L"%ls", wArr);
wprintf(L"%ls\n", wArr);
//wscanf_s example
int i, result;
float fp;
char c, s[80];
wchar_t wc, ws[80];
result = scanf_s("%d %f %c %C %s %S", &i, &fp, &c, 1, &wc, 1, s, (unsigned)_countof(s), ws, (unsigned)_countof(ws));
printf("The number of fields input is %d\n", result);
printf("The contents are: %d %f %c %C %s %S\n", i, fp, c, wc, s, ws);
result = wscanf_s(L"%d %f %hc %lc %S %ls", &i, &fp, &c, 2, &wc, 1, s, (unsigned)_countof(s), ws, (unsigned)_countof(ws));
wprintf(L"The number of fields input is %d\n", result);
wprintf(L"The contents are: %d %f %C %c %hs %s\n", i, fp, c, wc, s, ws);
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/io/fwscanf
https://www.standards.wiki/c/c_library_wchar_function_wscanf.html
https://www.standards.wiki/c/c_appendix_secure_function_wscanf_s.html
https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/scanf-scanf-l-wscanf-wscanf-l?view=msvc-170
https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/scanf-s-scanf-s-l-wscanf-s-wscanf-s-l?view=msvc-170
fwscanf / fwscanf_s example
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <locale.h>
#include <wchar.h>
#include <limits.h>
#pragma warning(disable:4996)
int main(void)
{
setlocale(LC_ALL, "");
wchar_t wArr[30];
int ret = fwscanf(stdin, L"%ls", wArr);
wprintf(L"%ls ret = %d\n", wArr, ret);
//fwscanf_s example
FILE* stream;
long l;
float fp;
wchar_t s[81];
wchar_t c;
errno_t err = fopen_s(&stream, "fwscanf_s.out", "w+");
if (err)
printf_s("The file fwscanf_s.out was not opened\n");
else
{
fprintf_s(stream, "%s %ld %f%c", "a-string", 65000, 3.14159, 'x');
// Set pointer to beginning of file:
fseek(stream, 0L, SEEK_SET);
// Read data back from file:
fwscanf_s(stream, L"%s", s, _countof(s));
fwscanf_s(stream, L"%ld", &l);
fwscanf_s(stream, L"%f", &fp);
fwscanf_s(stream, L"%c", &c, 1);
// Output data read:
wprintf(L"%s\n", s);
wprintf(L"%ld\n", l);
wprintf(L"%f\n", fp);
wprintf(L"%c\n", c);
fclose(stream);
}
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/io/fwscanf
https://www.standards.wiki/c/c_library_wchar_function_fwscanf.html
https://www.standards.wiki/c/c_appendix_secure_function_fwscanf_s.html
https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/fscanf-fscanf-l-fwscanf-fwscanf-l?view=msvc-170
https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/fscanf-s-fscanf-s-l-fwscanf-s-fwscanf-s-l?view=msvc-170
swscanf / swscanf_s example
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <locale.h>
#include <wchar.h>
#include <limits.h>
#pragma warning(disable:4996)
int main(void)
{
setlocale(LC_ALL, "");
const wchar_t wStr[] = L"家和万事兴";
wchar_t wArr[6];
int ret = swscanf(wStr, L"%ls", wArr);
wprintf(L"%ls ret = %d\n", wArr, ret);
//swscanf_s example
wchar_t tokenstring[] = L"15 12 14...";
wchar_t s[81];
wchar_t c;
int i;
float fp;
//int __CRTDECL swscanf_s(
// _In_z_ wchar_t const* const _Buffer,
// _In_z_ _Scanf_s_format_string_ wchar_t const* const _Format,
// ...)
// Input various data from tokenstring:
// max 80 character string plus null terminator
swscanf_s(tokenstring, L"%ls", s, (unsigned)_countof(s));
swscanf_s(tokenstring, L"%c", &c, (unsigned)sizeof(char));
swscanf_s(tokenstring, L"%d", &i);
swscanf_s(tokenstring, L"%f", &fp);
// Output the data read
wprintf_s(L"String = %ls\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;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/io/fwscanf
https://www.standards.wiki/c/c_library_wchar_function_swscanf.html
https://www.standards.wiki/c/c_appendix_secure_function_swscanf_s.html
https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/sscanf-sscanf-l-swscanf-swscanf-l?view=msvc-170
https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/sscanf-s-sscanf-s-l-swscanf-s-swscanf-s-l?view=msvc-170
vwscanf /vwscanf_s example
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <locale.h>
#include <wchar.h>
#include <limits.h>
#include <stdarg.h>
#pragma warning(disable:4996)
int vwscanf_test(const wchar_t* format, ...)
{
va_list args;
va_start(args, format);
vwscanf(format, args);
va_end(args);
return 0;
}
int vwscanf_s_test(wchar_t* format, ...)
{
int result;
va_list arglist;
va_start(arglist, format);
result = vwscanf_s(format, arglist);
va_end(arglist);
return result;
}
int main(void)
{
setlocale(LC_ALL, "");
wchar_t character[256];
int count = 0;
wprintf(L"输入一段文字:");
do
{
vwscanf_test(L"%lc", (character + count));
} while (character[count++] != L'\n');
for (int i = 0; i < (count - 1); ++i)
wprintf(L"character[%d]: %lc\n", i, character[i]);
//vwscanf_s example
int i, result;
float fp;
char c, s[81];
wchar_t wc, ws[81];
result = vwscanf_s_test(L"%d %f %hc %lc %S %ls", &i, &fp, &c, 2, &wc, 1, s, _countof(s), ws, _countof(ws));
wprintf(L"The number of fields input is %d\n", result);
wprintf(L"The contents are: %d %f %C %c %hs %s\n", i, fp, c, wc, s, ws);
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/io/fwscanf
https://www.standards.wiki/c/c_library_wchar_function_vwscanf.html
https://www.standards.wiki/c/c_appendix_secure_function_vwscanf_s.html
https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/vscanf-vwscanf?view=msvc-170
https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/vscanf-s-vwscanf-s?view=msvc-170
vfwscanf /vfwscanf_s example
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <locale.h>
#include <wchar.h>
#include <limits.h>
#include <stdarg.h>
#pragma warning(disable:4996)
int vfwscanf_test(FILE* stream, const wchar_t* format, ...)
{
va_list args;
va_start(args, format);
vfwscanf(stream, format, args);
va_end(args);
return 0;
}
int vfwscanf_s_test(FILE* istream, char* format, ...)
{
int result;
va_list arglist;
va_start(arglist, format);
result = vfwscanf_s(istream, format, arglist);
va_end(arglist);
return result;
}
int main(void)
{
setlocale(LC_ALL, "");
wchar_t character[256];
int count = 0;
FILE* pFile;
//打开文件
if ((pFile = fopen("gch.txt", "r")) == NULL)
exit(EXIT_FAILURE);
//向数组中写入字符
while (!feof(pFile))
{
vfwscanf_test(pFile, L"%lc", (character + count), sizeof(wchar_t));
++count;
}
//关闭文件
fclose(pFile);
for (int i = 0; i < (count - 1); ++i)
wprintf(L"character[%d]: %lc\n", i, character[i]);
//vfwscanf_s example
FILE* stream;
long l;
float fp;
wchar_t s[81];
wchar_t c;
if (fopen_s(&stream, "vfwscanf_s.out", "w+") != 0)
{
printf("The file vfscanf_s.out was not opened\n");
}
else
{
fwprintf(stream, L"%s %ld %f%c", L"a-string", 65000, 3.14159, 'x');
// Security caution!
// Beware loading data from a file without confirming its size,
// as it may lead to a buffer overrun situation.
// Set pointer to beginning of file:
fseek(stream, 0L, SEEK_SET);
// Read data back from file:
vfwscanf_s_test(stream, L"%ls %ld %f%c", s, _countof(s), &l, &fp, &c, 1);
// Output data read:
wprintf(L"%ls\n", s);
wprintf(L"%ld\n", l);
wprintf(L"%f\n", fp);
wprintf(L"%c\n", c);
fclose(stream);
}
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/io/fwscanf
https://www.standards.wiki/c/c_library_wchar_function_vfwscanf.html
https://www.standards.wiki/c/c_appendix_secure_function_vfwscanf_s.html
https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/vfscanf-vfwscanf?view=msvc-170
https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/vfscanf-s-vfwscanf-s?view=msvc-170
vswscanf /vswscanf_s example
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <locale.h>
#include <wchar.h>
#include <limits.h>
#include <stdarg.h>
#pragma warning(disable:4996)
int vswscanf_test(const wchar_t* s, const wchar_t* format, ...)
{
va_list args;
va_start(args, format);
vswscanf(s, format, args);
va_end(args);
return 0;
}
int vswscanf_s_test(char* tokenstring, char* format, ...)
{
int result;
va_list arglist;
va_start(arglist, format);
result = vswscanf_s(tokenstring, format, arglist);
va_end(arglist);
return result;
}
int main(void)
{
setlocale(LC_ALL, "");
wchar_t character[256];
const wchar_t wStr[] = L"端午节";
int count = 0;
const wchar_t* wPtr = wStr;
while (*wPtr != L'\0')
vswscanf_test(wPtr++, L"%lc", (character + count++));
for (int i = 0; i < count; ++i)
wprintf(L"character[%d]: %lc\n", i, character[i]);
//vswscanf_s example
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:
vswscanf_s_test(tokenstring, L"%80s", s, _countof(s));
vswscanf_s_test(tokenstring, L"%c", &c, sizeof(char));
vswscanf_s_test(tokenstring, L"%d", &i);
vswscanf_s_test(tokenstring, L"%f", &fp);
// Output the data read
wprintf(L"String = %ls\n", s);
wprintf(L"Character = %c\n", c);
wprintf(L"Integer: = %d\n", i);
wprintf(L"Real: = %f\n", fp);
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/io/fwscanf
https://www.standards.wiki/c/c_library_wchar_function_vswscanf.html
https://www.standards.wiki/c/c_appendix_secure_function_vswscanf_s.html
https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/vsscanf-vswscanf?view=msvc-170
https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/vsscanf-s-vswscanf-s?view=msvc-170