Символьные переменные и строки. Обработка строк. 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Символьные переменные и строки. Обработка строк.



 

Строка представляет собой массив символов, завершающийся так называемым нуль-символом — символом с кодом 0 (’\0’). По положению нуль-символа определяется реальная длина строки. Например, определение переменной-строки из 79 символов выглядит так:

char s1[80];

Строки можно при их определении инициализировать строковыми константами (см. раздел “ Основные типы данных, операции и выражения ”); при этом нуль-символ в конце строки формируется автоматически:

 

char s1[80] = “Здесь был Вася”;

либо даже так:

char s1[] = “Здесь был Вася”;

В последнем случае компилятор сам выделит память, достаточную для размещения строки с завершающим нулём. Если инициализирующая строка короче, чем указанный размер строки, то оставшиеся элементы строки инициализируются символом ‘\0’.

Определить в программе константу-строку MSG можно одним из следующих способов:

#define MSG “Умом Россию не понять”

или

const char MSG[ ] = “Умом Россию не понять”;

 

Имя переменной-строки (без квадратных скобок) отождествляется в программе с ее адресом. Поэтому операции присваивания и сравнения для строк c завершающим нуль-символом в С/С++ недопустимы. Нельзя, например, использовать такую последовательность предписаний:

 

char str[80];

str = “ Здесь был Вася ”;

 

Для присваивания переменной строкового литерала можно использовать подходящую стандартную функцию библиотеки языка:

 

strcpy(str, “ Здесь был Вася ”);

 

Библиотека стандартных функций имеет в своем составе множество полезных функций для работы со строками, в том числе: для вычисления реальной длины строки (strlen()); сцепления строк (strcat(), strncat()); сравнения строк (strcmp(), strncmp()); поиска вхождения символа в строку (strchr()); поиска подстроки в строке (strstr()) и др. Эти функции описаны в заголовочном файле <string.h> (<cstring>). Более подробно синтаксис каждой из них легко выяснить с помощью справочной системы Интегрированной среды разработки.

 

Дадим краткое описание важнейших функций

 

Функция strlen(s1) возвращает длину строки, указанной аргументом s1.

Функция strcpy(s1, s2) копирует содержимое строки s2 в строку s1. Строка s1 должна быть достаточно протяженной, чтобы в неё можно было поместить строку s2. В противном случае возможно аварийное завершение программы.

 

Функция strcat(s1, s2) присоединяет строку s2 вконец строки s1, при этом строка s2 не изменяется. Обе строки должны завершаться нулевым символом. Результирующая строка s1 также будет завершаться нулевым символом. Строка s1 должна быть достаточно большой, чтобы в нее поместилось, кроме ее исходного содержимого, содержимое строки s2.

 

Функция strcmp(s1, s2) сравнивает строку s2 со строкой s1 и возвращает значение 0, если они равны. Если строка s1 лексикографически (т.е. в соответствии с алфавитным порядком) больше строки s2, возвращается положительное число; если строка s1 лексикографически меньше строки s2, возвращается отрицательное число. Точнее говоря, функция возвращает разность кодов первой пары несовпавших символов.

 

 

В стандартной библиотеке имеются полезные функции преобразования строк в числа (разумеется, если это возможно):

atof() – преобразует заданную строку в double; atoi() – преобразует строку в int; atol() – в long. Если строку нельзя преобразовать в число, возвращается 0. Обратные преобразования можно осуществить с помощью библиотечной функции sprintf().

 

В языке C++ существует и другой тип представления строк. Он заключается в применении объектов класса string, который является частью библиотеки классов C++.

Таким образом, класс string — не встроенный тип. Он подразумевает объектно-ориентированный подход к обработке строк, обеспечивает удобные для пользователя операции и методы: ввод и вывод строк, присваивание, сравнение, конкатенацию строк, поиск подстроки и др. Важно отметить, что строки типа string защищены от выхода информации за их границы (длина строки изменяется динамически в соответствии с потребностями). Однако тип string проигрывает массивам символов в эффективности и используется не так широко, как строки с завершающим нулем. В дальнейшем мы рассматриваем в основном строки с завершающим нулем.

Покажем для сравнения важнейшие операции для работы со строками, используя параллельно оба метода.

 

 

// Программа отлажена в Visual Studio 2008

#include <iostream>

#include <string.h>

#include <string>

using namespace std;

int main()

{ char c1[80], c2[80],c3[80]; //строки с 0-символом

string s1, s2, s3; //объекты класса string

 

//Присваивание строк

strcpy_s(c1,"Стиль языка С");

strcpy_s(c2, c1);

s1="Стиль языка С++";

s2=s1;

 

//Сцепление строк

strcpy_s(c3,"1 - ");

strcat_s(c3, c2); cout<<c3<<endl;

 

s1="2 - ";

s3=s1 + s2; cout<<s3<<endl;

 

return 0;

}

 

Результат выполнения программы:

 

1 – Стиль языка С

2 – Стиль языка С++

 

 

Ввод – вывод строк.

 

Для ввода‑вывода строк естественно пытаться использовать известные нам объекты cin и cout языка C++, а также функции языка С (scanf(), printf(), gets(), puts() и др.)

В отличие от массивов, строки вводятся и выдаются на экран не поэлементно, а целиком, что присуще простым переменным:

char s1[80]; cout << “Как тебя зовут?”;

cin >> S1; cout << “Привет” << S1;

 

Следует иметь в виду, что если количество вводимых символов превышает длину строки, определённую при её описании, то поведение программы непредсказуемо.

Рассмотрим примеры.

 

 

Задача 106. Программа запрашивает имя пользователя и после ответа приветствует его по имени. Используется стиль C++.

#include <iostream.h>

#include <conio.h>

void main()

{

char S1[80];

cout<<"Как тебя зовут? ";

cin>>S1;

cout<<"Привет, "<<S1<<”!”;

getch();

}

 

 

Задача 107. Программа запрашивает имя пользователя и после ответа приветствует его по имени. Используется стиль C.

#include <conio.h>

#include <stdio.h>

void main()

{

 

char S1[80];

printf("Как тебя зовут? ");

scanf("%s", S1);

printf("Привет, %s\n! ", S1);

getch();

}

 

Протестируйте две приведенные выше программы. Сначала введите имя, состоящее из одного слова. Обе программы корректно обрабатывают введённую строку и выдают правильные результаты. Введите теперь имя, состоящее из двух слов (например, Наполеон Бонапарт). Во втором случае в приветствии выводится только первое слово! Это вызвано тем, что ввод строки средствами cin и scanf() осуществляется до первого пробельного символа (т.е. пробела, знака табуляции и символа перевода строки ‘\n’).

Рассмотрим ещё один пример.

 

Задача 108. Программа запрашивает имя пользователя и его любимый напиток, а после ответа приветствует его по имени. Используется стиль C++.

 

// Программа отлажена в Visual Studio 2008

#include <iostream>

#include <string.h>

#include <conio.h>

using namespace std;

 

 

int main()

{

char name[25],drink[25];

// Устанавливаем локализацию для выходного потока

wcout.imbue(locale("rus_rus.866"));

// Выводим строку на русском!

wcout<<L"Как Вас зовут? ";

cin>>name;

wcout <<L"Ваш любимый напиток? "; cin>>drink;

wcout<<L"Привет, "<<name<<'\n';

wcout<<L"Да, "<<drink<<L" - чудесный напиток"<<endl;

_getch(); return 0;

}

 

Чтобы помочь вам разобраться в том, что делает эта программа, приведём результаты её работы (полужирным курсивом выделен текст, вводимый пользователем):

 

Как Вас зовут? Бонапарт Наполеон

Ваш любимый напиток? Привет, Бонапарт

Да, Наполеон - чудесный напиток

 

Таким образом, текст, введённый после пробельного символа, не игнорируется! Он сохраняется в специальном буфере ввода‑вывода и извлекается оттуда при вызове очередной функции ввода данных. Этим и объясняется, что вводить по оператору

сin >> drink;

ничего не понадобилось: фраза “Наполеон” была извлечена из буфера.

Применение функции scanf() вместо cin приводит к аналогичным результатам. Протестируйте следующую задачу самостоятельно.

 

 

Задача 109. Программа запрашивает имя пользователя и его любимый напиток, а после ответа приветствует его по имени. Используется стиль C.

#include <stdio.h>

#include <conio.h>

void main()

{

char name[15],drink[12];

printf("Как Вас зовут? "); scanf("%s",name);

printf("Ваш любимый напиток? "); scanf("%s",drink);

printf("Привет, %s\n",name);

printf("Да, %s - чудесный напиток\n",drink);

getch();

}

 

В дальнейшем для ввода строк будем в основном использовать функцию gets(S1) (S1 — имя вводимой строки), которая лишена указанного выше недостатка. Эта функция вводит все символы входного потока, в том числе и пробелы, пока не будет нажата клавиша Enter. Код клавиши Enter преобразуется в нуль-символ и все введенные символы заполняют строковую переменную S1. Но и эта функция не безгрешна: если количество вводимых символов превышает длину строки S1, определённую при её описании, то, скорее всего, программа завершится аварийно.

 

Что же касается вывода строк, то можно с одинаковым успехом применять метод cout, функции printf(), puts():

 

cout << “Привет, ” << name << endl;

printf (“Привет, %s\n”, name);

puts(“Привет,”); puts(name);

 

Следует иметь в виду, что функция printf() менее удобна, чем puts(), но более гибкая. В частности, printf(), в отличие от puts(), не выводит автоматически каждую строку текста с новой строки экрана. С другой строки, функция puts() выводит за одно обращение к ней только одну строку символов, а printf() может легко объединить несколько выводимых строк в одну:

 

сhar name[20], S1[] = “Привет,”;

printf(Как тебя зовут?); gets(name);

printf(“%s %s\n”, S1, name);

 

Задача 110. Программа запрашивает имя пользователя и его любимый напиток, а после ответа приветствует его по имени. Используются функции gets(), puts() и printf() для ввода-вывода. Теперь программа работает корректно.

 

#include "stdafx.h"

#include <stdio.h>

#include <conio.h>

int main()

{

char name[15],drink[12];

puts("Как Вас зовут? "); gets(name);

puts("Ваш любимый напиток? "); gets(drink);

printf("Привет, %s\n",name);

printf("Да, %s - чудесный напиток\n",drink);

_getch(); return 0;

}

 

 



Поделиться:


Последнее изменение этой страницы: 2016-12-16; просмотров: 466; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.145.206.169 (0.04 с.)