Основные функции для работы с L-строками

Перечислим основные функции для работы с L-строками:

  • wcslen() — возвращает количество символов в L-строке без учета нулевого символа. Прототип функции:
#include <cwchar> /* или #include <cstring> */
size_t wcslen(const wchar_t *str);

Тип size_t объявлен как беззнаковое целое число:

typedef unsigned __int64 size_t;
#define __int64 long long

Пример:

_wsetlocale(LC_ALL, L"Russian_Russia.1251");
wchar_t str[] = L"строка";
size_t len = std::wcslen(str);
std::wcout << len << std::endl; // 6, а не 7

Определить общий размер массива можно с помощью оператора sizeof. Оператор возвращает размер в байтах. Чтобы получить длину в символах, полученное значение нужно разделить на размер типа wchar_t. Пример:

wchar_t str[20] = L"строка";
std::wcout << sizeof(str) << std::endl;                   // 40
std::wcout << sizeof(str) / sizeof(wchar_t) << std::endl; // 20
  • wcsnlen() — возвращает количество символов в L-строке без учета нулевого символа. Прототип функции:
#include <cwchar> /* или #include <cstring> */
size_t wcsnlen(const wchar_t *str, size_t maxCount);

Во втором параметре указывается размер символьного массива. Если нулевой символ не встретился в числе maxCount символов, то возвращается значение maxCount. Пример:

_wsetlocale(LC_ALL, L"Russian_Russia.1251");
wchar_t str[7] = L"строка";
size_t len = wcsnlen(str, 7);
std::wcout << len << std::endl;  // 6
  • wcscpy() — копирует символы из L-строки source в L-строку dest и вставляет нулевой символ. В качестве значения функция возвращает указатель на строку dest. Если строка source длиннее строки dest, то произойдет переполнение буфера. Прототип функции:
#include <cwchar> /* или #include <cstring> */
wchar_t *wcscpy(wchar_t *dest, const wchar_t *source);

Пример использования функции:

_wsetlocale(LC_ALL, L"Russian_Russia.1251");
wchar_t str[7];
std::wcscpy(str, L"String");
std::wcout << str << std::endl; // String

Вместо функции wcscpy() лучше использовать функцию wcscpy_s(). Прототип функции:

#include <cwchar> /* или #include <cstring> */
errno_t wcscpy_s(wchar_t *dest, rsize_t destSize, 
                 const wchar_t *source);

Функция wcscpy_s() копирует символы из строки source в строку dest и вставляет нулевой символ. В параметре destSize указывается максимальное количество элементов массива dest. Пример:

_wsetlocale(LC_ALL, L"Russian_Russia.1251");
const int SIZE = 7;
wchar_t str[SIZE];
wcscpy_s(str, SIZE, L"String");
std::wcout << str << std::endl; // String

Вместо функций wcscpy() и wcscpy_s() можно воспользоваться функциями wmemcpy() и wmemcpy_s(), которые копируют count первых символов из массива source в массив dest, но не вставляют нулевой символ. В параметре numberOfElements указывается количество элементов массива dest. Прототипы функций:

#include <cwchar> /* или #include <wchar.h> */
wchar_t *wmemcpy(wchar_t *dest, const wchar_t *source,
                 size_t count);
errno_t wmemcpy_s(wchar_t *dest, size_t numberOfElements,
                  const wchar_t *source, size_t count);

Пример:

_wsetlocale(LC_ALL, L"Russian_Russia.1251");
wchar_t str[8] = {0};
str[6] = L'1';
std::wmemcpy(str, L"String", 6);
std::wcout << str << std::endl;
// String1 (нулевой символ не вставляется!!!)
wmemcpy_s(str, 8, L"string2", 7);
std::wcout << str << std::endl; // string2

Функции wmemcpy() и wmemcpy_s() при пересечении указателей работают некорректно. Чтобы копирование при пересечении выполнялось правильно нужно воспользоваться функциями wmemmove() и wmemmove_s(). Функции копируют count первых символов из массива source в массив dest. Нулевой символ функции не вставляют. В параметре numberOfElements указывается количество элементов массива dest. Прототипы функций:

#include <cwchar> /* или #include <wchar.h> */
wchar_t *wmemmove(wchar_t *dest, const wchar_t *source,
                  size_t count);
errno_t wmemmove_s(wchar_t *dest, size_t numberOfElements,
                   const wchar_t *source, size_t count);

Пример:

_wsetlocale(LC_ALL, L"Russian_Russia.1251");
wchar_t str[8] = {0};
str[6] = L'1';
std::wmemmove(str, L"String", 6);
std::wcout << str << std::endl;
// String1 (нулевой символ не вставляется!!!)
wmemmove_s(str, 8, L"string2", 7);
std::wcout << str << std::endl; // string2
  • wcsncpy() — копирует первые count символов из L-строки source в L-строку dest. В качестве значения функция возвращает указатель на строку dest. Если строка source длиннее строки dest, то произойдет переполнение буфера. Прототип функции:
#include <cwchar> /* или #include <cstring> */
wchar_t *wcsncpy(wchar_t *dest, const wchar_t *source,
                 size_t count);

Если количество символов в строке source меньше числа count, то строка dest будет дополнена нулевыми символами, а если больше или равно, то копируются только count символов, при этом нулевой символ автоматически не вставляется. Пример копирования шести символов:

_wsetlocale(LC_ALL, L"Russian_Russia.1251");
wchar_t str[7];
std::wcsncpy(str, L"String", 6);
str[6] = L'\0'; // Нулевой символ автоматически не вставляется
std::wcout << str << std::endl; // String

Вместо функции wcsncpy() лучше использовать функцию wcsncpy_s(). Прототип функции:

#include <cwchar> /* или #include <cstring> */
errno_t wcsncpy_s(wchar_t *dest, size_t destSizeInChars,
                  const wchar_t *source, size_t maxCount);

Функция wcsncpy_s() копирует первые maxCount символов из строки source в строку dest и вставляет нулевой символ. В параметре destSizeInChars указывается максимальное количество элементов массива dest. Пример:

_wsetlocale(LC_ALL, L"Russian_Russia.1251");
const int SIZE = 7;
wchar_t str[SIZE];
wcsncpy_s(str, SIZE, L"String", 5);
std::wcout << str << std::endl; // Strin
  • wcscat() — копирует символы из L-строки source в конец L-строки dest и вставляет нулевой символ. В качестве значения функция возвращает указатель на строку dest. Если строка dest имеет недостаточный размер, то произойдет переполнение буфера. Прототип функции:
#include <cwchar> /* или #include <cstring> */
wchar_t *wcscat(wchar_t *dest, const wchar_t *source);

Пример использования функции:

_wsetlocale(LC_ALL, L"Russian_Russia.1251");
wchar_t str[20] = L"ст";
std::wcscat(str, L"ро");
std::wcscat(str, L"ка");
std::wcout << str << std::endl; // строка

Обратите внимание на то, что перед копированием в строке dest обязательно должен быть нулевой символ. Локальные переменные автоматически не инициализируются, поэтому этот код приведет к ошибке:

wchar_t str[20];             // Локальная переменная
std::wcscat(str, L"строка"); // Ошибка, нет нулевого символа!

Чтобы избавиться от ошибки нужно произвести инициализацию строки нулями следующим образом:

_wsetlocale(LC_ALL, L"Russian_Russia.1251");
wchar_t str[20] = {0};          // Инициализация нулями
std::wcscat(str, L"строка");    // Все нормально
std::wcout << str << std::endl; // строка

Вместо функции wcscat() лучше использовать функцию wcscat_s(). Прототип функции:

#include <cwchar> /* или #include <cstring> */
errno_t wcscat_s(wchar_t *dest, rsize_t destSize,
                 const wchar_t *source);

Функция wcscat_s() копирует символы из строки source в конец строки dest. В параметре destSize указывается максимальное количество элементов массива dest. Пример:

_wsetlocale(LC_ALL, L"Russian_Russia.1251");
const int SIZE = 20;
wchar_t str[SIZE] = L"ст";
wcscat_s(str, SIZE, L"ро");
wcscat_s(str, SIZE, L"ка");
std::wcout << str << std::endl; // строка
  • wcsncat() — копирует первые count символов из L-строки source в конец строки dest и вставляет нулевой символ. В качестве значения функция возвращает указатель на строку dest. Обратите внимание на то, что перед копированием в строке dest обязательно должен быть нулевой символ. Если строка dest имеет недостаточный размер, то произойдет переполнение буфера. Прототип функции:
#include <cwchar> /* или #include <cstring> */
wchar_t *wcsncat(wchar_t *dest, const wchar_t *source,
                 size_t count);

Пример использования функции:

_wsetlocale(LC_ALL, L"Russian_Russia.1251");
wchar_t str[20] = L"ст";
std::wcsncat(str, L"ром", 2);
std::wcsncat(str, L"какао", 2);
std::wcout << str << std::endl; // строка

Вместо функции wcsncat() лучше использовать функцию wcsncat_s(). Прототип функции:

#include <cwchar> /* или #include <cstring> */
errno_t wcsncat_s(wchar_t *dest, size_t destSizeInChars,
                  const wchar_t *source, size_t maxCount);

Функция wcsncat_s() копирует первые maxCount символов из строки source в конец строки dest. В параметре destSizeInChars указывается максимальное количество элементов массива dest. Пример:

_wsetlocale(LC_ALL, L"Russian_Russia.1251");
const int SIZE = 20;
wchar_t str[SIZE] = L"ст";
wcsncat_s(str, SIZE, L"ром", 2);
wcsncat_s(str, SIZE, L"какао", 2);
std::wcout << str << std::endl; // строка
  • _wcsdup() — создает копию L-строки в динамической памяти и возвращает указатель на нее. Прототип функции:
#include <cwchar> /* или #include <cstring> */
wchar_t *_wcsdup(const wchar_t *str);

Память выделяется с помощью функции malloc(), поэтому после использования строки следует освободить память с помощью функции free(). Пример:

// #include <cstdlib>
_wsetlocale(LC_ALL, L"Russian_Russia.1251");
wchar_t str[] = L"строка", *p = nullptr;
p = _wcsdup(str);
if (p) {
   std::wcout << str << std::endl; // строка
   std::free(p);
}
  • wcstok() — разделяет L-строку str на подстроки, используя в качестве разделителей символы из L-строки delim. При первом вызове указываются оба параметра. В качестве значения возвращается указатель на первую подстроку или нулевой указатель, если символы-разделители не найдены в L-строке str. Чтобы получить последующие подстроки необходимо каждый раз вызывать функцию wcstok(), указывая в первом параметре нулевой указатель, а во втором параметре те же самые символы-разделители. Обратите внимание: функция изменяет исходную строку str, вставляя вместо символов-разделителей нулевой символ. Прототип функции:
#include <cwchar> /* или #include <cstring> */
wchar_t *wcstok(wchar_t *str, const wchar_t *delim);

Пример использования функции:

_wsetlocale(LC_ALL, L"Russian_Russia.1251");
wchar_t str[] = L"a,b.c=d", *p = nullptr;
p = std::wcstok(str, L",.=");
while (p) {
   std::wcout << p << '-';
   p = std::wcstok(nullptr, L",.=");
} // Результат: a-b-c-d-
std::wcout << std::endl;
// Функция изменяет исходную строку!!!
int len = (int) (sizeof(str) / sizeof(wchar_t));
for (int i = 0; i < len; ++i) {
   std::wcout << (int)str[i] << ' ';
} // 97 0 98 0 99 0 100 0
std::wcout << std::endl;

Вместо функции wcstok() лучше использовать функцию wcstok_s(). Прототип функции:

#include <cwchar> /* или #include <cstring> */
wchar_t *wcstok_s(wchar_t *str, const wchar_t *delim,
                  wchar_t **context);

Первые два параметра аналогичны параметрам функции wcstok(). В параметре context передается адрес указателя. Обратите внимание: функция изменяет исходную строку str, вставляя вместо символов-разделителей нулевой символ. Пример:

_wsetlocale(LC_ALL, L"Russian_Russia.1251");
wchar_t str[] = L"a b c,d", *p = nullptr, *context = nullptr;
p = wcstok_s(str, L" ,", &context);
while (p) {
   std::wcout << p << '-';
   p = wcstok_s(nullptr, L" ,", &context);
} // Результат: a-b-c-d-
std::wcout << std::endl;
// Функция изменяет исходную строку!!!
int len = (int) (sizeof(str) / sizeof(wchar_t));
for (int i = 0; i < len; ++i) {
   std::wcout << (int)str[i] << ' ';
} // 97 0 98 0 99 0 100 0
std::wcout << std::endl;

Практически все функции без суффикса _s, которые мы рассмотрели в этом разделе, в VC++ выводят предупреждающее сообщение warning C4996, т. к. по умолчанию функции не производят никакой проверки корректности данных. В этом случае возможно переполнение буфера. Забота о корректности данных полностью лежит на плечах программиста. Если вы уверены в своих действиях, то можно подавить вывод предупреждающих сообщений. Сделать это можно двумя способами:

  • определить макрос с названием _CRT_SECURE_NO_WARNINGS в самом начале программы, перед подключением заголовочных файлов. Пример:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cwchar>
  • вставить прагму warning. Пример:
#pragma warning( disable : 4996 )
Обратите внимание

Учебник C++ (MinGW-W64)
Учебник C++ (MinGW-W64) в формате PDF

Помощь сайту

ЮMoney (Yandex-деньги): 410011140483022

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов