Язык c строки и символы

Строки в языке C

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

Исторически сложилось два представления формата строк:

Формат ANSI устанавливает, что значением первой позиции в строке является ее длина, а затем следуют сами символы строки. Например, представление строки «Моя строка!» будет следующим:

11 ‘М’ ‘о’ ‘я’ ‘ ‘ ‘с’ ‘т’ ‘р’ ‘о’ ‘к’ ‘а’ ‘!’
В строках с завершающим нулем, значащие символы строки указываются с первой позиции, а признаком завершения строки является значение ноль. Представление рассмотренной ранее строки в этом формате имеет вид:

‘М’ ‘о’ ‘я’ ‘ ‘ ‘с’ ‘т’ ‘р’ ‘о’ ‘к’ ‘а’ ‘!’ 0

Объявление строк в C

Строки реализуются посредством массивов символов. Поэтому объявление ASCII строки имеет следующий синтаксис:

char имя[длина];
Объявление строки в С имеет тот же синтаксис, что и объявление одномерного символьного массива. Длина строки должна представлять собой целочисленное значение (в стандарте C89 – константа, в стандарте C99 может быть выражением). Длина строки указывается с учетом одного символа на хранение завершающего нуля, поэтому максимальное количество значащих символов в строке на единицу меньше ее длины. Например, строка может содержать максимально двадцать символов, если объявлена следующим образом:
char str[21]; Инициализация строки в С осуществляется при ее объявлении, используя следующий синтаксис:
char str[длина] = строковый литерал;

Строковый литерал – строка ASCII символов заключенных в двойные кавычки. Примеры объявления строк с инициализацией:

char str1[20] = «Введите значение: «, str2[20] = «»;

const char message[] = «Сообщение об ошибке!»;

Работа со строками в С

Так как строки на языке С являются массивами символов, то к любому символу строки можно обратиться по его индексу. Для этого используется синтаксис обращения к элементу массива, поэтому первый символ в строке имеет индекс ноль. Например, в следующем фрагменте программы в строке str осуществляется замена всех символов ‘a’ на символы ‘A’ и наоборот.

Массивы строк в С

Объявление массивов строк в языке С также возможно. Для этого используются двумерные массивы символов, что имеет следующий синтаксис:
char имя[количество][длина];

Первым размером матрицы указывается количество строк в массиве, а вторым – максимальная (с учетом завершающего нуля) длина каждой строки. Например, объявление массива из пяти строк максимальной длиной 30 значащих символов будет иметь вид:

Число строковых литералов должно быть меньше или равно количеству строк в массиве. Если число строковых литералов меньше размера массива, то все остальные элементы инициализируются пустыми строками. Длина каждого строкового литерала должна быть строго меньше значения длины строки (для записи завершающего нуля).

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

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

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

Ввод и вывод строк в С

Для ввода и вывода строковой информации можно использовать функции форматированного ввода и вывода (printf и scanf). Для этого в строке формата при вводе или выводе строковой переменной необходимо указать спецификатор типа %s. Например, ввод и последующий вывод строковой переменной будет иметь вид:

char str[31] = «»;
printf(«Введите строку: «);
scanf(«%30s”,str);
printf(«Вы ввели: %s”,str);

Недостатком функции scanf при вводе строковых данных является то, что символами разделителями данной функции являются:

Поэтому, используя данную функцию невозможно ввести строку, содержащую несколько слов, разделенных пробелами или табуляциями. Например, если в предыдущей программе пользователь введет строку: «Сообщение из нескольких слов», то на экране будет выведено только «Сообщение».
Для ввода и вывода строк в библиотеке stdio.h содержатся специализированные функции gets и puts.

Функция gets предназначена для ввода строк и имеет следующий заголовок:
char * gets(char *buffer);

Между тем использовать функцию gets категорически не рекомендуется, ввиду того, что она не контролирует выход за границу строки, что может произвести к ошибкам. Вместо нее используется функция fgets с тремя параметрами:

char * fgets(char * buffer, int size, FILE * stream);

Функция puts предназначена для вывода строк и имеет следующий заголовок:
int puts(const char *string);

Простейшая программа: ввод и вывод строки с использованием функций fgets и puts будет иметь вид:

Помимо функций ввода и вывода в потоки в библиотеке stdio.h присутствуют функции форматированного ввода и вывода в строки. Функция форматированного ввода из строки имеет следующий заголовок:

Функции форматированного вывода в строку имеют следующие заголовки:

Преобразование строк

В С для преобразования строк, содержащих числа, в численные значения в библиотеке stdlib.h
предусмотрен следующий набор функций:
double atof(const char *string); // преобразование строки в число типа double
int atoi(const char *string); // преобразование строки в число типа int
long int atol(const char *string); // преобразование строки в число типа long int
long long int atoll(const char *string); // преобразование строки в число типа long long int

Корректное представление вещественного числа в текстовой строке должно удовлетворять формату:

После символов E, e указывается порядок числа. Корректное представление целого числа в текстовой строке должно удовлетворять формату:

Помимо приведенных выше функций в библиотеке stdlib.h доступны также следующие функции преобразования строк в вещественные числа:

Аналогичные функции присутствуют и для преобразования строк в целочисленные значения:

Функции обратного преобразования (численные значения в строки) в библиотеке stdlib.h присутствуют, но они не регламентированы стандартом, и рассматриваться не будут. Для преобразования численных значений в строковые наиболее удобно использовать функции sprintf и snprintf.

Обработка строк

В библиотеке string.h содержаться функции для различных действий над строками.
Функция вычисления длины строки:
size_t strlen(const char *string);

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

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

Функции осуществляют сравнение строк по алфавиту и возвращают:

положительное значение – если string1 больше string2;
отрицательное значение – если string1 меньше string2;
нулевое значение – если string1 совпадает с string2;

Функции объединения (конкатенации) строк:

Функции поиска символа в строке:

Функция поиска строки в строке:
char * strstr(const char *str, const char *substr);

Функция поиска первого символа в строке из заданного набора символов:
size_t strcspn(const char *str, const char *charset);

Функции поиска первого символа в строке не принадлежащему заданному набору символов:
size_t strspn(const char *str, const char *charset);

Функции поиска первого символа в строке из заданного набора символов:
char * strpbrk(const char *str, const char *charset);

Функция поиска следующего литерала в строке:
char * strtok(char * restrict string, const char * restrict charset);

Источник

Строки в си. Введение

Строки в си. Введение.

Э то вводная статья по строкам в си. Более подробное описание и примеры будут, когда мы научимся работать с памятью и указателями. В компьютере все значения хранятся в виде чисел. И строки тоже, там нет никаких символов и букв. Срока представляет собой массив чисел. Каждое число соответствует определённому символу, который берётся из таблицы кодировки. При выводе на экран символ отображается определённым образом.
Для хранения строк используются массивы типа char. Ещё раз повторюсь – тип char – числовой, он хранит один байт данных. Но в соответствии с таблицей кодировки каждое из этих чисел связано с символом. И в обратную сторону – каждый символ определяется своим порядковым номером в таблице кодировки. Например

Мы создали две переменные, одна типа char, другая int. Литера ‘A’ имеет числовое значение 65. Это именно литера, а не строка, поэтому окружена одинарными кавычками. Мы можем вывести её на печать как букву

Тогда будет выведено
A Если вывести её как число, то будет 65 Точно также можно поступить и с числом 65, которое хранится в переменной типа int.
Спецсимволы также имеют свой номер

Здесь будет сначала «выведен» звуковой сигнал, затем его числовое значение, затем опять звуковой сигнал. Строка в си – это массив типа char, последний элемент которого хранит терминальный символ ‘\0’. Числовое значение этого символа 0, поэтому можно говорить, что массив оканчивается нулём.
Например

Для вывода использовался ключ %s. При этом строка выводится до первого терминального символа, потому что функция printf не знает размер массива word.
Если в этом примере не поставить

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

В данном случае всё корректно. Строка «ABC» заканчивается нулём, и ею мы инициализируем массив word. Строка text инициализируется побуквенно, все оставшиеся символы, как следует из главы про массивы, заполняются нулями.

Чтение строк

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

В данном случае количество введённых символов ограничено 19, а размер буфера на 1 больше, так как необходимо хранить терминальный символ. Напишем простую программу, которая запрашивает у пользователя строку и возвращает её длину.

Так как числовое значение символа ‘\0’ равно нулю, то можно записать

Теперь напишем программу, которая запрашивает у пользователя два слова и сравнивает их

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

Источник

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

Библиотека string.h предоставляет функции для работы со строками (zero-terminated strings) в си, а также несколько функций для работы с массивами, которые сильно упрощают жизнь. Рассмотрим функции с примерами.

Копирование

Копирует участок памяти из source в destination, размером num байт. Функция очень полезная, с помощью неё, например, можно скопировать объект или перенести участок массива, вместо поэлементного копирования. Функция производит бинарное копирование, тип данных не важен. Например, удалим элемент из массива и сдвинем остаток массива влево.

Функция меняет местами две переменные

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

Копирует блок памяти из source в destination размером num байт с той разницей, что области могут пересекаться. Во время копирования используется промежуточный буфер, который предотвращает перекрытие областей.

Копирует одну строку в другую, вместе с нулевым символом. Также возвращает указатель на destination.

Можно копировать и по-другому

Копирует только num первых букв строки. 0 в конец не добавляется автоматически. При копировании из строки в эту же строку части не должны пересекаться (при пересечении используйте memmove)

Конкатенация строк

Добавляет в конец destination строку source, при этом затирая первым символом нулевой. Возвращает указатель на destination.

Добавляет в конец строки destination num символов второй строки. В конец добавляется нулевой символ.

Сравнение строк

Возвращает 0, если строки равны, больше нуля, если первая строка больше, меньше нуля, если первая строка меньше. Сравнение строк происходит посимвольно, сравниваются численные значения. Для сравнения строк на определённом языке используется strcoll

Трансформация строки в соответствии с локалью. В строку destination копируется num трансформированных символов строки source и возвращается её длина. Если num == 0 и destination == NULL, то возвращается просто длина строки.

Поиск

Проводит поиск среди первых num байтов участка памяти, на который ссылается ptr, первого вхождения значения value, которое трактуется как unsigned char. Возвращает указатель на найденный элемент, либо NULL.

Возвращает указатель на место первого вхождения character в строку str. Очень похожа на функцию memchr, но работает со строками, а не с произвольным блоком памяти.

Здесь обратите внимание на строку i++ после printf. Если бы её не было, то strcspn возвращал бы всегда 0, потому что в начале строки стояла бы гласная, и произошло зацикливание.
Для решения этой задачи гораздо лучше подошла функция, которая возвращает указатель на первую гласную.

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

Возвращает указатель на последнее вхождение символа в троку.

Возвращает указатель на первое вхождение строки str2 в строку str1.

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

Ещё функции

Самая популярная функция

Конверсия число-строка и строка-число.

Переводит строку в целое

Переводит строку в число типа double.

Форматированный ввод и вывод в буфер

Можно также выделить две функции sprintf и sscanf. Они отличаются от printf и scanf тем, что выводят данные и считывают их из буфера. Это, например, позволяет переводить строку в число и число в строку. Например

Работа с локалью

Устанавливает локаль для данного приложения. Если locale равно NULL, то setlocale может быть использована для получения текущей локали.

Локаль хранит информацию о языке и регионе, специфичную для работы функций ввода, вывода и трансформации строк. Во время работы приложения устанавливается локаль под названием «C», которая совпадает с настройками локали по умолчанию. Эта локаль содержит минимум информации, и работа программы максимально предсказуема. Локаль «C» также называется «». Константы category определяют, на что воздействует изменение локали.

Значения параметра category

ИмяНа что влияет
LC_ALLНа всю локаль
LC_COLLATEНа поведение strcoll и strxfrm.
LC_CTYPEНа поведение функций, работающих с символами.
LC_NUMERICНа десятичный разделитель в числах.
LC_TIMEНа поведение strftime.

Строка locale содержит имя локали, например «En_US» или «cp1251»

Источник

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Язык c строки и символы. Смотреть фото Язык c строки и символы. Смотреть картинку Язык c строки и символы. Картинка про Язык c строки и символы. Фото Язык c строки и символы

Свободный массив

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

Большинство операций языка Си, имеющих дело со строками, работает с указателями. Для размещения в оперативной памяти строки символов необходимо:

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

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

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

В качестве аргумента функции передается указатель на строку, в которую осуществляется ввод. Функция просит пользователя ввести строку, которую она помещает в массив, пока пользователь не нажмет Enter.

Функции вывода строк

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

или в сокращенном формате

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

которая печатает строку s и переводит курсор на новую строку (в отличие от printf() ). Функция puts() также может использоваться для вывода строковых констант, заключенных в кавычки.

Функция ввода символов

Для ввода символов может использоваться функция

которая возвращает значение символа, введенного с клавиатуры. Указанная функция использовалась в рассмотренных ранее примерах для задержки окна консоли после выполнения программы до нажатия клавиши.

Функция вывода символов

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

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

Пример Посчитать количество введенных символов во введенной строке.

Результат выполнения
Язык c строки и символы. Смотреть фото Язык c строки и символы. Смотреть картинку Язык c строки и символы. Картинка про Язык c строки и символы. Фото Язык c строки и символы

Основные функции стандартной библиотеки string.h

Основные функции стандартной библиотеки string.h приведены в таблице.

присоединяет не более n символов s2 к s1, завершает строку символом ‘\0’, возвращает s1сравнивает не более n символов строк s1 и s2, возвращает значение 0, если начальные n символов строк эквивалентнызаполняет строку s символами, код которых равен значению c, возвращает указатель на строку sзаменяет первые n символов строки s символами, код которых равен c, возвращает указатель на строку s

Пример использования функций

Результат выполнения
Язык c строки и символы. Смотреть фото Язык c строки и символы. Смотреть картинку Язык c строки и символы. Картинка про Язык c строки и символы. Фото Язык c строки и символы

Комментариев к записи: 111

#include
#include «string.h»
#include «stdio.h»
using namespace std;

int main()
<
char from, to;
char text[100],*wbeg, * wend, delim[] = » ;. » ;
cout «Input text and put ‘.’ at the end: » ; cin.getline(text, 100, ‘.’);
do < cout "Line is empty! Retry: " ; cin.getline(text, 100, '.');>while (strlen(text) == 0);
int n_delim = strspn(text, delim); // возвращает к-сть разделителей
wbeg = text + n_delim; // указатель на начало слова
wend = text + strlen(text); // указатель на конец слова
n_delim = strcspn(wbeg, delim); //длина первого слова

int count = 1; cout «Input number of thе word: » ; int number; cin >> number;
while ((wbeg + n_delim if (count == number)
<
do
<
cout «Input symbol, that should be changed: » ; char ch1; cin >> ch1; //запрос буквы
char *pos_s = strchr(wbeg, ch1);
if (pos_s == 0) cout «No symbol!» ;
else if (wbeg + n_delim «Input symbol to change one: » ; char ch2; cin >> ch2;
ch2 = &pos_s;

> while (count else cout «No words with given number!» ; return 0;
>
return 0;
>

Источник

Язык c строки и символы

Любой язык программирования содержит средства представления и обработки текстовой информации. Другое дело, что обычно программист наряду с символами имеет дело с типом данных (формой представления) – строкой, причем особенности ее организации скрыты, а для работы предоставлен стандартный набор функций. В Си, наоборот, форма представления строки является открытой, а программист работает с ней «на низком уровне».

Представление символов и строк в Си

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

· работа с текстовыми файлами «вписана» в стандартный ввод-вывод. Например, в Си потоки ввода-вывода могут быть перенаправлены как на текстовый файл, так и на консольный ввод-вывод (клавиатура – экран);

· если приложения не работают с форматами данных друг друга (не совместимы по данным), то единственным форматом обмена является текстовый файл, в котором числовые (или символьные ) данные разделены стандартными разделителями (пробел, табуляция, запятая, точка с запятой, конец строки). Обмен данными через такие файлы называется экспортом-импортом. В Си файлы такого формата читаются стандартными функциями форматного ввода;

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

Константа Название Действие

\ a bel Звуковой сигнал

\b bs Курсор на одну позицию назад

\f ff Переход к началу (перевод формата)

\n lf Переход на одну строку вниз(перевод строки)

\r cr Возврат на первую позицию строки

\ t ht Переход к позиции, кратной 8 (табуляция)

\v vt Вертикальная табуляция по строкам

\nn Символ с восьмеричным кодом nn

\xnn Символ с шестнадцатеричным кодом nn

\0 Символ с кодом 0

Некоторые программы и стандартные функции обработки символов и строк (isdigit,isalpha) используют тот факт, что цифры, прописные и строчные (маленькие и большие) латинские буквы имеют упорядоченные по возрастанию значения кодов:

· строка хранится в массиве символов, массив символов может быть инициализирован строкой, а может быть заполнен программно:

· соответствие размерности массива и длины строки транслятором не контролируется, за это несет ответственность программа (программист, ее написавший):

char C[20], B []=”Строка слишком длинная для C ”;

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

// и ограничить строку его размерностью

char A[80] = «123456\r\n»;

char B[] = «aaaaa\033bbbb»;

Функции стандартной библиотеки ввода-вывода обязаны «сглаживать противоречия», связанные с исторически сложившимися формами и анахронизмами в представлении строки в различных устройствах ввода-вывода и операционных системах (текстовый файл, клавиатура, экран) и приводить их к единому внутреннему формату.

Стандартные приемы обработки строк

· редактировать строку «на месте», реализуя вставку и удаление символов или фрагментов;

· организовать посимвольное переписывание входной строки в выходную, с копированием нужных и преобразованных фрагментов (что проще).

Получить символ десятичной цифры из значения целой переменной, лежащей в диапазоне 0..9:

int n; char c; c = n + ‘0’;

Получить символ шестнадцатеричной цифры из значения целой переменной, лежащей в диапазоне 0..15:

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

Получить значение целой переменной из шестнадцатеричной цифры:

Преобразовать маленькую латинскую букву в большую:

//— Подсчет количества слов

//— Удаление лишних пробелов при посимвольном переписывании

void nospace(char c1[],char c2[]) <

c 2[ j ++]=’ ‘; // добавить пробел

c 2[ j ++]= c 1[ i ]; // Перенести символ слова

//—- Сравнение строк по значениям кодов

int my_strcmp(unsigned char s1[],unsigned char s2[]) <

if (s1[n] == s2[n]) return 0;

//—- Сравнение строк с заданными «весами» символов

static char ORD[] = » АаБбВвГгДдЕе 1234567890″;

for ( int n=0; ORD[n]!=’\0′; n++)

int my_strcmp(char s1[],char s2[])<

if (c1 == c2) return 0;

Пример: a < b < c >b > a < d < e < g >e > d > a => < c >< b 1 b >< g >< e 3 e > < d 4 d >a 2 a 5 a

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

int i; // Индекс в строке

int k ; // Счетчик вложенности

int max ; // Максимум вложенности

int b; // Индекс максимальной » <"

for (i=0, max=0, b=-1; c[i]!=0; i++)<

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

int i; // Индекс в строке

int b; // Индекс максимальной » <"

Идея основного алгоритма заключается в последовательной нумерации «выкусываемых» из входной строки фрагментов, при этом на место каждого помещается его номер – значение счетчика, которое для этого переводится во внешнюю форму представления.

//—— Копирование вложенных фрагментов с » выкусыванием»

void copy(char c1[], char c2[])<

int i =0; // Индекс в выходной строке

int k ; // Индекс найденного фрагмента

int n ; // Запоминание начала фрагмента

int m ; // Счетчик фрагментов

for ( n = k ; c 1[ k ]!= ‘>’ ; k ++, i ++) c 2[ i ]= c 1[ k ]; // Переписать фрагмент и его «>»

if ( m /10!=0) c 1[ n ++] = m /10 + ‘0’ ; // На его место две цифры

c 1[ n ++] = m %10 + ‘0’ ; // номера во внешней форме

c 1[ n ]=0; > // сдвинуть » хвост» к началу

for ( k =0; c 1[ k ]!=0; k ++, i ++) c 2[ i ]= c 1[ k ]; // перенести остаток

c 2[ i ]=0;> // входной строки

Практический совет – желательно избегать сложные вычисления над индексами. Лучше всего для каждого фрагмента строки заводить свой индекс и перемещать их независимо друг от друга в нужные моменты. Что, например, сделано при «уплотнении» строки – индекс k после переписывания найденного фрагмента «останавливается» на начале «хвоста» строки, который переносится под индекс n – начало удаляемого фрагмента. Причем записываемые цифры номера смещают это начало на один или два символа. Таким образом, фрагмент заменяется во входной строке на его номер.

Язык c строки и символы. Смотреть фото Язык c строки и символы. Смотреть картинку Язык c строки и символы. Картинка про Язык c строки и символы. Фото Язык c строки и символы

Внешняя и внутренняя форма представления чисел

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

Функции и объекты стандартных потоков ввода/вывода могут, в частности, вводить и выводить целые числа, представленные в десятичной, восьмеричной и шестнадцатеричной системах счисления. При этом происходят преобразования, связанные с переходом от внешней формы представления к внутренней и наоборот.

Язык c строки и символы. Смотреть фото Язык c строки и символы. Смотреть картинку Язык c строки и символы. Картинка про Язык c строки и символы. Фото Язык c строки и символы

Обратите внимание, что о системе счисления имеет смысл говорить только тогда, когда число рассматривается в виде последовательности цифр, то есть во внешней форме представления числа. Внутренняя форма представления числа – двоичная и нас, грубо говоря, не интересует, поскольку компьютер корректно оперирует с ней и без нашего участия.

На самом деле алгоритмы ввода-вывода числовых данных (вернее, преобразования данных из внешней формы во внутреннюю, и наоборот) идентичны алгоритмам преобразования чисел из произвольной системы счисления в десятичную (см. 1.3). При этом десятичная система играет роль внутренней («родной») формы представления.

Ввод целого числа сопровождается его преобразованием из внешней формы – последовательности цифр – в внутренней – целой переменной, которая «интегрирует» цифры в одно значение с учетом их веса (что зависит, кроме всего прочего, и от системы счисления, в которой представлено вводимое число). В преобразовании используется тот факт, что при добавлении к числу очередной цифры справа старое значение увеличивается в 10 раз и к нему добавляется значение новой цифры, например:

Значение: 123 1234 = 123 * 10 + 4

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

//—— Ввод десятичного целого числа

int StringToInt(char c[])<

if (c[i]==’\0′) return 0; // Поиск первой цифры

for (n=0; c[i]>=’0′ && c[i] // Накопление целого

//—- Вывод целого десятичного числа

void IntToString(char c[], int n)

for (nn=n, k=0; nn!=0; k++, nn/=10); // Подсчет количества цифр числа

c[k] = ‘\0’; // Конец строки

for (k—; k >=0; k—, n /= 10) // Получение цифр числа

c[k] = n % 10 + ‘0’; // в обратном порядке

При преобразовании дробной части во внешнюю форму используется тот факт, что при умножении дробной части на 10 (точнее, на основание системы счисления) очередная цифра «вылезает» в целую часть. Из нее формируется символ, после чего целая часть отбрасывается.

//—- Вывод вещественного десятичного числа

void FloatToString(char c[], double v)

for (nn=v, k=0; nn!=0; k++, nn/=10); // Подсчет количества цифр

kk=k-1; c[k++] = ‘.’; // целой части числа

for (nn=v; kk >=0; kk—, nn /= 10) // Получение цифр числа

c[kk] = nn % 10 + ‘0’; // в обратном порядке

v-=(int)v; // Убрать целую часть

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

//—— Ввод десятичного вещественного числа

double StringToFloat(char c[])<

if (c[i]==’\0′) return 0; // Поиск первой цифры

for (n=0; c[i]>=’0′ && c[i] // Накопление целого

v=v/10; // весом разряда дробной части

Преобразование, в котором внешняя форма числа задана в другой системе счисления, выполняются аналогично, только вместо числа 10 используется основание системы, а для систем счисления, больших 10, используется особое преобразование символов-цифр во внутреннее представление:

Посимвольная и пословная обработка.

Одну и ту же программу обработки строки текста можно написать разными способами. Если речь идет о формате текстовой строки, то отслеживать его можно двумя способами (см. 3.8):

// Функция возвращает индекс начала слова или 1, если нет слов

// Логика переменной состояния – n – счетчик символов слова

if (s[i]!=’ ‘) n++; // символ слова увеличить счетчик

n=0; // фиксация максимального значения

>> // то же самое для последнего слова

// Структурная логика – 3 цикла: просмотр слов, пробелов и символов

while (in[i]==’ ‘) i++; // Пропуск пробелов перед словом

for (k=0;in[i]!=’ ‘ && in[i]!=0; i++,k++); // Подсчет длины слова

m=k; b=i-k; > // Одновременно запоминается

По завершении посимвольного просмотра строки последнее слово (если после него нет пробела) оказывается необработанным. Поэтому контекст фиксации максимума повторяется после выхода из цикла.

Здесь можно проиллюстрировать еще один принцип разработки программ: после ее написания для произвольной «усредненной» ситуации необходимо проверить ее «на крайности». В данном случае, при отсутствии в строке слов (строка состоит из пробелов или пуста), установленное начальное значение b =-1 будет возвращено в качестве результата (что и задумывалось при установке значения –1 как недопустимого).

Лабораторный практикум

1. В строке найти последовательности цифр, каждую из них считать числом в той системе счисления, которая соответствует максимальной цифре, заменить числа в строке символами с кодами, полученными из этих чисел. Пример: aaa 010101 bbb 343 ccc – двоичная и пятиричная системы счисления.

2. В строке найти последовательности цифр, каждую из них считать числом в той системе счисления, которая соответствует первой цифре, заменить числа в строке символами с кодами, полученными из этих чисел. Пример: aaa 2010101 bbb 8343 ccc – двоичная и восьмиричная системы счисления.

6. Найти в строке два одинаковых фрагмента (не включающих в себя пробелы) длиной более 5 символов, скопировать их в выходную строку и удалить. Повторять этот процесс, пока такие фрагменты находятся. Остаток строки добавить в выходную.

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

10. Определить, является ли строка палиандромом (например, «я у ребят беру наган») – удалить пробелы, найти фрагменты – палиандромы максимальной длины и удалить.

Вопросы без ответов

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

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *