Strrchr   strset работа со строками


Содержание

Функции для работы со строками

Пожалуйста, приостановите работу AdBlock на этом сайте.

В языке Си предусмотрено множество разных функций, предназначенных для работы со строками. Для их использования необходимо подключить заголовочный файл string.h

Разберём самые простые из них:

  • strlen(str) – длина строки str ;
  • strcmp(str1, str2) – сравнение строк str1 и str2 ;
  • strcat(str1, str2) – конкатенация (склеивание) двух строк. К строке str1 в конце приклеивается строка str2 .
  • strcpy(str1, str2) – копирование строки str2 в строку str1 ;

Функция strlen

Данная функция возвращает целое число – длину строки, которая ей передана в качестве аргумента.

Обратите внимание. Длина строки – это не количество элементов символьного массива, а количество элементов в массиве до первого нуль-символа. Например, следующий код выведет на экран не 19 , а 7 .

Рис.1 Работа функции strlen.

Функция склеивания строк strcat.

Данная функция склеивает строки, которые передаются ей в качестве параметров. Функция strcat присоединяет к концу строки str1 строку str2 .

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

Результат работы этой программы ниже:

Рис.2 Работа функции strcat.

Функция сравнения строк strcmp

Данная функция сравнивает посимвольно строки, переданные ей в качестве аргументов. Функция strcmp вернёт нуль, если строки равны между собой, иначе какое-либо другое целое число (положительное или отрицательное). Общее правило таково: Если в функции strcmp() первая строка больше, чем вторая строка, то функция возвращает положительное число. Если меньше – отрицательное. Сравнение осуществляется по кодам символов в таблице ASCII

Посмотрите на пример.

Рис.3 Работа функции strcmp.

Первая и вторая строки одинаковы, поэтому результат их сравнения нуль. А вот первая и третья строки различаются седьмым символом. В первой строке это строчная w , а в третьей – прописная W . Т.к. код строчной буквы w больше, чем код прописной буквы W (119 > 87) , то в n13 помещается положительное число, т.к. первая строка, больше второй. Теперь если мы поменяем строки местами, то получим отрицательное число.

Функция копирования строк strcpy.

Данная функция принимает на вход две строки, а потом копирует вторую строку в первую. Простой примерчик.

Рис.4 Работа функции strcpy.

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

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

Практика

Решите предложенные задачи:

Для удобства работы сразу переходите в полноэкранный режим

Исследовательские задачи для хакеров

  1. (Листинг 2) Попробуйте самостоятельно, добавляя символов в строки str2 или str3 , добиться того, чтобы программа завершалась с ошибкой.
  2. (Листинг 4) Попробуйте скопировать первую строку во вторую, поменяв их местами в вызове функции strcpy .

Функции обработки строк в Cи

В программе строки могут определяться следующим образом:

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

Кроме того, должно быть предусмотрено выделение памяти для хранения строки.

Любая последовательность символов, заключенная в двойные кавычки «» , рассматривается как строковая константа .

Для корректного вывода любая строка должна заканчиваться нуль-символом ‘\0’ , целочисленное значение которого равно 0. При объявлении строковой константы нуль-символ добавляется к ней автоматически. Так, последовательность символов, представляющая собой строковую константу, будет размещена в оперативной памяти компьютера, включая нулевой байт.

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

Для помещения в строковую константу некоторых служебных символов используются символьные комбинации. Так, если необходимо включить в строку символ двойной кавычки, ему должен предшествовать символ «обратный слеш»: ‘\»‘ .

Строковые константы размещаются в статической памяти. Начальный адрес последовательности символов в двойных кавычках трактуется как адрес строки. Строковые константы часто используются для осуществления диалога с пользователем в таких функциях, как printf() .

При определении массива символов необходимо сообщить компилятору требуемый размер памяти.

Компилятор также может самостоятельно определить размер массива символов, если инициализация массива задана при объявлении строковой константой:

В этом случае имена m2 и m3 являются указателями на первые элементы массивов:

  • m2 эквивалентно &m2[0]
  • m2[0] эквивалентно ‘Г’
  • m2[1] эквивалентно ‘o’
  • m3 эквивалентно &m3[0]
  • m3[2] эквивалентно ‘x’

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

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

В этом случае объявление массива переменной m4 может быть присвоен адрес массива:

Здесь m3 является константой-указателем. Нельзя изменить m3 , так как это означало бы изменение положения (адреса) массива в памяти, в отличие от m4 .

Для указателя можно использовать операцию увеличения (перемещения на следующий символ):

Массивы символьных строк

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

В этом случае poet является массивом, состоящим из четырех указателей на символьные строки. Каждая строка символов представляет собой символьный массив, поэтому имеется четыре указателя на массивы. Указатель poet[0] ссылается на первую строку:
*poet[0] эквивалентно ‘П’,
*poet[l] эквивалентно ‘-‘.

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

Разница заключается в том, что такая форма задает «прямоугольный» массив, в котором все строки имеют одинаковую длину.

IT Памятка

Чтобы не забыть и впоследствии освежить память

Распространенные функции для работы со строками С++

Функции для работы со строками

Для преобразования строк в языке Си предусмотрена библиотека string.

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

void *strcat(char *s1,const char *s2) – дополняет строку s1 строкой s2.

char *strncat(char *s1,const char *s2, size_t n) – дополняет строку s1 символами из строки s2, но не более чем n штук.

char *strcpy(char *s1,const char *s2) – копирует строку, указанную указателем s2, на место, указанное указателем s1; возвращает s1.

char *stpcpy(char *dest, const char *src) – копирует строку, указанную указателем src, на место, указанное указателем dest; не копирует символ конца строки;

char *strncpy(char *s1, const char *s2, size_t n) – копирует строку, указанную указателем s2, на место, указанное указателем s1; возвращает s1; копируется не более чем n символов.

int strcmp(const char *s1,const char *s2) – сравнивает строки, указанные указателями s1 и s2; символы строк сравнивают с помощью значений их кодов; функция возвращает 0, если строки одинаковы; значение, которое меньше 0, если первая строка меньше второй; и значение, превышающее 0, если первая строка больше второй.

int strncmp(const char *s1,const char *s2, size_t n ) – сравнивает первые n символов или до первого пустого символа строки, указанные указателями s1 и s2.

int stricmp(const char *s1,const char *s2) – сравнивает строки, указанные указателями s1 и s2, игнорируя регистр символов (строчные или заглавные);

int strcmpi(const char *s1,const char *s2) – сравнивает строки, указанные указателями s1 и s2, игнорируя регистр символов (строчные или заглавные);

char *strchr(const chat *s, int c) – ищет первое появление c (преобразованного в char) в строке, указанной указателем s; пустой символ является частью строки; возвращает указа-тель на первое появление или NULL, если ничего не найдено.

char *strrchr(const chat *s, int c) – ищет последнее появление символа c в строке, то есть поиск идет с конца строки, заданной указателем s; пустой символ является частью строки; возвращает указатель на первое появление или NULL, если ничего не найдено.

char *strstr(const chat *s1, const char *s2) – возвращает указатель на положение первого появления последовательности символов из s2 в строке s1 (исключая завершающие про-белы); возвращает NULL, если совпадений не найдено.

char *strtok(chat *s1,const chat *s2) – эта функция переформирует строку s1 в отдельные знаки; строка s2 содержит символы, которые используются в качестве разделителей. Функция вызывается последовательно. Для первого вызова s1 должен указывать на стро-ку, которую необходимо разбить на знаки. Функция находит разделитель, который следует за символом, не являющимся разделителем, и заменяет, его пробелом. Она возвращает указатель на строку, содержащую первый знак. Если ни оного знака не найдено, она воз-вращает NULL. Чтобы найти следующий знак в строке, необходимо вызвать функцию опять, но первым аргументом поставить NULL. Каждый последовательный вызов возвращает указатель на следующий знак или на NULL, если больше знаков не найдено.

int strlen(const char *s) – возвращает число символов (исключая завершающие пробелы) в строке s.

void setmem(void *dest, unsigned length, char value) – присваивает значение value диапа-зону памяти, начиная с адреса dest;

size_t strspn(const char *s1, const char *s2) – находит начальный сегмент строки s1, кото-рая состоит из символов строки s2; возвращает длину найденного сегмента.

size_t strсspn(const char *s1, const char *s2) – находит начальный сегмент строки s1, ко-торая не состоит из символов строки s2; возвращает длину найденного сегмента.

char *strdup(const char s) – резервирует оперативную память и помещает на это место копию строки s; возвращает указатель на зарезервированную область памяти.

char *strlwr(char *s) – преобразует все символы строки к нижнему регистру (от a до z); возвращает указатель на строку s.

char *strupr(char *s) – преобразует все символы строки к верхнему регистру (от A до Z); возвращает указатель на строку s.

char *strpbrk(const char *s1, const char *s2) – сканирует строку s1 на присутствие любого символа строки s2; возвращает указатель
на найденный символ или NULL, если совпаде-ние не найдено.

char *strrev(char *s) – переписывает символы в строке в обратной последовательности; возвращает указатель на строку s.

char *strset(char *s, int ch) – все символы в строке делает равными ch; возвращает указа-тель на строку s.

size_t strxfrm(char *s1, char *s2, size_t n) – символы строки s2 заменяет на соответствующие символы строки s1, но не более чем n символов; возвращает количество замененных символов.

Преобразования одномерных массивов байтов памяти

Кроме функций для работы со строками в библиотеке string есть ряд функций для преобразования одномерных массивов байтов памяти:

int memcmp (const void *s1, const void *s2, size_t n) – сравнивает два блока памяти, начинающиеся с адресов s1 и s2, но не более, чем n байтов; возвращает 0, если блоки рав-ны, число меньшее 0, если первый блок меньше второго, число большее 0, если первый блок больше второго.

Илон Маск рекомендует:  Событие onmouseout в HTML

void *memcpy (void *dest, const void *src, size_t n) – копирует блок памяти src в блок памяти dest, но не более, чем n байтов; если блоки пересекаются, то результат не определен.

void *memccpy(void *dest, const void *src, int c, size_t n) – копирует блок памяти src в блок памяти dest; копирование останавливается по достижении количества в n байтов или после копирования символа c.

void *memmove(void *dest, const void *src, size_t n) – копирует блок памяти src в блок памяти dest, но не более, чем n байтов; копирование корректное даже если блоки памяти пересекаются.

void *memchr (const void *s, int c, size_t n) – в блоке памяти в n байтов ищет символ c, начиная с адреса s; если символ найден – возвращается указатель на найденный элемент, в противном случае NULL.

Объясните пожалуйста как работать правильно с strset

1 ответ 1

1)int main(), а не void (или «int main(int argc, char *argv[])», если вы хотите передать какие-то параметры вашей программе), и соответственно программа должна возвращать значение типа int при завершении;
2)Присваивать значение переменной chr нужно до того, как с этой переменной ведется какая-то работа, в вашем случае даже если бы strset работала, она заполняла бы строку string неизвестно чем;
3)Насколько я понимаю, strset() принимает вторым параметром аргумент типа int, а не char (link);
4)Строка вида » char *string = «1234»; » — указание компилятору создать указатель на константную! строку, если вы попытаетесь модифицировать данные, на которые он ссылается, получите segmentation fault

К сожалению, у меня в дистрибутивах в библиотеке string.h функции strset() нет, поэтому проверить ее работу я не могу, но если в вашей библиотеке под Visual она есть, то должно работать так :

Если же данной функции все же нет и в вашей библиотеке, можно заменить ее на собственную :

Всё ещё ищете ответ? Посмотрите другие вопросы с метками char c строки c++ или задайте свой вопрос.

Похожие

Подписаться на ленту

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

дизайн сайта / логотип © 2020 Stack Exchange Inc; пользовательское содержимое попадает под действие лицензии cc by-sa 4.0 с указанием ссылки на источник. rev 2020.11.11.35402

Diplom Consult.ru

Библиотека обработки строк обеспечивает много полезных функций для работы со строковыми данными, сравнения строк, поиска в строках сим­волов и других подстрок, разметки строк (разделения строк на логические куски) и определения длины строк. В этом разделе представлены некоторые типовые функции работы со строками из библиотеки обработки строк (из стандартной библиотеки С). Сведения об этих функциях сведены в таблицу 2.1.

Некоторые функции из таблицы 2.1. имеют параметры с типом данных size_t. Этот тип определяется в заголовочном файле stddef.h (из стандартной библиотеки С) как беззнаковый целый тип, такой, как unsigned int или unsigned long.

Типичная ошибка программирования. Забывают включить заголовочный файл при использовании функций из библиотеки обработки строк.

Функции работы со строками из библиотеки обработки

char *strcpy(char s1, const char *s2)

Копирует строку s2 в массив символов s1. Возвращает значение s1.

char *strncpy(char *s1, const char *s2, size_t n)

Копирует не более п сиволов из строки s2 в массив символов s1. Возвращает значение s1.

char *strcat(char s1, const char *s2)

Добавляет строку s2 к строке s1. Первый символ строки s2 записывается поверх завершающего нулевого символа строки s1. Возвращает значение s1.

strncat(char *s1, const char *s2, size_t n)

Добавляет не более n символов строки s2 в строку s1. Первый символ из s2 записывается поверх завершающего нулевого символа в s1. Возвращает значение s1.

char * strcmp (const char *s1, const char *s2)

Сравнивает строки s1 и s2. Функция возвращает значение 0, меньшее, чем или большее, чем 0, если s1 соответственно равна, меньше или больше, чем s2.

char * strcmp (const char *s1, const char *s2, size_t n)

Сравнивает до n символов строки s1 со стокой s2. функция возвращает значение 0, меньшее, чем или большее, чем 0, если s1 соответственно равна, меньше или больше, чем s2.

char *strtok(char s1, const char *s2)

Последовательность вызовов strtok разбивает строку s1 на «лексемы» — логические куски, такие, как слова в строке текста -разделенные символами, содержащимися в строке s2. Первый вызов содержит в качестве первого аргумента s1, а последующие вызовы для продолжения обработки той же строки, содержат в качестве первого аргумента NULL. При каждом вызове возвращается указатель на текущую лексему. Если при вызове функции лексем больше нет, возвращается NULL.

size_t strlen(const char *s)

Определяет длину строки s. Возвращает количество символов, предшествующих завершающему нулевому символу.

Функция strcpy копирует свой второй аргумент – строку в свой первый аргумент – массив символов, который должен быть достаточно большим, чтобы хранить строку и ее завершающий нулевой символ, который также копируется.

Функция strncpy эквивалентна strcpy за исключением того, что strncpy указывает количество символов, которое должно быть скопировано из строки в массив. Функция strncpy не обязательно должна копировать завершающий нулевой символ своего второго аргумента; завершающий нулевой символ записывается только в том случае, если количество символов, которое должно быть скопировано, по крайней мере на один больше, чем длина строки. Например, если второй аргумент – «test», завершающий нулевой символ записывается только в случае, если третий аргумент strncpy по меньшей мере равен 5 (четыре символа в «test» плюс один завершающий нулевой символ). Если третий аргумент больше пяти, завершающий нулевой символ добавляется к массиву до тех пор, пока не будет записано общее количество символов, указанное третьим аргументом.

Типичная ошибка программирования. Не добавляется завершающий нулевой символ к первому аргументу strncpy, когда третий аргумент меньше или равен длине строки во втором аргументе.

В программе (см. ниже) strcpy используется для копирования полной строки в массиве x в массив у и strncpy – для копирования первых 14 символов массива x в массив z. Нулевой символ (‘\0’) добавляется в массив z, потому что вызов strncpy в программе не записывает завершающий нулевой символ (третий аргумент меньше, чем длина строки второго аргумента).

//Использование strcpy и strncpy

char x[ ] = «Поздравляю Вас с днем рождения»;

Забытые секреты кодинга №2: строковые операции в C

«…Я обнаружил, что понимание указателей в С — это не навык, а способность. При поступлении на факультет кибернетики набирается человек 200 вундеркиндов, писавших игрушки для Atari 800 на BASIC в возрасте 4 лет. Затем они весело проводят время, изучая Паскаль, но в один прекрасный день профессор заводит речь об указателях, и внезапно они не могут этого понять… 90% потока переходит на политехнический и становится отличниками, уверяя друзей, что на информатике мало девок. На самом же деле по неизвестной причине часть человечества просто рождается без той части мозга, которая понимает указатели».

Не знаю, есть ли в коре головного мозга зона, отвечающая за понимание указателей ;-). Но сегодня я расскажу тебе о том, как работают строки в Си, и о том, как ускорить их работу. Надеюсь, что будет понятно всем.

ВОПРОСЫ ПО СТАНДАРТНЫМ ФУНКЦИЯМ

Зачем нужны специальные функции для сравнения или копирования строк? Почему в Си не пользуются обычными операторами , +, =, как в других языках?
Да, Си работает со строками совсем по-другому. Строка в Си — это указатель на символ (char). В какой-то области памяти находятся символы строки, заканчивающиеся нулевым символом ‘\0’ — на рисунке это массив символов mom. Адрес этого массива можно передавать в строковые функции, можно извлекать из массива отдельные символы (например, mom[3] — четвертый символ) — словом, это обычная строка.

В другой части памяти может находиться указатель — переменная p, которая хранит адрес определенной части строки. Все операции со строками выполняются через указатели. Например, чтобы найти первую букву ‘А’, нужно вызвать функцию strchr(), которая вернет указатель на этот символ:

p = strchr(s, ‘А’); // p будет указывать на первый символ ‘А’ в строке s

Указатели можно увеличивать и сравнивать. Например, чтобы найти следующую за ‘А’ букву, прибавим к указателю (адресу!) единицу:

p = strchr(s, ‘А’) + 1;

Если нужно узнать, какая буква расположена ближе к началу строки, ‘А’ или ‘М’, сравним указатели:

if( strchr(s, ‘А’) char str[200] = «сто»;
strcat(str, «лица»);
if(str == «столица»)
printf(«Равны!»);

Ошибка заключается в том, что str и «столица» хотя и равны, но расположены в разных участках памяти. Поэтому указатели на них не равны. В этом примере строки будут расположены в памяти примерно так:

Чтобы сравнить «содержимое» строк, нужно вызвать функцию strcmp(). Обрати внимание, что эта функция возвращает 0, когда строки равны:

char str[200] = «сто»;
strcat(str, «лица»);
if(strcmp(str, «столица») == 0)
printf(«Равны!»);

Можно ли в C работать со строками как в Паскале или Бэйсике? То есть можно ли складывать строки плюсом, автоматически выделять под них память и все такое?
Да, можно. В MFC есть класс CString, кроме него можно назвать CStr из Snippets, и еще несколько похожих разработок. Но они всегда будут работать медленнее и занимать больше места в exe’шнике, чем обычные функции Си. Обобщенные функции выделения памяти страдают избыточностью, много времени уходит на создание промежуточных строк и бесполезное копирование между ними. Сишные функции strcmp, strchr и так далее не такие уж сложные, и если ты хорошо разберешься в них, твои программы станут быстрее и короче.

Как выделять память под строки и массивы? Прежде всего, память не выделяется автоматически, как в других языках программирования. Тебе придется подсчитать, сколько символов будет занимать строка, и создать массив нужного размера. Если строка выйдет за границы отведенного для нее массива, то возникнет баг, известный как «переполнение буфера». Взломщик может использовать эту ошибку, чтобы запустить свой вредительский exploit. Поэтому нужно проверять размер строк, полученных от юзера. Например, пользователь вводит текст в контрол, а нам нужно записать этот текст большими буквами. Это делается так:

char *s; int size;
size = SendMessage(hWndCtrl, WM_GETTEXTLENGTH, 0, 0) + 1; // Узнаем размер строки
s = (char*) malloc(size); // Выделяем size байт под строку
SendMessage(hWndCtrl, WM_GETTEXT, size, (LPARAM)s); // Копируем в этот буфер строку
CharUpper(s); // Меняем регистр
SendMessage(hWndCtrl, WM_SETTEXT, 0, (LPARAM)s); // Записываем в контрол
free(s); // Освобождаем память

Выделяя память, нужно помнить о последнем нулевом символе. Он также входит в массив, так что если длина строки — 10 символов, то нужно создавать массив длиной 11 байт. Вместо сишных функций malloc, free в C++ используют операторы new, delete. Разница только в синтаксисе, а по сути это одно и то же:

char *s; int size;
s = new char[size]; // Выделяем size байт под строку
. // Выполняем нужные операции
delete[] s; // Освобождаем память

Часто максимальный размер строки известен заранее. Например, путь к файлу в Windows не может быть длиннее MAX_PATH = 260 символов. Тогда проще ограничить длину вводимой строки (послать сообщение EM_SETLIMITTEXT), а затем использовать обычный статический массив:

Функции malloc/realloc/free и операторы new/delete обращаются к Windows, запрашивая у нее память. Если вместо них ты будешь пользоваться Windows’овскими функциями HeapAlloc, HeapRealloc, HeapFree, то сможешь выбросить из exe’шника стандартную библиотеку Си, и он станет короче примерно на 20 Кб. А код для выделения памяти будет очень похожим на
malloc/free:

HANDLE heap;
heap = GetProcessHeap(); // в начале программы
s = (char*) HeapAlloc(heap, 0, size); // Выделяем size байт под строку
HeapFree(heap, 0, s); // Освобождаем память

ПРОСТЫЕ ОПЕРАЦИИ СО СТРОКАМИ

Как выделить подстроку справа, например, имя файла? Просто найди символ, с которого начинается подстрока, и пользуйся указателем на него. На рисунке указатель filename показывает на строку «C:\WORK\FV.C», а указатель p — на часть этой строки «FV.C».

Илон Маск рекомендует:  Атрибут pattern в HTML

p = strrchr(filename, ‘\\’) + 1; // Символ, следующий за последней обратной косой чертой

Как выделить подстроку слева, например, путь к файлу? Подставь нулевой байт в конец подстроки:

p = strrchr(filename, ‘\\’);
*p = ‘\0’; // Теперь в filename записан путь к файлу

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

Как подсчитать, сколько раз символ встречается в строке? Можно каждый раз искать этот символ в оставшейся части строки и, если он был найден, увеличивать счетчик и сдвигаться к концу строки:

char *p = str; int n = 0;
while(p = strchr(p, ‘А’))
p++, n++; // По окончании цикла n == число вхождений символа ‘А’ в строку str

В более удобочитаемом виде та же программа записывается следующим образом:

Почему указатели быстрее, чем индексы массивов? Программеров, которые пришли из Паскаля или Бэйсика, может немного смутить код, приведенный выше. Для них привычнее обращаться к символу строки по индексу (его номеру в квадратных скобках):

Чем лучше указатели? Да тем, что процессору не нужно при каждом проходе цикла складывать адрес начала строки s и переменную i, чтобы вычислить адрес
s[i]:

xor ecx, ecx ; ecx — это i
xor edx, edx ; edx — это n
LOOP:
cmp DWORD PTR s[ecx], ‘A’
jne SHORT BYPASS
inc edx
BYPASS:
inc ecx
cmp ecx, eax
jb SHORT LOOP

Вместо этого хорошая программа просто увеличивает адрес, то есть указатель p, а не индекс i. Код тела цикла становится немного проще и быстрее:

mov ecx, offset s ; ecx — это p
xor edx, edx ; edx — это n
LOOP:
cmp BYTE PTR [ecx], ‘A’
jne SHORT BYPASS
inc edx
BYPASS:
inc ecx
cmp ecx, eax
jb SHORT LOOP

Здесь нужно сказать, что интеллектуальный компилятор может «додуматься» преобразовать код с индексом в код с указателем, но слишком надеяться на это не стоит. Компилятор все же не так умен, как использующий его программист :).

Как найти первую гласную или согласную букву в строке? Для этого случая лучше всего подходят функции strpbrk() и
strspn().

p = strpbrk(«стройка», «аеёиоуыэюя»); //
p – указатель на первую гласную
p = s + strspn(s, «аеёиоуыэюя»); // p – указатель на первую согласную

ПРОБЛЕМЫ С РУССКИМ ЯЗЫКОМ

Как преобразовать русские буквы в верхний или нижний регистр? Лучше всего использовать функции CharUpper() и CharLower() из библиотеки Windows (заголовочный файл windows.h). Во-первых, эти функции учитывают язык, установленный в Панели управления Windows, поэтому твоя программа будет работать правильно во всех странах и со всеми языками. Во-вторых, проще пользоваться этими функциями, чем пытаться настроить стандартные функции Си для работы с русским или изобретать что-то свое. Пример:

char *m=»министр», *p=»Президент»;
CharUpper(m);
CharLower(p);
printf(«%s %s», m, p); // Выведет «МИНИСТР президент»

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

char m[]=»министр»;
m[0] = (char)CharUpper((char*)(unsigned)(unsigned char)m[0]); // Министр
CharUpperBuff(m+2, 3); // МиНИСтр

Глядя на этот кусок кода, знатоки Си могут употребить немало интересных слов великого и могучего русского языка :). Но я пока не нашел другого работающего способа преобразовать тип (char) в (char*). Если кто-то найдет — пишите. Кстати, во многом это проблема программистов Microsoft. Им нужно было написать отдельное определение (макрос или inline-функцию) для CharUpper с аргументом типа
char.

В сравнении строк есть и еще одна тонкость, на которую обычно не обращают внимания. Дело в том, что коды символов не всегда соответствуют их порядку в алфавите. Например, русская буква «Ё» и специфические белорусские буквы «Ў» («у» краткое), «ї» («и» десятеричное) расположены в кодовой таблице Windows отдельно от всех остальных букв. И если ты сравниваешь слова «дерево» и «ёлка» с помощью strcmp (сравнение по кодам), то получишь, что «ёлка» меньше (ближе к началу алфавита), чем «дерево». Чтобы избежать этой ошибки, пользуйся функцией lstrcmp() из библиотеки Windows. Для примера приведу простейшую программу пузырьковой сортировки:

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
< char *a[]=<"кедр","дуб","желудь","дерево","ёлка","сосна">;
char *p, *x; unsigned i, j; char s[200];
#define N sizeof(a)/sizeof(a[0])
for(i=0; i Пузырьковая сортировка, strcmp
for(j=i+1; j 0 )
< x = a[i];
a[i] = a[j];
a[j] = x;
>
p = s;
p += sprintf(p, » strcmp:\n»);
for(i=0; i Пузырьковая сортировка, lstrcmp
for(j=i+1; j 0 )
< x = a[i];
a[i] = a[j];
a[j] = x;
>
p += sprintf(p, «\n lstrcmp:\n»);
for(i=0; i

Эта программа выведет (видно, что сортировка с использованием strcmp неверно обрабатывает слово «ёлка»):

strcmp:
ёлка
дерево
дуб
желудь
кедр
сосна

lstrcmp:
дерево
дуб
ёлка
желудь
кедр
сосна

УБРАТЬ И УДВОИТЬ

Как убрать из строки определенные символы, например, все пробелы и знаки препинания? Есть очень простой способ. Заведем два указателя: один (p) на ту часть строки, которую мы просматриваем, другой (p2) — на ту часть, в которую мы будем копировать символы, не являющиеся пробелами или знаками препинания. Если нам встретился знак препинания, пропускаем его, увеличивая только первый указатель. Таким образом, мы «собираем» все символы к началу строки (см. рисунок ниже).

char s[256], *p = s, *p2 = s;
gets(s);
while(*p) // Пока в строке есть символы
< if( !ispunct(*p) && !isspace(*p) )
*(p2++) = *p; // Если не знак препинания, копируем
p++; // Переходим к следующему символу
>
*p2 = ‘\0’;
puts(s);

Кстати, в Visual C++ функции ispunct, isspace довольно медленные, поэтому вместо них лучше написать условие типа

‘ ) //
примерно на 10% быстрее, чем !ispunct(p) &&
!isspace(*p)

Как убрать из строки все вхождения подстроки, например, убрать все переносы строк? Точно также, как и в случае с удалением символа, будем копировать нужные нам части строки в её начало. Можно искать подстроку с помощью strstr() или применить описанный в первой части статьи «Забытые секреты кодинга» макрос
toShort:

Написать собственные аналоги функций strlen, strcmp, strchr, strcpy, strcat (дописать и исправить ошибки)

вот задание: Написать собственные аналоги функций strlen, strcmp, strchr, strcpy,
strcat из стандартной библиотеки cstring (string.h).
сделал код. но запарился с strcat. помогите

14.08.2012, 10:15

Реализовать собственные функции strcat, strcpy, strcmp, strlen
Добрый день. Помогите с задачей. Необходимо реализовать собственные функции strcat, strcpy.

Напишите свои аналоги функций strlen(), strcpy(), strcmp() и сравните с библиотечными.
Напишите свои аналоги функций strlen(),strcpy(),strcmp() и сравните с библиотечными. Наивно.

Рекурсивная реализация strcat, stracpy, strcmp и strlen
Introduce strcat (), stracpy (), strcmp () и strlen () recursively.

Написать программу: работа с си строками, функции strlen, strcpy
С помощью данного алгоритма нужно вставить слово в конец и начало строки. С помощью strlen().

Написать аналог функций strcat и strcmp
Помогите пожалуйста написать аналог функций strcat и strcmp на Си

Функции работы со строками и символами

Читайте также:

  1. DOS Fn 5eH: Разные сетевые функции
  2. Functio laesa (нарушение функции).
  3. I. 3. Функции минеральных веществ плазмы крови
  4. I. 4. Функции белков плазмы крови
  5. I. Сущность и основные функции перестрахования.
  6. II этап коррекционно-развивающей работы.
  7. II-4.6 Функции причастия в предложении и их перевод
  8. II. Основные задачи и функции
  9. II. Роль, функции, отграничение трудового права от смежных отраслей права.
  10. II. Тригонометрические функции и функции работающие с углами.
  11. III. Методическое обоснование и рекомендации по организации работы по формированию физиологичесого и речевого дыхания у дошкольников с речевой патологией.
  12. III. Режимы работы в ТТС

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

Библиотека С содержит функции копирования строк (strcpy. strncpy), сравне­ния (strcmp, strncmp), объединения строк (strcat. strncat), поиска подстроки (strstr), поиска вхождения символа (strchr, strrchr, strpbrk), определения дли­ны строки (strlen) и другие. Полный список функций приведен в приложении 6.

В заголовочных файлах и содержатся полезные функции преобразования строк в числа (обратные преобразования можно сделать с помо­щью функции sprintf): double atof(const char* p) преобразует переданную строку в double; int atoi (const char* p) преобразует переданную строку в int; long atol (const char* p) преобразует переданную строку в long.

Пробелы и табуляции в начале строки пропускаются. Преобразование прекраща­ется при встрече недопустимого символа или конца строки. Если строку нельзя преобразовать в число, возвращается 0. Если число выходит за пределы диапазо­на данного типа, переменной errno (заголовочный файл ) присваивается значение ERANGE и возвращается допустимое число.

Пример (программа заполняет массив типа double из строки):

char s[] = «2. 38.5. 70. 0. 0. 1». *p = s:

>while(p = strchr(p, ‘,’), p++);

for( int k = 0; k и ) есть следующие функции:

Имя проверка на принадлежность символа множеству
isalnum букв и цифр (A-Z, a-z, 0-9)
isalfa букв (A-Z, a-z)
iscntrl управляющих символов (с кодами 0..31 и 127)
isdigit цифр (0-9)
isgraph печатаемых символов, кроме пробела (isalfa | isdigit | ispunct)
islower букв нижнего регистра (a-z)
isprint печатаемых символов
ispunct знаков пунктуации
isspace символов-разделителей
isupper букв верхнего регистра (A-Z)
isxdigit шестнадцатиричных цифр (A-F, a-f, 0-9)

Функции принимают величину типа int и возвращают значение true, если усло­вие выполняется. Рекомендуется пользоваться стандартными функциями, а не писать собственные циклы проверки, так как это снижает количество ошибок в программе.

Кроме описанных выше, в библиотеке есть функции tolower и toupper, переводя­щие символ латинского алфавита соответственно в нижний и верхний регистр.

Символьные строки и строковые функции

Срока – это массив типа Char, завершающийся кодом нуль (\0)

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

const int len_str = 80;

char str[len_str]; // в этой строке можно использовать не 80, а 79 символов

Строку можно инициализировать. При этом «ноль» создается автоматически:

char a[100]=”это строка”; // 10+1 = 11 байтов -проинициализированная строка

char *st=”Это строка”; // это указатель на строку-константу, его изменять

В динамической памяти строка создается так:

char *p=new char(m); // m определяется заранее

С++

Ввод-вывод строк средствами С++

Можно использовать cin, cout и другие функции.

cin>>s; // вводит последовательность символов до ближайшего

//пробела (т.е. вводит одно слово)

Можно использовать метод getline или get класса IOSTREAM, объектом которого является cin:

cin.getline(s,80); /* считывает из потока 79 символов (или меньше если встретится (т.е. \n) и записывает их в строку s. Символ \n тоже считывается из потока, вместо него в строку помещается «ноль» */

scanf(“%s”,s); /* ввод до ближайшего пробела, символ & опускать! т.к. имя строки это указатель на её начало*/

2) Ввести предложение:

scanf(“%10c”,s); // ввод строки с пробелами 10 это кол-во вводимых символов

printf(“%15s”,s); // выводит строку в 15 позиций, выравнивание по правому краю

3) Специальные средства ввода – вывода строк – gets и puts

gets(s); // это лучший способ ввода строки в С

puts(s); // это лучший способ вывода строки в С

gets(s) – возвращает указатель на строку s. При ошибке возвращает NULL

puts(s) – в случае нормального нормального выполнения возвращает отрицательное число, в случае ошибки – EOF

Итог: printf удобно использовать при выводе данных различных типов. Если выводить только строки, то puts.

(Для ввода-вывода одного символа используют спец. функции:

Различия между массивом символов и указателем на строку

Char s1[]=”Я люблю кошек!”; // длина массива определяется автоматически

Char *s2=”Я люблю собак!”;

Дата добавления: 2014-01-11 ; Просмотров: 604 ; Нарушение авторских прав? ;

Илон Маск рекомендует:  Что такое код dlgdirlistcombobox

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

Строки и структуры в C++. Уроки программирования

Строки в C++

Строка — последовательность (массив) символов. Если в выражении встречается одиночный символ, он должен быть заключен в одинарные кавычки. При использовании в выражениях строка заключается в двойные кавычки. Признаком конца строки является нулевой символ \0. В C++ строки можно описать с помощью массива символов (массив элементов типа char), в котором следует предусмотреть место для хранения признака конца строки.

Например, описание строки из 25 символов должно выглядеть так:

Здесь элемент s[24] предназначен для хранения символа конца строки.

Можно описать и массив строк:

Определен массив из 3 строк по 25 байт в каждой.

Для работы с указателями можно использовать (char *). Адрес первого символа будет начальным значением указателя.

Рассмотрим пример объявления и вывода строк.

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

Но следует отметить, что если пользователь введет в одну переменную слова разделенные пробелом, то программа будет работать иначе:

Все дело в том, что функция cin вводит строки до встретившегося пробела. Более универсальной функцией является getline.

cin.getline(char *s, int n);

Функция предназначена для ввода с клавиатуры строки s с пробелами, в строке не должно быть более n символов. Следовательно, для корректного ввода строк, содержащих пробел, необходимо в нашей программе заменить cin>>s на cin.getline(s, 80).

Операции над строками

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

Для преобразования числа в строку можно воспользоваться функцией sprintf из библиотеки stdio.h.

Некоторые функции работы со строками:

Прототип функции Описание функции
size_t strlen(const char *s) вычисляет длину строки s в байтах.
char *strcat(char *dest, const char *scr) присоединяет строку src в конец строки dest, полученная срока возвращается в качестве результата
char *strcpy(char *dest, const char *scr) копирует строку scr в место памяти, на которое указывает dest
char strncat(char *dest, const char *dest, size_t maxlen) присоединяет строку maxlen символов строки src в конец строки dest
char *strncpy(char *dest, const char *scr, size_t maxlen) копирует maxlen символов строки src в место памяти, на которое указывает dest
int ctrcmp(const char *s1, const char *s2) сравнивает две строки в лексикографическом порядке с учетом различия прописных и строчных букв, функция возвращает 0, если строки совпадают, возвращает — 1, если s1 располагается в упорядоченном по алфавиту порядке раньше, чем s2, и 1 — в противоположном случае.
int strncmp(const char *s1, const char *s2, size_t maxlen) сравнивает maxlen символов двух строк в лексикографическом порядке, функция возвращает 0, если строки совпадают, возвращает — 1, если s1 располагается в упорядоченном по алфавиту порядке раньше, чем s2, и 1 — в противоположном случае.
double atof(const char *s) преобразует строку в вещественное число, в случае неудачного преобразования возвращается число 0
long atol(const char *s) преобразует строку в длинное целое число, в случае неудачного преобразования возвращается 0
char *strchr(const char *s, int c); возвращает указатель на первое вхождение символа c в строку, на которую указывает s. Если символ c не найден, возвращается NULL
char *strupr(char *s) преобразует символы строки, на которую указывает s, в символы верхнего регистра, после чего возвращает ее

Тип данных string

Кроме работы со строками, как с массивом символов, в C++ существует специальный тип данных string. Для ввода переменных этого типа можно использовать cin, или специальную функцию getline.

getline(cin, s);

Здесь s — имя вводимой переменной типа string.

При описании переменной этого типа можно сразу присвоить значение этой переменной.

string var(s);

Здесь var — имя переменной, s — строковая константа. В результате этого оператора создается переменная var типа string, и в нее записывается значение строковой константы s. Например,

string v(«Hello»);

Создается строка v, в которую записывается значение Hello.

Доступ к i-му элементу строки s типа string осуществляется стандартным образом s[i]. Над строками типа string определенны следующие операции:

  • присваивания, например s1=s2;
  • объединения строк (s1+=s2 или s1=s1+s2) — добавляет к строке s1 строку s2, результат храниться в строке s1, пример объединения строк:
  • сравнения строк на основе лексикографического порядка: s1=s2, s1!=s2, s1 s2, s1 =s2 — результатом будет логическое значение;

При обработке строк типа string можно использовать следующие функции:

  • s.substr(pos, length) — возвращает подстроку из строки s, начиная с номера pos длинной length символов;
  • s.empty() — возвращает значение true, если строка s пуста, false — в противном случае;
  • s.insert(pos, s1) — вставляет строку s1 в строку s, начиная с позиции pos;
  • s.remove(pos, length) — удаляет из строки s подстроку length длинной pos символов;
  • s.find(s1, pos) — возвращает номер первого вхождения строки s1 в строку s, поиск начинается с номера pos, параметр pos может отсутствовать , в этом случае поиск идет с начала строки;
  • s.findfirst(s1, pos) — возвращает номер первого вхождения любого символа из строки s1 в строку s, поиск начинается с номера pos, который может отсутствовать.

Русский язык для строк

Думаю вы уже заметили, что при выводе русских букв, в консоли появляются «левые» символы. Для того чтобы избежать этого недоразумения, необходимо воспользоваться сторонней функцией CharToOemA. Подключаем библиотеку windows.h, она нужна для того, чтобы наша функция могла преобразовать строки в другую кодировку. Также, нам понадобиться дополнительный символьный массив. Исходный код программы будет выглядеть вот так:

Способ только что описанный достаточно не удобен. Но существует более простой вариант решения «русской» проблемы. Как видите, в программе используется функция setlocale(), вместо этого удобнее вписать в главную функцию следующую конструкцию:

Теперь у нас появляется библиотека windows.h, а также две новые функции: SetConsoleCP() и SetConsoleOutputCP().

Структуры в C++

Кроме числовых и символьных данных в C++ есть тип, который позволяет объединить разнородные данные и обрабатывать их как единое целое. Этот тип называется структурой. Структура является собранием одного или более объектов (переменных, массивов, указателей и т.д.), которые для удобства работы с ними объединены под одним именем.

Определение структуры состоит из двух шагов:

  • объявление структуры (задание нового типа данных, определенного пользователем); структура состоит из полей, например:
  • определение переменных типа «структура»:

Для обращения к полям структуры нужно указать имя переменной и через точку имя поля

Structura.pole

При работе с динамическими массивами структур к их полям можно обращаться и по-другому. Обращение к полю year i-го элемента динамического массива структуры x можно записать так:

Функции для обработки строк

Особенности функций для работы со строками

Языки программирования могут включать специальные функции для работы со строками, избавляя тем самым программиста от необходимости писать собственные функции обработки строк. Например, часто требуется определить длину строки, и поэтому в языках предусмотрена функция, измеряющая ее длину.

В языке программирования C функции для работы со строками объявляются в заголовочном файле string.h, который надо не забывать подключать к своему исходному коду. Существует около двадцати функций для работы со строками. Среди них есть те, которые осуществляют поиск символов в строке, функции сравнения, копирования строк, а также более специфические. Перечень и описание большинства существующих на данный момент в языке C функций можно найти в приложении книги Б. Кернигана, Д. Ритчи «Язык программирования C. Второе издание».

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

Например, функция strcpy() имеет такое объявление: char *strcpy (char *, const char*) . Она копирует строку, на которую указывает второй параметр, в строку, на которую указывает первый параметр. Таким образом первый параметр изменяется. Кроме того, функция возвращает указатель на первый символ строки:

Здесь s2 и s3 указывают на один и тот же символ ( printf() выводит одинаковые адреса). Однако то, что возвращает strcpy() , нельзя присвоить массиву. Результат работы этой функции обычно ничему не присваивают; бывает достаточно того, что она просто изменяет одну из переданных по указателю строк.

Другое дело, такие функции как strlen() или strcmp() , которые не изменяют параметры, а вызываются ради результата. Функция strcmp() сравнивает две строки-аргумента по буквам (лексикографически) и возвращает 0, -1 или 1. Например, вызов strcmp(«boy», «body») вернет 1, т.к. код буквы ‘y’ больше буквы ‘d’. Вызов strcmp(«body», «boy») вернет -1, т.к. первый аргумент лексикографически меньше второго.

Функция strtok()

С помощью функции strtok() можно разбить строку на отдельные части (лексемы). Объявление этой функции выглядит так char *strtok (char *, const char *) . При первом вызове функции в качестве первого параметра указывается строка, которую требуется разбить. Вторым параметром указывается строка-разделитель. При последующих вызовах функции для этой же строки первым параметром должен быть NULL, т.к. функция уже «запомнила» с чем работает. Рассмотрим пример:

В результате выполнения данного кода на экран в столбик выводятся слова:

При первом вызове strtok() в функцию передается указатель на первый символ массива и строка-разделитель. После этого вызова массив str изменяется, в нем остается только слово «one», также функция возвращает указатель на это слово, который присваивается sp.

Хотя мы потеряли остаток массива в вызывающей функции, однако внутри strtok() сохраняется указатель на остаток массива. Когда передается NULL, функция «знает», что надо работать с этим «хвостом».

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

Когда требуется просто соединить две строки, то проблема легко решается с помощью вызова функции strcat() , которая к концу первого аргумента присоединяет второй. Похожая функция strncat() присоединяет n символов второй строки к первой. n указывается в качестве третьего параметра.

Что если ситуация более сложная? Например, есть две непустые строки и надо соединить начало первой и конец второй. Сделать это можно с помощью функции strcpy() , если передавать ссылки не на первые символы строк:

В данном случае на экране будет выведено «Peter Roberts». Почему так произошло? В функцию strcpy() был передан указатель на шестой символ первой строки. Это привело к тому, что при копировании символы этой строки затираются только начиная с 6-го, т.к. strcpy() о предыдущих символах ничего не «знает». В качестве второго аргумента также передается только часть строки, которая и копируется в первую.

Как вставить одну строку в середину другой? Можно решить эту задачу, используя третью «буферную» строку, куда можно сначала скопировать первую строку, потом вторую, затерев конец первой, потом присоединить конец первой. Но можно поступить и так:

Здесь сначала во вторую строку копируется конец первой, получается «two three». Затем в первую строку, минуя ее начало, копируется вторая.

Описание некоторых функций для работы со строками

Задание
Ниже представлены описания некоторых функций, выполняющих операции над строками. Придумайте и напишите маленькие программы, иллюстрирующие работу этих функций.

  • char *strchr (const char *, int c) . Возвращает указатель на первое вхождение символа с в строку. Возвращает NULL, если такого символа в строке нет.
  • char *strstr (const char *s2, const char *s1) . Возвращает указатель на первое вхождение строки s1 в строку s2. Если совпадений нет, возвращает NULL.
  • char *strncpy (char *, const char *, size_t n) . Копирует n символов второй строки в первую.
  • size_t strspn (const char *, const char *) . Возвращает длину начала первой строки, в которую входят символы, из которых состоит вторая строка.
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL