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

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

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

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

typedef unsigned __int64 size_t;
#define __int64 long long

Пример:

char str[7] = "строка";
std::cout << std::strlen(str) << std::endl; // 6, а не 7

Определить общий размер массива можно с помощью оператора sizeof. Оператор возвращает размер в байтах. Так как тип char занимает 1 байт, следовательно, размер в байтах будет равен размеру массива. Пример:

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

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

char str[7] = "строка";
std::cout << strnlen(str, 7) << std::endl; // 6
  • strcpy() — копирует символы из C-строки source в C-строку dest и вставляет нулевой символ. В качестве значения функция возвращает указатель на строку dest. Если строка source длиннее строки dest, то произойдет переполнение буфера. Прототип функции:
#include <cstring> /* или #include <string.h> */
char *strcpy(char *dest, const char *source);

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

char str[7];
std::strcpy(str, "String");
std::cout << str << std::endl; // String

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

#include <cstring> /* или #include <string.h> */
errno_t strcpy_s(char *dest, rsize_t sizeInBytes, 
                 const char *source);

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

const int SIZE = 7;
char str[SIZE];
strcpy_s(str, SIZE, "String");
std::cout << str << std::endl; // String
  • strncpy() — копирует первые count символов из C-строки source в C-строку dest. В качестве значения функция возвращает указатель на строку dest. Если строка source длиннее строки dest, то произойдет переполнение буфера. Прототип функции:
#include <cstring> /* или #include <string.h> */
char *strncpy(char *dest, const char *source, size_t count);

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

char str[7];
std::strncpy(str, "String", 6);
str[6] = '\0'; // Нулевой символ автоматически не вставляется
std::cout << str << std::endl; // String

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

#include <cstring> /* или #include <string.h> */
errno_t strncpy_s(char *dest, size_t sizeInBytes, 
                  const char *source, size_t maxCount);

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

const int SIZE = 7;
char str[SIZE];
strncpy_s(str, SIZE, "String", 5);
std::cout << str << std::endl; // Strin
  • strcat() — копирует символы из C-строки source в конец C-строки dest и вставляет нулевой символ. В качестве значения функция возвращает указатель на строку dest. Если строка dest имеет недостаточный размер, то произойдет переполнение буфера. Прототип функции:
#include <cstring> /* или #include <string.h> */
char *strcat(char *dest, const char *source);

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

char str[20] = "ст";
std::strcat(str, "ро");
std::strcat(str, "ка");
std::cout << str << std::endl; // строка

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

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

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

char str[20] = {0};            // Инициализация нулями
std::strcat(str, "строка");    // Все нормально
std::cout << str << std::endl; // строка

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

#include <cstring> /* или #include <string.h> */
errno_t strcat_s(char *dest, rsize_t sizeInBytes, 
                 const char *source);

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

const int SIZE = 20;
char str[SIZE] = "ст";
strcat_s(str, SIZE, "ро");
strcat_s(str, SIZE, "ка");
std::cout << str << std::endl; // строка
  • strncat() — копирует первые count символов из C-строки source в конец строки dest и вставляет нулевой символ. В качестве значения функция возвращает указатель на строку dest. Обратите внимание на то, что перед копированием в строке dest обязательно должен быть нулевой символ. Если строка dest имеет недостаточный размер, то произойдет переполнение буфера. Прототип функции:
#include <cstring> /* или #include <string.h> */
char *strncat(char *dest, const char *source, size_t count);

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

char str[20] = "ст";
std::strncat(str, "ром", 2);
std::strncat(str, "какао", 2);
std::cout << str << std::endl; // строка

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

#include <cstring> /* или #include <string.h> */
errno_t strncat_s(char *dest, size_t sizeInBytes, 
                  const char *source, size_t maxCount);

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

const int SIZE = 20;
char str[SIZE] = "ст";
strncat_s(str, SIZE, "ром", 2);
strncat_s(str, SIZE, "какао", 2);
std::cout << str << std::endl; // строка
  • _strdup() — создает копию строки в динамической памяти и возвращает указатель на нее. Прототип функции:
#include <cstring> /* или #include <string.h> */
char *_strdup(const char *str);

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

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

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

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

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

#include <cstring> /* или #include <string.h> */
char *strtok_s(char *str, const char *delim, char **context);

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

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

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

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

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

Помощь сайту

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

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