本篇介绍 wchar.h头文件的安全函数学习之wcscat_s,wcscpy_s,wcsncat_s,wcsncpy_s,wcsnlen_s,wcstok_s。
实验环境:window11, VS2022
wcscat / wcscat_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)
{
#define LENGTH 100
wchar_t str[50] = L"Земля, прощай.";
wcscat(str, L" ");
wcscat(str, L"В добрый путь.");
setlocale(LC_ALL, "en_US.utf8");
printf("%ls\n", str);
setlocale(LC_ALL, "");
wchar_t wStrOne[LENGTH] = L"早安";
const wchar_t wStrTwo[] = L"中国";
if (!wcscat_s(wStrOne, LENGTH, wStrTwo))
wprintf_s(L"%ls\n", wStrOne);
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/string/wide/wcscat
https://www.standards.wiki/c/c_library_wchar_function_wcscat.html
https://www.standards.wiki/c/c_appendix_secure_function_wcscat_s.html
https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/strcat-wcscat-mbscat?view=msvc-170
https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/strcat-s-wcscat-s-mbscat-s?view=msvc-170
wcscpy / wcscpy_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* src = L"犬 means dog";
// src[0] = L'狗' ; // 这会是未定义行为
//wchar_t dst[wcslen(src) + 1]; // 为适应空终止符 +1
wchar_t dst[32];
wcscpy(dst, src);
dst[0] = L'狗'; // OK
setlocale(LC_ALL, "en_US.utf8");
printf("src = %ls\ndst = %ls\n", src, dst);
//wcscopy_s example
#define LENGTH 100
setlocale(LC_ALL, "");
wchar_t destination[LENGTH];
const wchar_t source[] = L"上有天堂,下有苏杭。";
if (!(wcscpy_s(destination, LENGTH, source)))
fputws(destination, stdout);
printf("\n\n");
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/string/wide/wcscpy
https://www.standards.wiki/c/c_library_wchar_function_wcscpy.html
https://www.standards.wiki/c/c_appendix_secure_function_wcscpy_s.html
https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/strcpy-wcscpy-mbscpy?view=msvc-170
https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/strcpy-s-wcscpy-s-mbscpy-s?view=msvc-170
wcsncat / wcsncat_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 str[50] = L"Земля, прощай.";
wcsncat(str, L" ", 1);
wcsncat(str, L"В добрый путь.", 8); // 只后附首 8 个宽字符
setlocale(LC_ALL, "en_US.utf8");
printf("%ls\n", str);
//wcsncat_s example
setlocale(LC_ALL, "");
wchar_t wStrOne[10] = L"早安";
const wchar_t wStrTwo[] = L"中国上海";
if (!wcsncat_s(wStrOne, 10, wStrTwo, 2))
wprintf_s(L"%ls\n", wStrOne);
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/string/wide/wcsncat
https://www.standards.wiki/c/c_library_wchar_function_wcsncat.html
https://www.standards.wiki/c/c_appendix_secure_function_wcsncat_s.html
wcsncpy / wcsncpy_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)
{
const wchar_t src[] = L"わゐ";
wchar_t dest[6] = { L'あ', L'い', L'う', L'え', L'お' };
wcsncpy(dest, src, 4); // 这将复制 わゐ 并重复 L'\0' 二次
puts("The contents of dest are: ");
setlocale(LC_ALL, "en_US.utf8");
const long dest_size = sizeof dest / sizeof * dest;
for (wchar_t* p = dest; p - dest != dest_size; ++p) {
*p ? printf("%lc ", *p)
: printf("\\0 ");
}
//wcsncpy_s example
setlocale(LC_ALL, "");
const wchar_t source[] = { L'东', L'西', L'南', L'北', L'中', L'\0' };
wchar_t destination[10];
if (!(wcsncpy_s(destination, 10, source, 6)))
{
for (int i = 0; i < 6; ++i)
{
if (destination[i] == 0)
wprintf_s(L"空宽字符。\n");
else
wprintf_s(L"%lc\n", destination[i]);
}
}
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/string/wide/wcsncpy
https://www.standards.wiki/c/c_library_wchar_function_wcsncpy.html
https://www.standards.wiki/c/c_appendix_secure_function_wcsncpy_s.html
wcsnlen / wcsnlen_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 str[] = L"How many wide characters does this string contain?";
printf("without null character: %zu\n", wcslen(str));
printf("with null character: %zu\n", sizeof str / sizeof * str);
//wcsnlen_s example
setlocale(LC_ALL, "");
const wchar_t wStr[] = L"人需要真理,就像瞎子需要明眼的引路人一样。";
wprintf_s(L"字符总数: %zu\n", wcsnlen_s(wStr, sizeof(wStr) / sizeof(wchar_t)));
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/string/wide/wcslen
https://www.standards.wiki/c/c_library_wchar_function_wcslen.html
https://www.standards.wiki/c/c_appendix_secure_function_wcsnlen_s.html
wcstok / wcstok_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 input[] = L"A bird came down the walk";
printf("Parsing the input string '%ls'\n", input);
wchar_t* buffer;
wchar_t* token = wcstok(input, L" ", &buffer);
while (token)
{
printf("%ls\n", token);
token = wcstok(NULL, L" ", &buffer);
}
printf("Contents of the input string now: '");
for (size_t n = 0; n < sizeof input / sizeof * input; ++n)
input[n] ? printf("%lc", input[n]) : printf("\\0");
puts("'");
//wcstok_s example
setlocale(LC_ALL, "");
wchar_t wStr[] = L"张伟 米洛舍维奇 李军 高尔基 普京 黄药师 \
柴可夫斯基 梅德韦杰夫 巴普洛夫 普希金 \
门捷列夫 爱因斯坦 歌德 贝多芬 戈尔巴乔夫";
const wchar_t delimiter[] = L" ";
wchar_t* pch;
wchar_t* nextToken;
int count = 0;
//统计人数
pch = wcstok_s(wStr, delimiter, &nextToken);
while (pch != NULL)
{
++count;
pch = wcstok_s(NULL, delimiter, &nextToken);
}
wprintf_s(L"共%d人。\n", count);
return 0;
}
运行结果:
参考:
https://zh.cppreference.com/w/c/string/wide/wcstok
https://www.standards.wiki/c/c_library_wchar_function_wcstok.html
https://www.standards.wiki/c/c_appendix_secure_function_wcstok_s.html