Краткие теоретические сведения. Для представления символьной (текстовой) информации можно использовать символы, символьные переменные и символьные константы

Для представления символьной (текстовой) информации можно использовать символы, символьные переменные и символьные константы.

Символьная константа представляется последовательностью символов, заключенной в кавычки: “Начало строки \n”. В Си нет отдельного типа для строк. Массив символов - это и есть строка. Количества элементов в таком массиве на один элемент больше, чем изображение строки, т. к. в конец строки добавлен ‘\0’ (нулевой байт или нуль-терминатор).

А А \0

‘A’ “A”

символ(1 байт) строка (2 байта)

Присвоить значение массиву символов с помощью обычного оператора присваивания нельзя. Поместить строку в массив можно либо при вводе, либо с помощью инициализации:

char s[] = “ABCDEF”;

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

int getchar(void) - осуществляет вод одного символа их входного потока, при этом она возвращает один байт информации (символ) в виде значения типа int. Это сделано для распознавания ситуации, когда при чтении будет достигнут конец файла.

int putchar (int c) – помещает в стандартный выходной поток символ c.

char* gets(char*s) – считывает строку s из стандартного потока до появления символа ‘\n’, сам символ ‘\n’ в строку не заносится.

int puts(const char* s) записывает строку в стандартный поток, добавляя в конец строки символ ‘\n’, в случае удачного завершения возвращает значение больше или равное 0 и отрицательное значение (EOF=-1) в случае ошибки.

Примеры:

1. char s[20];

cin>>s;//ввод строки из стандартного потока

cout<<s;//вывод строки в стандартный поток

Результат работы программы:

При вводе строки “123 456 789”, чтение байтов осуществляется до первого пробела, т. е. в строку s занесется только первое слово строки “123/0”, следовательно, выведется: 123.

2. char s[20];

gets(s);//ввод строки из стандартного потока

puts(s);//вывод строки в стандартный поток

Результат работы программы:

При вводе строки “123 456 789”, чтение байтов осуществляется до символа ‘\n’, т. е. в s занесется строка”123 456 789\n\0”, при выводе строки функция puts возвращает еще один символ ‘\n’, следовательно, будет выведена строка “123 456 789\n\n”.

3. char s[20];

scanf(“%s”,s);//ввод строки из стандартного потока

printf(“%s”,s);//вывод строки в стандартный поток

Результат работы программы:

При вводе строки “123 456 789”, чтение байтов осуществляется до первого пробела, т. е. в строку s занесется только первое слово строки “123/0”, следовательно, выведется: 123. Т. к. s – имя массива, т. е. адрес его первого элемента, операция & в функции scanf не используется.

Для работы со строками существует специальная библиотека string.h. Примеры функций для работы со строками из библиотеки string.h:

Функция Прототип и краткое описание функции
strcmp int strcmp(const char *str1, const char *str2); Сравнивает строки str1 и str2. Если str1< str2, то результат отрицательный, если str1 = str2, то результат равен 0, если str1> str2, то результат положительный.
strcpy char* strcpy(char*s1, const char *s2); Копирует байты из строки s1 в строку s2
strdup char *strdup (const char *str); Выделяет память и перености в нее копию строки str.
strlen unsigned strlen (const char *str); Вычисляет длину строки str.
strncat char *strncat(char *s1, const char *s2, int kol); Приписывает kol символов строки s1 к строке s2.
strncpy char *strncpy(char *s1, const char *s2, int kol); Копирует kol символов строки s1 в строку s2.
strnset char *strnset(char *str, int c, int kol); Заменяет первые kol символов строки s1 символом с.

 

Строки, при передаче в функцию, в качестве фактических параметров могут быть определены либо как одномерные массивы типа char[], либо как указатели типа char*. В отличие от обычных массивов в этом случае нет необходимости явно указывать длину строки.

При работе со строками часто используются указатели.

Распространенные ошибки при работе со строками — отсутствие нуль-символа и выход указателя при просмотре строки за ее пределы.

Рассмотрим процесс копирования строки src в строку dest. Очевидный алгоритм имеет вид:

char src[10], dest[10];

for (int i = 0; i<=strlen(src); i++) dest[i] = src[i];

Длина строки определяется с помощью функции strlen, которая вычисляет длину, выполняя поиск нуль-символа. Таким образом, строка фактически просматривается дважды. Более эффективным будет использовать проверку на нуль-символ непосредственно в программе. Увеличение индекса можно заменить инкрементом указателей (для этого память под строку src должна выделяться динамически, а также требуется определить дополнительный указатель и инициализировать его адресом начала строки dest):

#include <iostream.h>

int main()

{

char *src = new char [10];

char *dest = new char [10], *d = dest;

cin >>src;

while ( *src != 0) *d++ = *src++;

*d = 0; // завершающий нуль

cout <<dest;

return 0;

}

В цикле производится посимвольное присваивание элементов строк с одновременной инкрементацией указателей. Результат операции присваивания — передаваемое значение, которое, собственно, и проверяется в условии цикла, поэтому можно поставить присваивание на место условия, а проверку на неравенство нулю опустить (при этом завершающий нуль копируется в цикле, и отдельного оператора для его присваивания не требуется). В результате цикл копирования строки принимает вид:

while ( *d++ = *src++);

Оба способа работы со строками (через массивы или указатели) приемлемы и имеют свои плюсы и минусы, но в общем случае лучше не изобретать велосипед, а пользоваться функциями библиотеки или определенным в стандартной библиотеке C++ классом string, который обеспечивает индексацию, присваивание, сравнение, добавление, объединение строк и поиск подстрок, а также преобразование из С-строк, то есть массивов типа char, в string, и наоборот.

Строки C++ не обязательно должны состоять из символов типа char. Это позволяет использовать любой набор символов (не только ASCII), но для произвольного набора следует определить собственную операцию копирования, что может снизить эффективность работы.

Пример :

Сформировать динамический массив строк. Удалить из него строку с заданным номером.

#include <iostream.h>

#include <string.h>

void main()

{

int n;

cout<<"\n Число строк N=?";cin>>n;

char s[100];

char**matr=new char*[n];

for(int i=0;i<n;i++)

{

cout<<"\nВведите строку (без пробела)S=?";

cin>>s; /* можно использовать здесь функцию gets(s) и тогда можно вводить пробелы*/

matr[i]=new char[strlen(s)];

strcpy(matr[i],s);

}

for(i=0;i<n;i++)

{

cout<<matr[i];

cout<<"\n";

}

int k;

cout<<"\nВведите номер строки, которую необходимо удалитьK=?";

cin>>k;

if(k>=n){cout<<"Нет такой строки\n";return;}

char **temp=new char*[n-1];

int j=0;

for(i=0;i<n;i++)

if(i!=k)

{

temp[j]=new char[strlen(matr[i])];

strcpy(temp[j],matr[i]);

j++;

}

n--;

for(i=0;i<n;i++)

{

cout<<temp[i];

cout<<"\n";

}

}

Постановка задачи

 

Задана строка, состоящая из символов. Символы объединяются в слова. Слова друг от друга отделяются одним или несколькими пробелами. В конце текста ставится точка. Текст содержит не более 255 символов. Выполнить ввод строки, используя функцию Gets(s) и обработку строки в соответствии со своим вариантом.

 

Варианты

 

Вариант 1.

Проверить является ли строка палиндромом. (Палиндром - это выражение, которое читается одинакова слева направо и справа налево).

 

Вариант 2.

Напечатать самое длинное и самое короткое слово в этой строке.

 

Вариант 3.

Напечатать все слова, которые не содержат гласных букв.

 

Вариант 4.

Напечатать все слова, которые содержат по одной цифре.

 

Вариант 4.

Напечатать все слова, которые совпадают с ее первым словом.

 

Вариант 5.

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

 

Вариант 6.

Преобразовать строку так, чтобы все буквы в ней были отсортированы по возрастанию.

 

Вариант 7.

Преобразовать строку так, чтобы все цифры в ней были отсортированы по убыванию.

 

Вариант 8.

Преобразовать строку так, чтобы все слова в ней стали идентификаторами, слова состоящие только из цифр - удалить.

 

Вариант 9.

Напечатать все слова-палиндромы, которые есть в этой строке(см 1 вариант).

 

 

Вариант 10.

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

 

Вариант 11.

Преобразовать строку таким образом, чтобы все слова в ней были напечатаны наоборот.

 

Вариант 12.

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

 

Вариант 13.

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

 

Вариант 14.

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

 

Вариант 15.

Определить какое слово встречается в строке чаще всего.

 

Вариант 16.

Определить какие слова встречаются в строке по одному разу.

 

Вариант 17.

Все слова строки, которые начинаются с буквы, отсортировать в алфавитном порядке.

 

Вариант 18.

Все слова строки, которые начинаются с цифры отсортировать по убыванию.

 

Вариант 19.

Удалить из строки все слова, которые не являются идентификаторами.

Содержание отчета

1. Постановка задачи;

2. Исходные данные;

3. Алгоритм решения;

4. Листинг программы;

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

Контрольные вопросы

 

1. Особенности представления символьных и строковых данных в C/C++;

2. Ввод и вывод символьных данных в C/C++;

3. Функции для работы со строками. Примеры;

4. Особенности использования указателей при работе со строками.


 

Лабораторная работа № 8

 

«СТРУКТУРЫ»

Цель:Изучение структурных данных и методов работы с ними средствами языка Си.

Краткое теоритическое введение

Понятие структуры.Структура – это объединенное в единое целое множество поименованных элементов данных. Элементы структуры (поля) могут быть различного типа, они все должны иметь различные имена.

Форматы определения структурного типа следующие:

struct имя_типа //способ 1

{

тип 1 элемент1;

тип2 элемент2;

. . .

};

Пример:

struct Date//определение структуры

{

int day;

int month;

int year;

};

Date birthday;//переменная типа Date

struct //способ 2

{

тип 1 элемент1;

тип2 элемент2;

. . .

} список идентификаторов;

Пример:

struct

{

int min;

int sec;

int msec;

} time_beg, time_end;

 

В первом случае описание структур определяет новый тип, имя которого можно использовать наряду со стандартными типами.

Во втором случае описание структуры служит определением переменных.

Структурный тип можно также задать с помощью ключевого слова typedef:

typedef struct //способ 3

{

floar re;

float im;

} Complex;

Complex a[100];//массив из 100 комплексных чисел.

Инициализация структур

 

Для инициализации структур значения ее полей перечисляют в фигурных скобках.

Примеры:

struct Student

{

char name[20];

int kurs;

float rating;

};

Student s={”Иванов”,1,3.5};

struct

{

char name[20];

char title[30];

float rate;

}employee={“Петров", “директор”,10000};

Работа со структурами

Присваивание структур

 

Для переменных одного и того же структурного типа определена операция присваивания. При этом происходит поэлементное копирование.

Student ss=s;



/cgi-bin/footer.php"; ?>