Описание строк, завершающихся нулевым байтом
· Строка описывается как обычный массив символов char
·
char s [] = “Hello”; char s [6] = {‘H’, ‘e’, ‘l’, ‘l’, ‘o’, ‘\0’};
· Размер массива должен быть на 1 больше длины самой длинной строки, которую предполагается в этом массиве хранить
char s[10] = “Hello”;
Основные отличия строк, завершающих нулевым байтом, от массивов
· В процессе выполнения программы отслеживается текущая длина строки. · Строка в целом может быть проинициализирована значением строкового литерала (а не только поэлементно символьными значениями).
· При помещении идентификатора символьного массива в поток cout выводится не адрес массива, а его содержимое от 0-го элемента до последнего перед завершающим символом \0.
Основные ограничения на действия со строками, завершающимися нулевым байтом (С-строками)
· Строки, как и обычные массивы, нельзя присваивать друг другу, используя оператор присваивания (включая присвоение строке строкового литерала где-либо, кроме начальной инициализации). · К строкам, как к обычным массивам, нельзя применять операции сравнения. · Для строк нет перегруженных операций (например, + для операции конкатенации). · Для выполнения операций копирования, конкатенации, сравнения строк и ряда других операций приходится использовать встроенные функции, описанные в заголовке <string.h> .
Функции преобразования (С-строки)
STDLIB.H
Функции для работы с С-строками
STRING.H
Функции для работы со строками
Для строк не определена операция присваивания, поскольку строка является не основным типом данных, а массивом. Присваивание выполняется с помощью функций стандартной библиотеки strcpy или strncpy или посимвольно «вручную».
Функция strcpy (char *s1, char *s2) копирует все символы строки, указанной вторым параметром, включая завершающий 0, в строку, указанную первым параметром. Функция strncpy (char *s1, char *s2, n) выполняет то же самое, но не более n символов. Если нуль-символ встретился в исходной строке раньше, то копирование прекращается, а оставшиеся до n символы строки s2 заполняются нуль-символами. В противном случае (если n меньше или равно длине строки s1) завершающий нуль-символ в s2 не добавляется.
Функция strlen(char *s) возвращает фактическую длину строки s, не включая нуль-символ.
Функции strcat и strncat используются для объединения строк. Функция strcat (char *s1, char*s2) добавляет копию строки s2, включая завершающий нуль-символ, в конец строки s1. Первый символ строки s2 размещается в байте, в котором был записан нуль-символ строки s1. Если строка s1 заполнена, а s2 – не нулевая строка, то вызов strcat (s1, s2); перезапишет конец строки. Следите за длиной результирующей строки при конкатенации строк при вызове функции strcat (...). Функция strncat(char *s1, char *s2, n) позволяет добавить не более чем n символов строки s2 в конец строки s1.
Функция strcmp (char *s1, char *s2) позволяет сравнить 2 строки. Функция возвращает 0, если строки равны, отрицательное значение, если первая строка меньше, чем вторая, и положительное значение, если первая строка больше, чем вторая. Функция strncmp (char *s1, char *s2, n) проводит сравнение только первых n символов двух строк. Функции stricmp и strnicmp позволяют сравнивать строки без учета регистра, т.е. без различия между прописными и строчными буквами.
Функция strchr (const char *s, int c) реализует поиск одиночного символа в строке. Она возвращает значение NULL, если символ-аргумент в строке не найден, иначе возвращает указатель на этот символ.
Функция strcspn (char *s1, char *s2) - определяет и возвращает длину начальной части строки s1, состоящей из символов, не содержащихся в строке s2. Функция strspn (const char *s1, const char *s2) - определяет и возвращает длину начальной части строки s1, состоящей только из символов, содержащихся в строке s2.
Функция strpbrk (char *s1, char *s2) - определяет позицию первого вхождения в строку s1 любого из символов строки s2. Если символ не найден, то возвращается указатель NULL.
Функция strstr (char *s1, char *s2) - определяет позицию первого вхождения в строку s1 подстроки s2. Если подстрока не найдена, то возвращается указатель NULL.
Функция char* strtok (char *s1, const char *s2) интерпретирует строку s1 как последовательность лексических единиц (слов), разделенных ограничителями, которые заданы в строке-аргументе, соответствующей параметру s2. Функция возвращает указатель на первую из найденных лексических единиц или значение NULL, если таких единиц в строке-аргументе нет. После выделения лексической единицы из аргумента s1 непосредственно за ней размещается символ с нулевым кодом. Таким образом, функция разбивает переданную ей строку (первый аргумент вызова) на лексемы в соответствии с заданным набором разделителей (второй аргумент). Эту функцию можно использовать для выделения в строке лексем-слов. Функция изменяет разбиваемую на лексемы строку, поэтому необходимо позаботиться о предварительном сохранении строки.
Функции для работы со строками для Microsoft Visual Studio 2005
Функции strcpy_s (char *s1, size_t n, char* s2) strcat_s (char *s1, size_t n, char* s2) strncat_s (char *s1, size_t n, char *s2, k) _strlwr_s (char *s1, size_t n) _strupr_s(char *s1, size_t n)
аналогичны предыдущим функциям, n – размер строки s1. Как правило возвращают 0, если функция выполняется корректно.
Функция strtok_s (char *s1, const char *s2, char** sm) аналогична функции strtok. Причем sm – содержит начало следующей лексемы строки.
Ввод С-строк
При вводе строки с клавиатуры (помещение в поток cin) следует контролировать длину вводимой строки (чтобы она не превышала длину массива, где будет храниться строка
const int MAX=100; char str[MAX]; cin >> setw (MAX) >> str; // Ввод до MAX-1 символов
При помещении строки в поток cin пробелы и символы новой строки конвертируются в завершающий нулевой байт
const int MAX=100; char str [MAX]; cin >> setw (MAX) >> str; // Введем строку "Good Morning" cout << str; // Получим "Good"
Чтобы ввести строку, содержащую пробелы, необходимо вызвать встроенную функцию getline для потока cin:
char str [MAX]; cin.getline (str, MAX);
или можно задать свой разделитель строк:
char str [MAX]; char SEP = '$'; // Задаем свой разделитель строк cin.getline (str, MAX, SEP);
Строки стандартного класса string
Язык С++ включает в себя новый класс, называемый string. Этот класс во многом улучшает традиционный строковый тип, позволяет обрабатывать строки также как данные других типов, а именно с помощью операторов. Он более эффективен и безопасен в использовании, не нужно заботиться о создании массива нужного размера для строковой переменной, класс string берет на себя ответственность за управлением памятью.
Если при создании приложения скорость выполнения не является доминирующим фактором, класс string предоставляет безопасный и удобный способ обработки строк.
Для работы со строками класса string существует множество методов и операций.
Объявление и инициализация строк string.
//создаем пустую строку //вызов конструктора без аргументов string s1;
// создаем строку из C-строки //вызов конструктора с одним аргументом string s2("aaaa"); // string s2 = "aaaa"; // или так
// создаем строку из C-строки 10 символов //вызов конструктора с двумя аргументами string s3("abcdefghijklmnopqrstuvwxyz",10);
// создаем строку из 5 одинаковых символов string s4(5,’!’);
// создаем строку-копию из строки s3 string s5(s3);
// создаем строку-копию из строки s3 // начиная с индекса 5 не более 3 символов string s6(s3,5,3);
Методы для работы со строками класса string
Операции для работы со строками класса string
ПРИМЕР 1. Инициализация С-строки
#include <iostream> // for cin cout
using namespace std;
void main() { const int MAX = 8; //нулевой символ добавляется к концу строки автоматически char str1[MAX] = "stroka1";
//нулевой символ добавляется к концу строки автоматически char str2[] = "stroka2"; // нет \0 char str3[] = {'s', 't', 'r', 'o', 'k', 'a', '3'};
char str4[] = {'s','t','r','o','k','a','4','\0'};
char str5[MAX]; char *str6 = "stroka6";
cout << " 1 " << str1 << endl; cout << " 2 " << str2 << endl; cout << " 3 " << str3 << endl; cout << " 4 " << str4 << endl;
//!!! нельзя константный указатель str5 = "stroka5"; cout << " 5 " << str5 << endl; cout << " 6 " << str6 << endl;
//!!! можно!!! str6 = "stroka"; cout << " 6 " << str6 << endl; } ПРИМЕР 2. Ввод С-строки. Инструкция cin
#include <iostream> // for cin cout
using namespace std;
void main() { const int MAX = 80; char str[MAX];
cout << " Enter a string: "; //ввод выполняется до первого пробельного символа cin >> str; cout << "You entered: " << str << endl; } ПРИМЕР 3. Ввод С-строки. Функция gets
#include <stdio.h> // for gets puts #include <iostream> // for cin cout
using namespace std;
void main() { const int n = 80; char s[n];
cout << " Enter a string: "; gets(s); // gets_s(s); cout << "You entered: "; puts(s); // puts_s (s);
} ПРИМЕР 4. Ввод С-строки. Метод get
#include <iostream> // for cin cout
using namespace std;
void main() { const int MAX = 80; char str [MAX]; char c;
cout << " 1 Enter a string: "; // символ перевода строки '\n' остается в потоке // в строковую переменную добавляется '\0' cin.get (str, MAX); cout << " 1 You entered: " << str << endl;
cin.get(); // удаление из потока символа ‘\n’. cout << "\n 2 Enter a string:\n";
// свой разделитель для ввода строки cin.get(str, MAX, '$'); cout << " You entered:\n" << str << endl; c = cin.get(); // удаление из потока символа ‘$’. cout<<c<<endl; c = cin.get(); // удаление из потока символа ‘\n’. cout<<int(c)<<endl;
cout << "\n 3 Enter a string: "; //символ перевода строки '\n' остается в потоке //в строковую переменную добавляется '\0' cin.get (str, MAX); cout << "3 You entered: " << str << endl;
cin.get(); // удаление из потока символа ‘\n’.
}
ПРИМЕР 5. Ввод С-строки. Метод getline
#include <iostream> // for cin cout
using namespace std;
void main() { const int MAX = 80; char str [MAX];
cout << "\n 1 Enter a string: "; //при этом '\n' также считывается (удаляется) из потока //и вместо него в строковую переменную записывается '\0' cin.getline (str, MAX); cout << "1 You entered: " << str << endl;
cout << "\n 2 Enter a string: "; //свой разделитель для ввода строки //при этом '\n' также считывается (удаляется) из потока //и вместо него в строковую переменную записывается '\0' cin.getline (str, MAX, '&'); cout << "2 You entered: " << str << endl; } ПРИМЕР 6. Ввод С-строки с русскими буквами
#include <windows.h> #include <iostream> // cin cout
using namespace std;
void main() { char buff[80];
cin.getline(buff,80); // "русский текст"
cout << "Моя программа"<< endl; // на экране набор знаков cout << buff << endl; // на экране: "русский текст"
setlocale(LC_ALL, "rus");
cout << "Моя программа"<< endl; // на экране: "Моя программа" cout << buff << endl; // на экране набор знаков
OemToAnsi(buff, buff);
cout << "Моя программа"<< endl; // на экране: "Моя программа" cout << buff << endl; // на экране: "русский текст"
}
ПРИМЕР 7. Ввод С-строк. Метод getline
#include <string.h> #include <iostream> // for cin cout
using namespace std;
void main() { const int n = 80; char s[n];
// выход из цикла – конец файла – Ctrl+z while (cin.getline(s, n)) { if (! strcmp(s,"")) break; cout << s << endl; //.......... обработка строки } }
ПРИМЕР 8. Преобразование двоичного числа в десятичное.
#include <string.h> #include <iostream> // for cin cout
using namespace std;
void main () { char str[80]; long int dec; int i, v = 1;
// двоичное число задаем в виде строки cout << " Enter number v 2 ss "; cin.getline (str, 80);
dec = 0; for (i = strlen(str)-1; i >= 0; i--) { // значение элемента строки 0 или 1 if (str[i] == '1') { dec += v; // добавляем к результату cout<<v<<" "; } v *= 2; // вес следующего разряда } cout<<endl<<" result v 10 ss =" <<dec<<endl; } ПРИМЕР 9. Преобразование десятичного числа в двоичное.
#include <iostream> // for cin cout
using namespace std;
void main () { char str[80]; int n, r;
cout<<" vvedite number v 10 ss"<<endl; cin>>n;
int i = 0; do { r = n % 2; //остаток от деления на основание с/с n = n / 2; // частное от деления на основание с/с str[i] = char('0' + r); i++; } while (n > 0); // цифры результата в строке str в обратном порядке for(int j = 0; j < i / 2; j++) // меняем порядок цифр на обратный { int c = str[j]; str[j] = str[i – j – 1]; str[i – j – 1] = c; }
// конец строки i – номер позиции str[i] = '\0'; cout<<" result v 2 ss= " <<str<<endl; }
ПРИМЕР 10. Работа с символами С-строки
Задана строка символов. Получить новую строку из исходной, удалив символы ‘*’ и удвоив букву A (а).
#include <string.h> #include <iostream> // for cin cout
using namespace std;
void main() { const int MAX = 80; char str1 [MAX], str2 [MAX]; unsigned int i, k = 0;
cout << " Enter a string: "; cin.getline (str1, MAX);
for (i = 0; str1[i]; i++) { if (str1[i] == '*') // если * пропускаем continue;
// если А или а удваиваем if (str1[i] == 'A'|| str1[i] == 'a') str2[k++] = str1[i];
// в остальных случаях записываем в результирующую строку str2[k++] = str1[i]; }
str2[k] = '\0'; // конец строки cout << " Rezult = " << str2<< endl;
} ПРИМЕР 11. Копирование С-строк. Функции strcpy, strcpy_s
#include <string.h> #include <iostream> // for cin cout
using namespace std;
void main() { char st [20] = "*******************"; // 19 '*' int i, err;
for (i = 0; i <= 19; i++) cout << st[i]; cout << endl<< st << " " << strlen (st) << endl;
strcpy(st, "Good Morning");
for (i = 0; i <= 19; i++) cout << st[i]; cout << endl<< st << " " << strlen (st) << endl;
err = strcpy_s(st, 20, "Hello World"); if (!err) for (i = 0; i <= 19; i++) cout << st[i]; cout << endl<< st << " " << strlen (st) << endl;
strcpy(st, "Hello");
for (i = 0; i <= 19; i++) cout << st[i]; cout << endl<< st << " " << strlen (st) << endl; cout << endl; } ПРИМЕР 12. Сравнение С-строк. Функции strcmp и strlen
#include <string.h> #include <iostream> // for cin cout
using namespace std;
void main() { const int MAX = 80; char buffer[MAX] = ""; int count = 0;
while (true) { cout << "Enter a string of less than 80 characters:\n"; cin.getline(buffer, MAX);
if (! strcmp(buffer, "")) break;
for (count=0; buffer[count]!= '\0'; count++);
cout << count << " " << strlen(buffer) <<endl; }
}
ПРИМЕР 13. Объединение С-строк. Функции strcat, strncat, strcat_s, strcncat_s
#include <string.h> // for strcat strncat #include <iostream> // for cin cout using namespace std;
void main() { const int MAX = 80; char s1[MAX] = "1", s2[MAX] = "22222", s3[MAX] = "333"; char* s4; int err;
cout<<" 1 "<<endl; cout<<" str1="<< s1<<endl; cout<<" str2="<< s2<<endl;
cout<<" 2 "<<endl; cout<<"str1+str2="<< strcat(s1, s2)<<endl; cout<<" str1="<< s1<<endl;
cout<<" 3 "<<endl; cout<<" str1="<< s1<<endl; s4 = strcat(s1, s2); cout<<" str1="<< s1<<endl; cout<<"s4=str1+str2="<< s4<<endl;
cout<<" 4 "<<endl; err = strcat_s(s1, MAX, s2); if (!err) cout<<"str1+str2="<< s1<<endl;
cout<<" 5 "<<endl; cout<<" str3="<< s3<<endl; cout<<"str3+str2 ="<<strncat(s3, s2, 2)<<endl; cout<<" str3="<< s3<<endl;
cout<<" 6 "<<endl; s4 = strncat(s3, s2, 2); cout<<" str3="<< s3<<endl; cout<<"str4=str3+str2="<< s4<<endl;
cout<<" 7 "<<endl; err = strncat_s(s3, MAX, s2, 2); if (!err) cout<<"str1+str2="<< s3<<endl;
} ПРИМЕР 14. Вхождение символа в С-строку. Функция strchr
#include <string.h> #include <iostream> // for cin cout
using namespace std;
void main() { const int MAX = 80; char s[MAX] = "1234567890abcdefghABCDEFGH"; char c; char* str; int n;
cout<<" c = "<<endl; cin>>c;
while(c!= '!') { str = strchr(s, c); if (str!= NULL) { // определение позиции найденного символа n = int (str – s); cout<<" simvol ="<<c<< " v"<<n<<"pozicii"<< endl; } else cout<<" simvola ="<<c<< " net "<<endl;
cout<<" c= "<<endl; cin>>c; } }
ПРИМЕР 15. Вхождение С-подстроки в С-строку. Функция strstr
#include <string.h> #include <iostream> // for cin cout
using namespace std;
void main() { const int MAX = 80; char s1[MAX], s2[MAX]; char* str; int n;
cout << " s1= \n"; cin.getline(s1, MAX);
while(true) { cout << " s2= \n"; cin.getline(s2, MAX);
if (! strcmp(s2, "")) break;
str=strstr(s1, s2);
if (str!= NULL) { // определение позиции найденной подстроки n = int (str - s1); cout<<" s2 v s1 c ="<<n<<"pozicii"<<endl; } else cout<<" s2 no s1"<<endl; } }
ПРИМЕР 16. Вхождение символов в С-строку. Функции strspn, strcspn
#include <string.h> #include <iostream> // for cin cout
using namespace std;
void main() { const int MAX = 80; char s1[MAX], s2[MAX]; int n1, n2;
cout << " s1= \n"; cin.getline(s1, MAX);
while(true) { cout << " s2= \n"; cin.getline(s2, MAX);
if (! strcmp(s2,"")) break;
n1 = strspn(s1, s2); cout<<" dlina first part s1 only iz simvolov s2 = "<< n1<<endl;
n2 = strcspn(s1, s2); cout<<endl<<" dlina first part no simvolov s2 = "<< n2<<endl; } } ПРИМЕР 17. Определение С-подстроки из С-строки. Функция strpbrk
#include <string.h> #include <iostream> // for cin cout
using namespace std;
void main() { const int MAX = 80; char s1[MAX], s2[MAX]; char* str;
cout << " s1= \n"; cin.getline(s1, MAX);
while(true) { cout << " s2= \n"; cin.getline(s2, MAX);
if (! strcmp(s2,"")) break;
str = strpbrk(s1,s2);
if (str!= NULL) cout<<" podstroka s1 "<<str<<endl; else cout<<" v s1 net simvolov iz s2 "<<endl;
} } ПРИМЕР 18. Замена символов в С-строке из нижнего регистра в верхний. Функции strupr, _strupr_s
#include <string.h> #include <iostream> // for cin cout using namespace std;
void main() { const int MAX = 80; char str[MAX]; char *s; int err;
cout << " str= "; cin.getline(str, MAX); s = strupr(str); cout<<str<<" rezult = "<< s <<endl;
cout << " str= "; cin.getline(str, MAX); err = _strupr_s(str, MAX); if (!err) cout<<" rezult = "<< str <<endl;
}
ПРИМЕР 19. Замена символов в С-строке из верхнего регистра в нижний. Функции strlwr,_strlwr_s
#include <string.h> #include <iostream> // for cin cout using namespace std;
void main() { const int MAX = 80; char str [MAX]; char * s; int err;
cout << " str= "; cin.getline(str, MAX);
s = strlwr(str); cout<<str<<" rezult = "<<s<<endl;
cout << " str= "; cin.getline(str, MAX); err = _strlwr_s (str, MAX); if (!err) cout<<" rezult = "<< str <<endl;
}
ПРИМЕР 20. Преобразование С-строки в число. Функции atoi, atof
#include <string.h> // for strcmp #include <stdlib.h> // for atoi atof #include <iostream> // for cin cout
using namespace std;
void main() { const int MAX = 80; char str[MAX] = "abcd"; int i; double f;
i = atoi(str); cout<<i<<endl;
while (true) { cout << "1 Enter a string \n"; cin.getline(str, MAX);
if (! strcmp(str,"")) break;
i = atoi(str); cout<<i<<endl; }
while (true) { cout<<"2 Enter a string \n"; cin.getline(str, MAX);
if (! strcmp(str,"")) break;
f = atof(str); cout<<f<<endl; } } ПРИМЕР 21. Преобразование С-строки в число. Функция strtol
#include <string.h> // for strcmp #include <stdlib.h> // for strtol #include <iostream> // for cin cout
using namespace std;
void main() { const int MAX = 80; char str[MAX] = "abcd"; char *err; long l; int base; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|