- •Основные понятия
- •Определение С-строк
- •строка как массив символов
- •строка как указатель на char
- •особенности работы с С-строками в С++
- •Операции со строками
- •Инициализация строки
- •Возможные ошибки при работе со строками
- •Ввод-вывод строк
- •преобразование значения базового типа в С-строку
- •ввод ограниченного числа символов строки
- •функция вывода строки
- •особенности посимвольного вывода строки
- •Копирование строк
- •Оптимизация текста программы на примере функции копирования
- •Функции для работы с С-строками
- •Определение длины строки
- •Копирование строк
- •Объединение строк
- •Сравнение строк
- •Поиск символа в строке
- •Проверка принадлежности символа некоторому множеству
- •Поиск строки в строке
- •Преобразование и заполнение строк
- •преобразование строки в число
- •преобразование строчных символов строки в прописные и наоборот
- •реверс строки
- •заполнение строки символом
- •пример применения функций преобразования
- •Выделение лексем
- •Динамические строки
- •Копирование строки в динамическую строку
- •Передача строки в функцию в качестве параметра
- •Пример_1: в main()– строка-массив; в функции – строка-указатель
- •Пример_2: в main() – строка-указатель; в функции – строка-указатель
- •Передача в функцию массива строк
- •Примеры работы со строками
- •Определение длины строки с помощью функции пользователя
- •Реверс строки (перегрузка функций)
- •Удаление начальных пробелов из строки
- •Проверка, является ли строка целым числом
- •Проверка, является ли строка 16-ичным целым числом
- •Проверка, является ли строка дробным числом без знака
- •Перевод двоичного числа в десятичное
- •Перевод шестнадцатеричного числа в десятичное
- •Перевод десятичного числа в двоичное
- •Перевод десятичного числа в с/с от 2-х до 10
- •Перевод десятичного числа в шестнадцатеричное
- •Определение количества слов в фразе
- •Выделение слов в тексте по нажатию произвольной клавиши
- •Сортировка вводимых с клавиатуры строк *
- •Сортировка строк в зависимости от признака, передаваемого функции main() через аргумент argv *
- •Инвертирование строки с помощью рекурсивной функции
int main ( )
{
char msg[10]; |
|
//определение строки-массива |
|
//msg="hello"; |
|
// error!!! пытаемся изменить указатель-константу!!! |
|
strcpy_s (msg, "hello"); |
|
//ok!!! заполнение строки копированием!!! |
|
char *name; |
//определение указателя на char |
||
//scanf ("%s", name); |
// |
error!!! место под строку-указатель не выделено!!! |
|
name = (char*) malloc(10); |
// |
ok!!! присваивание указателю адреса динамической строки |
|
printf ("name?"); |
// или name = new char[10]; |
||
//ввод строки, перед именем переменной не ставится символ & |
|||
scanf ("%s",name); |
// ввод выполняется до первого пробельного символа
printf ("%s%s", msg, name); _getch();
return 0;
}
Так как имя строки-массива – это указатель-константа, то нельзя выполнить присваивание:
char array[20];
//array = "Literal of string"; // error!!!
Заполнить строку-массив можно с использованием функции копирования (что мы видели в
примере: strcpy_s (msg, "hello");).
При использовании строки-указателя без ее инициализации, необходимо позаботиться о выделении места под строку в динамической памяти.
Ввод-вывод строк
Для ввода-вывода С-строк используются функции printf (),scanf (),gets() и puts(), унаследованные из библиотеки С. Функция gets(s) читает символы с клавиатуры, в томчисле и пробелы ( до символа новой строки), и помещает их в строку, завершая ее 0- символом; функция puts(s) выводит строку, заменяя 0-символ символом новой строки.
// С-ввод строки до первого пробельного символа |
||||
int main() |
|
|
|
|
{ |
|
|
|
|
const int MAX = 80; |
// |
строка-массив |
||
char str[MAX]; |
||||
printf |
("Enter a string: "); |
адрес переменной здесь не указываем |
||
scanf |
("%s", str); |
//odin_dwa |
||
printf("%s", str); |
//odin_dwa |
|
||
printf(" %3s\n", str); |
|
//3 – минимальный размер поля вывода : odin_dwa |
||
printf(" %10.2s\n", str); |
// |
od выравнивание вправо и 2 символа |
||
printf(" %-10.2s\n", str); |
//od |
выравнивание влево и 2 символа |
printf (" string?\n"); |
//вводим: odin dwa, но вводится только odin (до пробела) |
scanf ("%s", str); |
|
printf (" %s\n", str); |
// в буфере ввода остался «хвост» dwa |
//fflush (stdin); |
// для корректной дальнейшей работы scanf() |
printf (" string?\n"); |
// требуется очистка буфера ввода: fflush (stdin); |
scanf ("%s", str); printf (" %s\n", str);
_getch(); return 0;
}
// С-ввод строки с пробелами int main()
{
Программирование – лекция 13 (лекции Стрикелевой Л.В.) |
6 |
|
const int MAX = 10; |
// строка-массив |
||
char str[MAX]; |
|||
printf ("Enter a string: "); |
|
|
|
gets(str); |
//ввод строки: odin dwa |
||
puts(str); |
//вывод строки: odin dwa |
||
_getch(); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
//посимвольный ввод строки в стиле С |
|
|
|
int main() |
|
|
|
{ |
|
|
|
const int MAX = 10; |
// строка-массив |
||
char str[MAX]; |
|||
printf ("Enter a string: "); |
|
|
|
for (int i=0; i<MAX; i++) |
//ввод символов 1234567899 |
||
scanf ("%c", &str[i]); |
|||
str[MAX-1]='\0'; |
|
//вывод строки 123456789 |
|
printf ("%s", str); |
|
||
int i=0; |
|
|
|
printf ("\nEnter a string: "); |
|
// или != ‘\r’ посимвольный ввод |
|
while ( (str[i] = _getch() ) !=13 ) |
|||
_putch (str[i++]); |
|
// посимвольный вывод |
|
str[i] = '\0'; |
|
|
//завершение строки |
_putch ('\n'); _putch ('o'); _putch ('k'); |
|||
printf ("\n%s", str); |
|
//вывод строки |
_getch(); return 0;
}
Для ввода-вывода С-строк в стиле С++ используются известные нам объекты cin и cout.
//ввод строки до первого пробельного символа
int main() |
|
|
{ |
|
|
const int MAX = 80; |
// строка-массив |
|
char str[MAX]; |
||
cout << "Enter a string: "; |
|
|
cin >> str; |
//ввод строки |
|
cout << "You entered: " << str |
<< endl; //вывод строки |
|
_getch(); |
|
|
return 0; |
|
|
} |
|
|
//посимвольный ввод строки |
|
|
int main() |
|
|
{ |
|
|
const int MAX = 10; |
// строка-массив |
|
char str[MAX]; |
||
cout << "Enter a string: "; |
|
|
for (int i=0; i< MAX-1; i++) |
//ввод символов 1234567899 |
|
cin >> str[i]; |
str[MAX-1]='\0';
cout << "You entered: " << str << endl; //вывод строки: 123456789 _getch();
return 0;
}
Для ввода любых символов, включая пробельные, используются методы get() и get(c) класса istream, объектом которого является cin:
char c, d, e;
c=cin.get(); //возвращается код извлеченного из потока символа или EOF
Программирование – лекция 13 (лекции Стрикелевой Л.В.) |
7 |
|
cin.get(d); |
//извлеченный из потока символ записывается в переменную-аргумент |
cin.get(e); |
|
//посимвольный ввод строки с использованием метода get()
int main() |
|
|
|
{ |
= 10; |
|
|
const int MAX |
|
|
|
char str[MAX]; |
// строка-массив |
|
|
cout << "Enter a string: "; |
|
|
|
for (int i=0; |
i< MAX-1; i++) |
//ввод без пробелов символов 12345 |
9 |
|
cin.get(str[i]); |
str[MAX-1]='\0';
cout << "You entered: " << str << endl; //вывод строки 12345 9 _getch();
return 0;
}
Для ввода строки из нескольких слов используются методы getline() или get()
объекта cin:
//ввод строки из нескольких слов с использованием метода getline() int main()
{
const int MAX = 80;
char str[MAX]; |
|
|
cout << "\nEnter a string: "; |
||
cin.getline (str, MAX); |
//ввод строки в str |
|
|
|
//символ ‘\n’ считывается (удаляется) из потока ввода |
|
|
//и вместо него в строковую переменную записывается ‘\0’ |
cout << "You entered: " << str << endl; |
||
cin.get (str, MAX); |
// ввод строки в str |
|
|
//символ ‘\n’ остается в потоке |
|
|
//в строковую переменную добавляется ‘\0’ |
cout << "You entered: " << str << endl; _getch();
return 0;
}
// ввод нескольких строк, завершающихся <enter>, в качестве одной строки const int MAX = 2000;
char str[MAX]; int main()
{ |
|
cout << "\nEnter a string:\n"; |
//ввод всех строк завершается символом $ |
cin.get(str, MAX, '$'); |
cout << "You entered:\n" << str << endl; _getch();
return 0;
}
В этом случае можно ввести несколько строк, завершающихся <enter>, и только затем набрать символ $ (все строки будут восприняты как одна строка):
Enter a string:
qwert 12345
qwert$
You entered: qwert
12345 qwert
Программирование – лекция 13 (лекции Стрикелевой Л.В.) |
8 |
|
Обратите внимание на «плохую» работу метода get() при вызове его с двумя аргументами два раза подряд:
char s[10]; |
|
|
|
int n=5; |
(s, n); |
//1 |
вводим 123<enter>,‘\n’остается в потоке ввода |
cin.get |
|||
cout << |
s << endl; |
//2 |
выводит 123 |
cin.get |
(s, n); |
//3 |
считывает пустую строку |
cout << |
s << endl; |
//4 |
выводит пустую строку |
cin.get |
(s, n); |
//5 |
считывает пустую строку |
cout << |
s << endl; |
//6 |
выводит пустую строку |
cout << |
"end" << endl; |
//7 |
выполняется!!! |
Результат работы:
123
123
end
За выводом в операторе //2 сразу последует сообщение “end”, выведенное оператором //7. Это происходит из-за символа ‘\n’, оставленного в потоке ввода первым вызовом метода get(), т.е. оператором //1. Поэтому операторами //3 и //5 будут считаны (и, соответственно) выведены на экран пустые строки.
Удалить символ ‘\n’ из входного потока можно путем вызова метода get() без
параметров cin.get(): |
|
|
char s[10]; |
|
|
int n=5; |
(s, n); |
//1 вводим 123<enter>,‘\n’остается в потоке ввода |
cin.get |
||
cout << |
s << endl; |
//2 выводит 123 |
cin.get |
(); |
//удаляем ‘\n’ из входного потока |
cin.get |
(s, n); |
//3 вводим 234<enter>,‘\n’остается в потоке ввода |
cout << |
s << endl; |
//4 выводит 234 |
cin.get |
(); |
//удаляем ‘\n’ из входного потока |
cin.get |
(s, n); |
//5 |
cout << |
s << endl; |
//6 |
cout << |
"end" << endl; |
//7 |
Результат работы: 123 123 234 234 345 345
end
Еще лучше – использовать в таких случаях метод getline().
Следующий цикл обеспечивает ввод символов до нажатия ctrl+z – признака конца файла
char c;
while ((c=cin.get())!=EOF) { //ввод символов, выход из цикла – ctrl+z – признак конца файла cout << c;
}
Для ввода нескольких С-строк можно использовать метод getline() в заголовке цикла:
int main()
{
Программирование – лекция 13 (лекции Стрикелевой Л.В.) |
9 |
|