Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Краткие сведения о работе со строками




Теоретическая часть.

Лабораторная работа №4.

Рекомендации по выполнению лабораторной работы.

 

Рекомендуемый алгоритм работы программы:

1. Посимвольно ввести 1-ое число (рекомендуется написание функции). Ввод числа состоит из следующих шагов:

a) выдается приглашение пользователю для ввода числа.

b) пока не достигнуто максимальное число цифр в числе или не нажата клавиша Enter (клавиша генерирует 2 символа с кодами #13#10) осуществляется ввод очередной цифры числа. Цифры вводятся в виде соответствующих символов.

c) производится выравнивание числа по правому краю. Для этого можно использовать функцию memmove.

2. Посимвольно ввести 2-ое число. Осуществляется аналогично вводу 1-ого числа.

3. Выбор действия (сложение или вычитание), если в задании реализуются оба действия.

4. Сложение (рекомендуется написание функции). Производится посимвольно справа налево. Причем при сложении каждых двух цифр необходимо учитывать разряд переноса от предыдущего сложения и формировать разряд переноса для следующего сложения. Т.к. каждая цифра представлена в виде символа, а этот тип данных не поддерживает арифметических операций, то ее необходимо перевести в числовое представление. Для этого можно вычесть из нее код символа ‘0’.

5. Вычитание (рекомендуется написание функции). Аналогично сложению, производится справа налево. При вычитании каждой пары цифр необходимо учитывать разряд заёма от предыдущего вычитания и формировать разряд заёма для следующего вычитания. Очевидно, что при вычитании двух цифр вычитание кода символа ‘0’ производить не нужно.

6. Вывести результат выполнения действия на экран (рекомендуется написание функции). Начиная с первого значащего символа (или знака числа) выводятся все цифры числа на экран.


Цель работы: изучить работу со строками, тип данных структура (struct) и основные приемы для работы с ним. Научиться применять полученные теоретические знания при написании программ.

 

Как уже говорилось в лабораторной работе №1, строка на языке C++ представляет собой последовательность символов, которая должна заканчиваться символом с ASCII кодом 0 (’\0’). Для стандартных функций, предназначенных для работы со строками, этот символ является ЕДИНТСВЕННЫМ признаком, на основании которого определяется конец строки. Такой подход для определения конца строки называется NULL terminated strings (строки, оканчивающиеся нулем).

Для хранения символов строки можно использовать статические или динамические одномерные массивы символов. Работа со статическими массивами (память под переменные типа массив выделяется в процессе компиляции программы) была рассмотрена в лабораторной работе №3.

Динамический одномерный массив символов отличается от статического тем, что память под хранение его элементов выделяется в процессе работы программы в специальной области памяти, которая называется куча (heap), причем количество выделенной памяти можно изменять, в отличие от статических массивов. Таким образом, динамический массив представляет собой указатель (номер ячейки памяти) на начало непрерывного участка памяти, который выделен в куче для хранения его элементов.

Пример описания переменной-указателя для работы с одномерным динамическим массивом:

char *st;

При описании переменных, как уже говорилось в лабораторной работе №3, символ * означает, что описывается типизированный указатель, т.е. указатель на значение определенного типа, в данном случае - char. Сам по себе указатель - это беззнаковое целочисленное 32-битное значение. При описании указателя областью действия знака * (собственно, признак указателя) является ОДНА СЛЕДУЮЩАЯ ПЕРЕМЕННАЯ.

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

int n;

//…..

scanf(”%i”, &n);

//…..

st = new char [n];

В этой записи после оператора new через пробел ставится тип данных, память под значение которого будет выделена (в примере - char). Если необходимо, как в приведенном примере, выделить память под массив, то после типа данных нужно через пробел в квадратных скобках указать количество (натуральное число) таких элементов. Для указания количества элементов можно использовать константы, выражения и переменные. Если память была выделена удачно, то в переменную st будет записан адрес начала выделенного блока, в противном случае - будет записан NULL.

Следует обратить внимание на тот факт, что обращаться к элементам динамического массива можно ТОЛЬКО ПОСЛЕ УДАЧНОГО ВЫДЕЛЕНИЯ ПАМЯТИ по требованию программы. Обращение к области памяти, которая не принадлежит Вашей программе (в том числе и адрес NULL), немедленно приводит к ошибке и работа программы прекращается.

Обращаться к элементам динамического массива можно также как и к элементам статического, например:

printf(”%c\n”, st[3]);

что приводит к выводу на экран 4-ого элемента массива. Следует обратить внимание, что при работе с динамическим массивом обращение к несуществующему элементу практически всегда приводит к аварийному завершению программы.

Другим способом обращения к элементу является операция разименования (*), например:

printf(”%c\n”, *(st + 3));

т.е. к указателю на начало добавляется число 3, после чего выполняется разименование - доступ к значению по указанному адресу.

После работы с динамическим массивом перед завершением программы нужно ОБЯЗАТЕЛЬНО освободить память, выделенную под него. Для этого можно воспользоваться оператором delete. Для рассмотренного выше массива это можно сделать следующим образом:

delete []st;

При освобождении памяти из-под динамических массивов перед указателем надо поставить квадратные скобки. Следует отметить, что после освобождения памяти переменная st будет хранить тот же адрес, но обращаться к значению по этому адресу уже нельзя, т.к. эта область памяти программе больше не принадлежит.

Для того чтобы понять корректный или нет адрес хранится в переменной-указателе рекомендуется до выделения памяти и после ее освобождения присваивать этой переменной значение NULL. Это и будет признаком некорректности адреса.

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

Существует ряд стандартных функций, разработанных специально для работы со строками. Для их использования необходимо подключить файл string.h. Также следует отметить, что все рассмотренные ниже функции не могут корректно обработать ситуацию, когда указатель на строку = NULL (произойдет ошибка выполнения программы). Рассмотрим эти функции, на примере работы с переменной st, предположив, что под нее выделено 15 байт и в нее считана с клавиатуры строка ”1234567” (сначала приводится описание прототипа, потом - пример использования функции, в случае необходимости):

- size_t strlen(const char *st), возвращает длину строки в символах (байтах), таким образом, strlen (st) в нашем случае вернет значение 7 (символ с ASCII кодом 0 не считается), причем st может быть переменной или константой;

- char *strcat(char *strDest, const char *strSrc) дописывает содержимое строки, на которую указывает strSrc к строке, на которую указывает strDest. Через свое имя возвращает указатель strDest. Например: в результате выполнения такого вызова strcat (st, ”890”) будет получено значение ”1234567890”. 1-ый аргумент strcat должен быть ТОЛЬКО переменной, 2-ой -может быть переменной или константой;

- char *strncat(char *strDest, const char *strSrc, size_t count) аналогично предыдущей функции, но дописывает только count символов из 2-ой строки в 1-ую. Следует отметить, что при использовании этой функции нужно самостоятельно добавлять символ с кодом 0 в конце строки, на которую указывает 1-ый аргумент, в случае, когда символ с кодом 0 не был скопирован из строки-источника;

- char *strstr(const char *str, const char *strSearch) осуществляет поиск начала подстроки, на которую указывает strSearch, в строке, на которую указывает str и, если strSearch будет найдена в строке str, то возвращает указатель на 1-ый символ строки strSearch в строке str, в противном случае будет возвращен NULL. Если strSearch указывает на пустую строку (обозначается ””), то возвращается str. Например: strstr (st, ”234”) вернет значение указатель на символ 2 в строке str, а strstr (st, ”235”) вернет NULL. Аргументы strstr могут быть переменными или константами;

- char *strchr(const char *str, int c) осуществляет поиск символа c в строке (слева направо), на которую указывает str и, если c будет найден в строке str, то возвращает указатель на 1-ый такой символ в строке str, в противном случае будет возвращен NULL. Например: strchr (st, ’2’) вернет значение указатель на символ 2 в строке str, а strstr (st, ’0’) вернет NULL. Аргументы strchr могут быть переменными или константами;

- char *strrchr(const char *str, int c) практически полностью аналогична strchr, за исключением того, что поиск производится справа налево;

- int strcmp(const char *string1, const char *string2) - осуществляет по символьное сравнение двух строк (с учетом регистра буквенных символов). Если 1-ая строка < 2-ой, то возвращается значение < 0, если равны - 0, если больше - значение больше 0. Например, strcmp( st, ”1234567” ) вернет 0, а strcmp( st, ”912” ) - значение < 0. Аргументы strcmp могут быть переменными или константами;

- int strncmp(const char *string1, const char *string2, size_t count) аналогична предыдущей функции, но сравнивает только 1-ых count символов;

- int stricmp(const char *string1, const char *string2) аналогична функции strcmp, но сравнение происходит без учета регистра буквенных символов;

- int strnicmp(const char *string1, const char *string2) аналогична функции strncmp, но сравнение происходит без учета регистра буквенных символов;

- char *strcpy(char *strDest, const char *strSrc) копирует содержимое строки, на которую указывает strSrc, в строку, на которую указывает strDest. 1-ый аргумент strcpy должен быть ТОЛЬКО переменной, 2-ой -может быть переменной или константой;

- char *strncpy(char *strDest, const char *strSrc, size_t count) аналогична предыдущей, но копирует только указанное количество символов count. Следует отметить, что при использовании этой функции нужно самостоятельно добавлять символ с кодом 0 в конце строки, на которую указывает 1-ый аргумент, в случае, когда символ с кодом 0 не был скопирован из строки-источника;

- char *_strdup(const char *strSrc) делает копию строки - своего аргумента и возвращает указатель на эту копию. Аргумент может быть переменной или константой;

- char *_strrev(char *str) переставляет символы в строке в обратном порядке и возвращает указатель на строку str. Например, в результате выполнения _strrev (st) st будет указывать на строку, содержащую ”7654321”. Аргумент может быть ТОЛЬКО переменной;

- char *_strset(char *str, int c) устанавливает все символы строки равными символу c. Пример: в результате выполнения _strset( st, ’2’ ) st будет указывать на строку ”2222222”. 1-ый аргумент _ strset должен быть ТОЛЬКО переменной, 2-ой -может быть переменной или константой;

- char *_strnset(char *str, int c, size_t count) аналогична предыдущей, но изменяет на символ c только указанное количество символов count;

- char *_strlwr(char *str) переводит все буквенные символы в нижний регистр. Через свое имя возвращает str. Аргумент может быть ТОЛЬКО переменной;

- char *_strupr(char *str) переводит все буквенные символы в верхний регистр. Через свое имя возвращает str. Аргумент может быть ТОЛЬКО переменной;

- Для использования следующих функций необходимо подключить stdio.h.

- int puts(const char *str) выводит на в стандартный выходной поток stdout содержимое строки, на которую указывает str. По окончании вывода происходит перевод курсора на новую строку. Возвращает EOF в случае неудачного окончания вывода. Аргумент может быть переменной или константой;

- int sprintf(char *buffer, const char *format, необязательный_перечень_аргументов) аналогична printf, но форматный вывод производится в строку (1-ый аргумент функции).

Удаление и вставку части строки можно реализовать с использованием функции memmove.

 

Следует отметить, что в C++ для работы со строками можно также использовать тип данных string. Однако, в отличие от языка Паскаль, тип данных string является шаблонным классом из STL (Standard Template Library) с перегруженными операторами (о перегрузке операторов будет сказано ниже). Рассмотрим пример использования этого типа данных:

 

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

 

#include "stdafx.h"

// Необходимо для компиляции проекта в среде Microsoft Visual Studio 2005

#include <string>

#include <iostream>

// Необходимо указывать без расширения h

using namespace std;

// Использование пространства имен std

main()

{

string str1, str2, str3;

cout << "Enter string 1: ";

getline(cin, str1);

/*

Следует отметить, что для ввода данных используется функция getline (функция scanf неприменима) из пространства имен std. Эта функция 1-ым апгументом получает имя входного потока, 2-ым - имя переменной типа string, а 3-им, необязательным - символ, после которого символы прекращают сохраняться во внутренний буфер (по умолчанию - это ‘\n’), причем ввод прекращается по нажатию клавиши Enter или по достижению максимально возможной длины буфера.

Также можно осуществить ввод данных в переменную str1 с помощью входного потока cin следующим образом:

cin >> str1;




Поделиться с друзьями:


Дата добавления: 2017-01-14; Просмотров: 735; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.037 сек.