Способы хранения строк с

Содержание
  1. Классы хранения
  2. static
  3. extern
  4. thread_local (C++ 11)
  5. зарегистрировать
  6. Пример: автоматическая и статическая инициализация
  7. Хранение большого (15000) количества строк в строковом массиве
  8. Решение
  9. Способы хранения строк с
  10. 162. Представление символьных строк компилятором
  11. 163. Хранение символьных строк в памяти
  12. 164. Отличие «А» от ‘А’
  13. 165. Задание кавычек внутри строковой константы
  14. 166. Вычисление длины строки
  15. 167. Использование функции strlen
  16. 168. Копирование символьных строк
  17. 169. Слияние строк
  18. 170. Добавление заданного числа символов в конец строки
  19. 171. Преобразование одной строки в другую
  20. 172. Нарушения границ строк
  21. 173. Проверка совпадения двух строк с учетом строчных и прописных букв
  22. 174. Проверка совпадения двух строк без учета строчных и прописных букв
  23. 175. Преобразование символьной строки к прописным или строчным буквам
  24. 176. Нахождение первого появления заданного символа в строке
  25. 177. Определение местоположения первого появления заданного символа в строке
  26. 178. Нахождение последнего появления заданного символа в строке
  27. 179. Определение местоположения последнего появления заданного символа в строке
  28. 180. Строки, задаваемые far-указателями
  29. 181. Разработка строковых функций, использующих far-указатели
  30. 182. Подсчет числа вхождений символа в строке.
  31. 183. Смена порядка следования символов в строке на обратный
  32. 184. Заполнение строки заданным символом
  33. 185. Сравнение двух символьных строк
  34. 186. Сравнение первых n символов двух строк
  35. 187. Сравнение строк без учета строчных и прописных букв
  36. 188. Преобразование символьного представления числа
  37. 189. Дублирование содержимого строки
  38. 190. Поиск в строке первого вхождения любого символа из заданного набора
  39. 191. Поиск подстроки в строке
  40. 192. Определение количества вхождений подстроки
  41. 193. Определение местоположения подстроки
  42. 194. Поиск крайнего правого вхождения подстроки
  43. 195. Вывод строки без спецификатора формата %s
  44. 196. Удаление подстроки из строки
  45. 197. Замена одной подстроки на другую
  46. 198. Преобразование ASCII-представлений чисел
  47. 199. Проверка алфавитно-цифрового символа
  48. 200. Проверка буквы алфавита
  49. 201. Проверка ASCII-значения символа
  50. 202. Проверка управляющих символов
  51. 203. Проверка символа-цифры
  52. 204. Проверка графического символа
  53. 205. Проверка буквы: прописная или строчная
  54. 206. Проверка печатного символа
  55. 207. Проверка знаков пунктуации
  56. 208. Проверка символов разделения
  57. 209. Проверка шестнадцатиричной цифры
  58. 210. Преобразование буквы в прописную
  59. 211. Преобразование буквы в строчную
  60. 212. Работа с ASCII-символами
  61. 213. Форматированный вывод в строковую переменную
  62. 214. Ввод символов из символьной строки
  63. 215. Экономия памяти путем кодирования строк
  64. 216. Инициализация строки

Классы хранения

Класс хранения в контексте объявлений переменных C++ — это описатель типа, который управляет временем существования, компоновкой и расположением памяти объектов. Каждый объект может иметь только один класс хранения. Переменные, определенные в блоке, имеют автоматическое хранение, если не указано иное с помощью extern static thread_local описателей, или. Автоматически создаваемые объекты и переменные не имеют компоновки. Они не доступны для кода за пределами блока. Память выделяется для них автоматически, когда выполнение входит в блок и освобождается при выходе из блока.

Примечания

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

Visual Studio 2010 и более поздних версий: auto Ключевое слово больше не является описателем класса хранения C++, а register ключевое слово является устаревшим. Visual Studio 2017 версии 15,7 и более поздних версий: (доступно с /std:c++17 ): register ключевое слово удаляется из языка C++.

static

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

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

При объявлении переменной или функции в области видимости файла (глобальной и/или области пространства имен) static ключевое слово указывает, что переменная или функция имеет внутреннюю компоновку. При объявлении переменной она имеет статическую длительность и компилятор инициализирует ее со значением 0, если не указано другое значение.

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

При объявлении члена данных в объявлении класса static ключевое слово указывает, что одна копия элемента совместно используется всеми экземплярами класса. Статические данные-член должны быть определены в области видимости файла. Целочисленный член данных, объявляемый как, const static может иметь инициализатор.

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

Объявление членов объединения как статических невозможно. Однако глобально объявленное анонимное объединение должно быть явно объявлено static .

В этом примере показано, как переменная static , объявленная в функции, удерживает свое состояние между вызовами этой функции.

В этом примере показано использование static в классе.

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

Начиная с C++ 11, static Инициализация локальной переменной гарантирует потокобезопасность. Эта функция иногда называется магической статичностью. Однако в многопоточном приложении все последующие назначения должны быть синхронизированы. Потокобезопасную функцию статической инициализации можно отключить с помощью /Zc:threadSafeInit- флага, чтобы избежать зависимости от CRT.

extern

Объекты и переменные, объявленные как extern объявляют объект, который определен в другой записи преобразования или во внешней области видимости как внешняя компоновка. Дополнительные сведения см. в разделе extern и Преобразование единиц и компоновки.

thread_local (C++ 11)

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

Обратите внимание на thread_local описатель:

Динамически инициализированные локальные переменные потока в библиотеках DLL могут быть неправильно инициализированы во всех вызывающих потоках. Дополнительные сведения см. на веб-сайте thread .

thread_local Спецификатор можно сочетать с static или extern .

Можно применять thread_local только к объявлениям и определениям данных; thread_local не может использоваться в объявлениях или определениях функций.

Можно указать thread_local только для элементов данных со статической длительностью хранилища. Сюда входят глобальные объекты данных ( static и extern ), локальные статические объекты и статические члены данных классов. Объявленная локальная переменная thread_local неявно является статической, если не предоставлен другой класс хранения; иными словами, в области видимости блока thread_local эквивалентна thread_local static .

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

в Windows thread_local функционально эквивалентен __declspec(thread) за исключением того, что *__declspec(thread) * может применяться к определению типа и является допустимым в коде на языке C. Везде, где это возможно, используйте, thread_local так как он является частью стандарта C++ и, таким образом, более переносим.

зарегистрировать

Visual Studio 2017 версии 15,3 и более поздних версий (доступно в /std:c++17 ): register ключевое слово больше не является поддерживаемым классом хранения. Ключевое слово по-прежнему зарезервировано в стандарте для будущего использования.

Пример: автоматическая и статическая инициализация

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

Рассмотрим следующий пример, в котором определяется класс, который регистрирует инициализацию и удаление объектов, а затем определяет три объекта: I1 , I2 и I3 .

В этом примере показано, как и когда I1 I2 инициализируются объекты, и, а также I3 когда они уничтожаются.

Существует несколько моментов, которые необходимо учитывать в программе:

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

Во-вторых, в C++ не обязательно объявлять объекты или переменные в начале блока. Более того, эти объекты инициализируются, только если поток элемента управления достигает их определения. ( I2 и I3 являются примерами таких определений.) Выходные данные показываются точно при инициализации.

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

Источник

Хранение большого (15000) количества строк в строковом массиве

Вложения

masha_001.7z (41.6 Кб, 3 просмотров)

Алгоритм и структура для поиска большого количества строк в другом массиве строк
Здравствуйте! Я решаю следующую задачу: Есть файл со «строками» (средняя длина которых 40-50.

Хранение большого количества файлов
Есть свой видео-хостинг типа ютуба, и вот такой вопрос возник. Как мне организовать хранение.

Хранение и использование большого количества изображений
Всем привет! Подскажите способ хранения большого количества изображений, чтобы можно было эти.

Хранение большого количества бинарных данных
Возник вопрос связаный с хранением данных: Мне нужно сохранять массивы бинарных данных (каждый.

anwender95, тогда может хранить лучше всего в графе все слова ?

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

и получишь в конце случайное слово ;
Всего таких генераций случайных букв будет как длина слова .

Можно ,скорее всего еще как то слить одинаковые части у слов ,наподобие автоматов

но это уж надо как делать пометки когда остановиться

Например : кукуруза входит в (ку) руза , но и входит кукукукукукукуруза тоже

Решение

Я как то делал так , но это было в терминах файловой системы

т.е у меня каждая папка имела имя — буква алфавита

но сейчас,пока не могу представить как это хранить в памяти ,
походу придеться каждой вершине дать уникальное имя

Например ,номер уровня и букву

вот ,тогда можно хранить например в матрице смежностей

Добавлено через 3 минуты
anwender95, 15000 слов ,да можно конечно и не париться и хранить все в массиве из [char*]
генерировать случайное число %15000 и использовать

Если все завязано на канкретное число и компактность их хранения вам не важна

Добавлено через 7 минут
anwender95,

Источник

Способы хранения строк с

Для хранения одного ASCII-символа требуется один байт памяти. Как известно, строка в Си — это последовательность ASCII-символов. При объявлении в программе строковой константы (литерной строки) Си автоматически добавляет в конец строки NULL-СИМВОЛ (двоичный нуль). Когда символьная строка создается в программе путем считывания символов с клавиатуры, следует добавлять NULL-СИМВОЛ после последнего введенного символа, отмечая тем самым конец строки. Символьная строка представляет собой последовательность байтов, заканчивающуюся двоичным нулем NULL, как показано на рис. 161.

Рис. 161. Си хранит строки в последовательных байтах памяти

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

162. Представление символьных строк компилятором

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

При использовании в программе строковой константы компилятор автоматически добавляет символ NULL (‘\0’) в конец строки. На рис. 162 показано, как Си-компилятор в действительности хранит в памяти приведенную выше константу.

Рис. 162. Си автоматически дополняет строковую константу NULL-символом

163. Хранение символьных строк в памяти

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

Читайте также:  Классический способ изготовления шампанского

В данном случае создается строка, способная содержать 256 символов, индексируемых от string [0] до string [255]. Поскольку в строке может содержаться меньше 256 символов, как правило, для обозначения конца строки используется символ NULL (0 в коде ASCII). Символ NULL не размещается в конце строки компилятором автоматически (за исключением случая строковых констант). Однако некоторые функции, такие как fgets или gets, размещают символ NULL в конце строки. При работе с символьными строками полную ответственность за наличие в строке NULL-символа несет программа. В следующей программе BUILDABC.C определяется 256-символьная строка, которой затем присваиваются прописные буквы алфавита:

Для присваивания строке букв от А до Z в программе используется цикл-for. Для обозначения конца строки после буквы Z размещается NULL-СИМВОЛ. Далее с помощью функции printf выводятся все символы строки сразу. Как уже известно, функции Си используют для обозначения конца строки NULL-СИМВОЛ. В следующей программе A_THRU_J.C строке также присваиваются символы от А до Z. Однако, символ NULL присваивается элементу массива string [10], который следует за элементом, содержащим букву J. При выводе содержимого строки с помощью функции printf последним выведенным символом будет J:

Для создании строковых данных нужно контролировать включение символа NULL в конец строки.

164. Отличие «А» от ‘А’

Как известно из С 161, символьная строка — это последовательность из нуля или более АSСII-символов, которая обычно завершается символом NULL (с кодом ASCII, равным 0). Работая с символами в Си, можно задавать их либо числовыми ASCII-значениями,либо непосредственно, заключая их в одинарные кавычки, например, ‘А’. С другой стороны, при использовании двойных кавычек (например «А») создается символьная строка, которая содержит заданный символ (или символы) и завершающий символ NULL. На рис. 164 показано, как в Си хранятся константы ‘А’ и «А».

Рис. 164. Хранение в Си констант ‘A’ и «A»

165. Задание кавычек внутри строковой константы

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

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

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

В следующей программе QUOTES.C демонстрируется использование специальной последовательности символов \» при задании знака кавычки внутри строковой константы:

166. Вычисление длины строки

Из С 163 известно, что символ NULL рассматривается в функциях Си обычно как символ, обозначающий конец строки. Такие функции, как fgets и cgets, присваивают символ NULL автоматически. В следующей программе SHOW_STR.C функция sets используется для чтения строки символов с клавиатуры, -затем с помощью цикла for выполняется посимвольный вывод содержимого строки до тех пор, пока не будет обнаружен символ NULL:

167. Использование функции strlen

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

В следующей программе STRLEN.C демонстрируется использование strlen:

После выполнения этой программы на экран выводится:

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

168. Копирование символьных строк

При работе со строками часто возникает потребность в копировании одной символьной строки в другую. Для выполнения этой операции большинство Си-компиляторов предоставляет функцию strcpy, с помощью которой символы одной строки (строка-источник) копируются в другую строку (строку-цель):

В качестве результата функция strcpy возвращает указатель на начало целевой строки. В следующей программе STRCPY.C демонстрируется использование функции strcpy:

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

В предложенной реализации функции символы исходной строки последовательно копируются в целевую до символа NULL включительно.

169. Слияние строк

При работе со строками может возникнуть потребность дополнить одну строку содержимым другой. Например, если в одной строке содержится имя поддиректории, а в другой — имя файла, то добавив имя файла к имени поддиректории, мы можем получить полное имя файла. Эта операция дополнения одной строки содержимым другой часто называется программистами конкатенацией строк. Для выполнения операции конкатенации строк большинство Си-компиляторов предоставляет функцию strcat, которая имеет следующий формат:

В следующей программе STRCAT.C демонстрируется использование функции strcat:

После компиляции и выполнения данной программы на экран выводится:

Для получения точного представления о работе strcat рассмотрим следующую реализацию этой функции:

Как можно видеть, сначала выполняется цикл по символам целевой строки (параметр target) до тех пор. пока не будет найден конец строки NULL. Затем каждый из символов исходной строки до символа NULL включительно добавляется к концу исходной строки.

170. Добавление заданного числа символов в конец строки

Из С 169 известно, что функция strcat позволяет выполнить слияние (конкатенацию) двух строк. В некоторых случаях может потребоваться добавить в конец данной строки содержимое другой строки, но не полностью, а только заданное количество (n) ее символов. Для выполнения данной операции большинство Си-компиляторов предоставляет функцию strncat, посредством которой первые» символов исходной строки добавляются в конец целевой строки:

Если заданное число символов превышает число символов в исходной строке, символы исходной строки будут копироваться вплоть до конца этой строки, но не более. В следующей программе STRNCAT.C демонстрируется использование функции strncat:

После компиляции и выполнения программы на экран выводится:

Для получения точного представления о работе strncat рассмотрим следующую реализацию этой функции:

171. Преобразование одной строки в другую

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

Параметр target — указатель строки, в которую копируется исходная строка. Параметр п определяет максимальное число копируемых символов. В следующей программе STRXFRM.C демонстрируется использование функции strxfrm:

172. Нарушения границ строк

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

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

173. Проверка совпадения двух строк с учетом строчных и прописных букв

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

Представленная функция возвращает значение 1, если строки эквивалентны, и 0 в противном случае. В следующей программе STREQL.C демонстрируется использование функции streql:

После компиляции и выполнения программы на экран выводится:

174. Проверка совпадения двух строк без учета строчных и прописных букв

В С 173 была создана функция sireql, которая обеспечивает в программах удобный способ проверки совпадения двух строк. При выполнении сравнения строк символы верхнего и нижнего регистров рассматриваются функцией streql как различные. Однако возможны случаи, когда различие между одной и той же прописной и строчной буквой не имеет значения при сравнении. Для сравнения строк без учета регистра можно предложить следующую функцию strieql:

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

После компиляции и выполнения программы на экран выводится:

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

При работе со строками может возникнуть потребность в преобразовании символов строки к верхнему регистру. Например, когда пользователь вводит с клавиатуры имя файла или им» покупателя, для упрощения операций сравнения или для обеспечения хранения данных в сопоставимом формате оказывается удобным преобразовывать введенные символы к верхнему регистру. Для подобных преобразований большинство Си-компиляторов предоставляет функции strlwr и strupr:

В следующей программе STRCASE.C демонстрируется использование этих двух функций:

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

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

176. Нахождение первого появления заданного символа в строке

При работе со строками часто возникает потребность в нахождении первого (самого левого) появления в строке заданного символа. Например, если выполняется работа со строкой, содержащей путь доступа к файлу, то может потребоваться просмотр строки для нахождения первого появления символа обратной наклонной черты (\). Для обеспечения такой возможности многими Си-компиляторами поддерживается функция strchr, которая возвращает указатель на первое появление в строке заданного символа:

Если заданный символ в строке не найден, то функция strchr возвращает символ NULL. В следующей программе STRCHR.С демонстрируется использование функции strchr:

После компиляции и выполнения этой программы на экран выводится:

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

177. Определение местоположения первого появления заданного символа в строке

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

Если символ в строке не найден,то значение, присваиваемое переменной index, будетравно длине строки. В дополнение к такому способу использования sirchr можно предложить следующую функцию str_index:

178. Нахождение последнего появления заданного символа в строке

При работе со строками может возникнуть необходимость найти последнее (самое правое) появление в строке заданного символа. Например, если выполняется работа со строкой, содержащей путь доступа к файлу, то может потребоваться просмотр строки для отыскания последнего появления символа обратной наклонной черты (\). Для обеспечения такой возможности многие Си-компиляторы предоставляют функцию strrchr, которая возвращает указатель на место последнего появления в строке заданного символа:

Если заданный символ в строке не найден, то strrchr возвращает символ NULL. В следующей программе STRRCHR.C демонстрируется использование функции strrchr:

Важно отметить, что посредством strrchr возвращается указатель местоположения, а не индекс символа в строке. Для получения точного представления о работе strrchr рассмотрим следующую реализацию этой функции: char *strrchr(const char *string, int letter) < char *ptr = NULL; while (*string) < if (*string == letter) ptr = string; string++; >return(ptr); >

179. Определение местоположения последнего появления заданного символа в строке

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

Читайте также:  Все способы связи с банком

Если символ в строке не найден, то значение, присвоенное индексу, будет равно длине строки. В дополнение к такому использованию strrchr можно предложить также следующую функцию strr_index:

180. Строки, задаваемые far-указателями

Как обсуждается в разделе «Управление памятью», far-указатели позволяют в программе, работающей под управлением DOS, получить доступ к данным, которые расположены вне текущего сегмента данных размером 64 Кб. При работе с far-указателями следует использовать только те функции, параметры которых являются far-указателями. К сожалению, все описанные функции манипулирования строками не предусматривают far-указатели строк в качестве значений параметров. При передаче far-указателя любой из этих функций произойдет ошибка. Однако, многие компиляторы обеспечивают реализации этих функций, работающие и с far-указателями. Различные варианты этих функций, отвечающие использованию в различных моделях памяти, собраны в соответствующих библиотеках поддержки компилятора. — Прим. перев. Например, для определения длины строки, задаваемой far-указателем, может быть использована следующая функция _fstrlen:

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

181. Разработка строковых функций, использующих far-указатели

Из С 180 известно, что отдельные компиляторы обеспечивают функции, которые работают со строками, передаваемыми функциям с помощью far-указателей. Если используемый компилятор не предоставляет такие функции,то они могут быть созданы самостоятельно путем модификации функций, представленных ранее в этом разделе. Например, следующая функция fstreql является вариантом функции streql, ориентированным на работу с far-указателями:

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

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

183. Смена порядка следования символов в строке на обратный

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

Для получения точного представления о работе strrev рассмотрим следующую реализацию этой функции:

184. Заполнение строки заданным символом

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

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

Как можно видеть, в цикле до появления символа NULL элементам строки присваивается значение заданного символа.

185. Сравнение двух символьных строк

С помощью функции streql, которая была представлена в С 173, можно проверить, равны ли две символьные строки. В зависимости от обработки, которую должна выполнить программа, могут возникать случаи (например, при реализации операции сортировки), когда требуется сравнивать строки для определения, больше ли содержимое одной строки, чем другой. Для выполнения такой операции в программе большинство Си-компиляторов предоставляет функцию strcmp, с помощью которой выполняется сравнение двух символьных строк:

При равенстве строк функция strcmp возвращает значение 0. Если первая строка больше, чем вторая, то возвращается значение, большее 0. Напротив, если вторая строка больше первой, то функция sircmp возвращает значение, меньшее 0. В следующей программе STRCMP.C демонстрируется использование функции strcmp:

Для получения точного представления о работе strcmp рассмотрим следующую реализацию этой функции:

186. Сравнение первых n символов двух строк

Как известно из С 185, для сравнения двух строк может быть использована функция strcmp. При работе со строками программе может потребоваться операция сравнения только первых п символов двух строк. Для выполнения в программе такой операции многие Си-компиляторы предоставляют функцию strncmp:

Подобно strcmp, функция strncmp возвращает значение 0 при равенстве сравниваемых строк и значение, меньшее или большее 0 в зависимости от того, какая из строк (вторая или первая) больше. В следующей программе STRNCMP.C демонстрируется использование функции strncmp:

Точное представление о работе strncmp дает следующая реализация этой функции:

187. Сравнение строк без учета строчных и прописных букв

Как известно из С 185, для сравнения двух строк может быть использована функция strcmp, Также известно (С 186), что для сравнения первых п символов двух строк используется функция strncmp. В обеих этих функциях прописная (верхний регистр) и строчная (нижний регистр) буквы рассматриваются как различные. Могут быть случаи, когда требуется сравнивать строки без учета регистра. Для выполнения такой операции большинство Си-компиляторов предоставляет следующие функции stricmp и strcmpi:

В следующей программе CMPCASE.C демонстрируется использование этих двух функций:

После компиляции и выполнения этой программы на экран выводится:

188. Преобразование символьного представления числа

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

Таблица 188. Функции Си-библиотеки, преобразующие A SCII-представление в числовые значения разных типов

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

189. Дублирование содержимого строки

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

При выполнении функции strdup с помощью malloc выделяется память, и затем в нее копируется содержимое строки. Когда копия строки становится ненужной, эта память может быть освобождена посредством функции/гее. В следующей программе STRDUP.C демонстрируется использование функции strdup:

Для получения точного представления о работе strdup рассмотрим следующую реализацию этой функции:

190. Поиск в строке первого вхождения любого символа из заданного набора

Из С 176 известно, как использовать функцию strchr для отыскания в строке первого появления заданного символа. В зависимости от назначения программы может возникнуть необходимость в организации поиска в строке первого вхождения любого символа из заданного набора символов. Для выполнения такой операции большинством Си-компиляторов обеспечивается функция strspn:

Эта функция возвращает смещение символа в строке, начиная с которого обнаружено несовпадение. Применение функции strspn демонстрируется следующей программой STRSPN.С:

После компиляции и выполнения этой программы на экран выводится:

Для получения точного представления о работе strspn рассмотрим следующую реализацию этой функции:

191. Поиск подстроки в строке

При работе со строками может потребоваться поиск в строке заданной подстроки. Для выполнения такой операции в большинстве Си-компиляторов имеется функция strstr:

Если подстрока внутри строки существует, то функция strstr возвращает указатель на первое появление подстроки в строке. Если подстрока не найдена, то возвращается NULL. В следующей программе STRSTR.C демонстрируется использование strstr:

Для получения точного представления о работе strstr рассмотрим следующую реализацию этой функции:

192. Определение количества вхождений подстроки

Как известно из С 191, для обнаружения заданной подстроки в символьной строке можно использовать функцию strstr. В некоторых случаях может потребоваться определить число вхождений подстроки в строку. Следующая функция strstr_cnt обеспечивает эту возможность:

193. Определение местоположения подстроки

В С191 была представлена функция strstr для получения указателя на подстроку, содержащуюся внутри заданной строки. Если символьные строки используются как массивы, то вместо указателя может потребоваться определить индекс первого символа найденной подстроки. Используя значение, возвращаемое функцией strstr, можно получить индекс следующим образом:

Если подстрока в строке не найдена, то значение переменной index будет равно длине строки. В дополнение к этому способу для получения индекса можно также воспользоваться следующей функцией strstr_index:

194. Поиск крайнего правого вхождения подстроки

В С 191 была представлена функция strstr, которая использовалась для получения указателя первого вхождения подстроки внутри строки. В зависимости от обработки, выполняемой в программе, может возникнуть необходимость в поиске последнего (самого правого) вхождения подстроки в строку. С помощью следующей функции r_strstr возвращается указатель на самое правое вхождение подстроки в строке или значение NULL, если строка не содержит заданную подстроку:

195. Вывод строки без спецификатора формата %s

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

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

Как можно видеть, в этом случае функции printf передается единственный параметр — переменная, содержащая выводимую символьную строку.

196. Удаление подстроки из строки

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

197. Замена одной подстроки на другую

Для удаления первого вхождения подстроки из строки была создана функция slrslr_rem (С 196). Возникает также необходимость в замене первого вхождения одной подстроки в строке на другую. Следующая функция strstr_rep позволяет выполнить такую замену:

198. Преобразование ASCII-представлений чисел

При работе в программе с символьными строками одной из часто используемых операций является преобразование ASCII-представления числа, такого как 1.2345, в соответствующее значение int, float, double или unsigned. Для выполнения таких операций Си-компилятор обеспечивает функции, представленные в табл. 198.

Таблица 198. Функции Си, преобразующие ASCII-представления чисел

Функция Назначение
atof Преобразует символьную строку в значение типа float
atoi Преобразует символьную строку в значение типа int
atol Преобразует символьную строку в значение типа long int
strtod Преобразует символьную строку в значение типа double
strtol Преобразует символьную строку в значение типа long int

Функция Назначение
atof Преобразование ASCII-представления числа типа float
atoi Преобразование ASCII-представления числа типа int
atol Преобразование ASCII-представления числа типа long int

Перечисленные в табл. 198 функции имеют следующий формат:

Если функция не в состоянии преобразовать символьную строку в числовое значение, то возвращается значение 0. В следующей программе ASCII_TO.C демонстрируется использование этих функций:

После компиляции и выполнения этой программы на экран выводится:

Обратим внимание на вызов функции atoi. Когда на входе функции встречается неподходящий символ (буква В), выполнение преобразования прерывается и возвращается значение, вычисленное до появления этой литеры в строке.

199. Проверка алфавитно-цифрового символа

Алфавитно-цифровой символ — это буква или цифра. Другими словами, им может быть прописная буква от А до Z, строчная буква от а до z или цифра от 0 до 9. Для того чтобы определить, является ли символ алфавитно-цифровым, можно воспользоваться макрокомандой isalnum, которая объявляется в заголовочном файле ctype.h. Макрокоманда проверяет заданный символ и возвращает 0, если символ не является алфавитно-цифровым, и ненулевое значение в противном случае:

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

[Как можно видеть, макрокоманда isalnum работает только с буквами латинского алфавита. — Прим. перев.]

200. Проверка буквы алфавита

При работе с символами может возникнуть необходимость выяснить, является ли заданный символ буквой алфавита (прописной или строчной). Для того чтобы выполнить такую проверку, можно воспользоваться макрокомандой isalpha, объявляемой в заголовочном файле ctype.h. Макрокоманда проверяет заданный символ и возвращает 0, если значение символа не является буквой от А до Z или от а до z. В противном случае макрокоманда возвращает ненулевое значение:

Для получения точного представления о работе isalpha рассмотрим следующую реализацию этой макрокоманды:

[Макрокоманда isalpha работает только с буквами латинского алфавита. — Прим. перев.]

201. Проверка ASCII-значения символа

ASCII-значение, или ASCII-код — это значение, находящееся в пределах от 0 до 127. При работе в программе с символами может потребоваться определить, является ли содержимое символа значением ASCII. Для выполнения такой проверки может быть использована макрокоманда isascii, определение которой содержится в заголовочном файле ctype.h. Эта макрокоманда проверяет символ и возвращает 0, если символ не содержит ASCII-значения, и ненулевое значение в противном случае:

Для получения точного представления о работе isascii рассмотрим следующую реализацию этой макрокоманды:

Как видим, только значения в диапазоне от 0 до 127 макрокоманда считает ASCII-значениями.

202. Проверка управляющих символов

Управляющие символы — это значения из диапазонов от ^А. до ^Z и от ^а до ^z. В различных приложениях управляющие символы используются по-разному. Например, DOS использует символ Соntго1-z для представления конца файла. Различные текстовые процессоры используют управляющие символы для представления начертания символов (курсив или жирный). При работе с потребоваться символами строки может выяснить, является ли некоторый символ управляющим. Для выполнения такой проверки может использоваться макрокоманда iscntrl, содержащаяся в заголовочном файле ctype.h. Эта макрокоманда возвращает ненулевое значение для управляющего символа и 0 в противном случае:

203. Проверка символа-цифры

Цифра — это ASCII-значение из диапазона от ‘0’ до ‘9’. При работе с символами строк может понадобиться определить, является ли заданный символ цифрой. Для выполнения в программе такой проверки заголовочный файл ctype.h обеспечивает макрокоманду isdigit. Эта макрокоманда возвращает 0, если символ не является цифрой, и ненулевое значение в противном случае:

Для получения точного представления о работе isdigit рассмотрим следующую реализацию этой макрокоманды:

204. Проверка графического символа

Графические символы — это печатные символы (см. [sprint в С206) за исключением символа пробела (ASCII 32). Когда в программе выполняется операции вывода символов, может потребоваться определить, является ли некоторый символ графическим. Для выполнения такой проверки заголовочный файл ctype.h предоставляет макрокоманду isgraph. Макрокоманда выполняет проверку символа и возвращает значение 0, если символ не является графическим, и ненулевое значение в противном случае:

получения точного представления о работе isgraph рассмотрим следующую реализацию этой макрокоманды:

Как можно видеть, графические символы ASCII находятся в пределах значений от 33 до 127.

205. Проверка буквы: прописная или строчная

При работе с символами строк может возникнуть необходимость определения регистра (верхний или нижний), в котором представлена буква, задаваемая данным символом. В верхнем (нижнем) регистре представляются прописные (строчные) буквы. Для выполнения такой проверки могут использоваться макрокоманды islower и isupper, определяемые в заголовочном файле ctype.h. Макрокоманды проверяют заданный символ и возвращают ненулевое значение, если он является буквой нижнего или верхнего регистра соответственно. В противном случае макрокоманды возвращают 0. Макрокоманды используются следующим образом:

Для получения точного представления о работе этих макрокоманд рассмотрим следующие их реализации:

206. Проверка печатного символа

Когда в программе выполняется вывод символов, может потребоваться проверка каждого из символов, для того чтобы гарантировать вывод только печатных символов. Печатным символом является любой из символов в пределах от 32 (символ пробела) до 127 (символ DEL). Для выполнения такой проверки может быть использована макрокоманда [sprint, определяемая в заголовочном файле ctype.h. Макрокоманда возвращает ненулевое значение для печатных символов и 0 в противном случае:

Для получения точного представления о работе isprint рассмотрим следующую реализацию этой макрокоманды:

Как вы можете видеть, макрокоманда считает печатными все ASCII-символы в пределах от 32 до 127.

207. Проверка знаков пунктуации

В книге знаками пунктуации являются запятые, точки с запятой, тире, знаки вопроса и т.д. Однако в Си знаками пунктуации считаются любые ASCII-символы, не являющиеся алфавитно-цифровыми. Когда программа работает с символами строк, может возникнуть необходимость выяснить, содержит ли данный символ знак пунктуации. Для выполнения такой операции может быть использована макрокоманда ispunct, содержащаяся в заголовочном файле ctype.h. Макрокоманда проверяет символ и возвращает ненулевое значение, если символ содержит знак пунктуации, и нулевое значение в противном случае:

Для получения точного представления о работе ispunct рассмотрим следующую реализацию этой макрокоманды:

208. Проверка символов разделения

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

Для получения точного представления о работе isspace рассмотрим следующую реализацию этой макрокоманды:

209. Проверка шестнадцатиричной цифры

Шестнадцатиричная цифра — это цифра из диапазона 0-9 или буква от А до F или от а до f.При работе с символами строки может потребоваться определить, является ли некоторый символ шестнадцатиричной цифрой. Для выполнения такой проверки может быть использована макрокоманда isxdigit, определяемая в заголовочном файле ctype.h. Макрокоманда проверяет символ и возвращает ненулевое значение, если символ представляет шестнадцатиричную цифру, и нулевое значение в противном случае:

Точное представление о работе isxdigil дает следующая реализация этой макрокоманды:

210. Преобразование буквы в прописную

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

Макрокоманда и функция имеют следующие форматы:

Хотя и макрокоманда и функция преобразуют символ к верхнему регистру, работают они по-разному. Макрокоманда _toupper не выполняет проверку преобразуемого символа, которая бы гарантировала, что символ является буквой нижнего регистра. Если обратиться к макрокоманде с символом, не являющимся буквой нижнего регистра, то произойдет ошибка. С другой стороны, функция toupper преобразует только те символы, которые являются буквами нижнего регистра, оставляя все другие символы без изменения. Если есть уверенность, что символ содержит букву нижнего регистра, то лучше использовать макрокоманду _toupper — она выполняется быстрее, чем функция. Однако, если точно неизвестно, что символ является буквой нижнего регистра, следует использовать функцию toupper. В следующей программе TOUPPER.C демонстрируется использование_toupper и toupper с ошибкой, которая может возникнуть при использовании макрокоманды с символом, не являющимся буквой нижнего регистра:

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

211. Преобразование буквы в строчную

При работе с символьными строками одной из часто выполняемых операций является преобразование символа к нижнему регистру. В таких случаях имеется две возможности. Во-первых, можно использовать макрокоманду _tolower, которая определена в заголовочном файле ctype.h. Во-вторых, можно использовать функцию Си-библиотеки tolower. Макрокоманда и функция имеют следующие форматы:

Хотя и макрокоманда и функция преобразуют символ к нижнему регистру, работают они по-разному. В макрокоманде _tolower не выполняется проверка преобразуемого символа, гарантирующая, что он является буквой верхнего регистра. Если обратиться к макрокоманде с символом, который не является буквой верхнего регистра, то произойдет ошибка. С другой стороны, функция tolower преобразует только те символы, которые являются буквами верхнего регистра, оставляя все другие символы без изменения. Если есть уверенность, что символ содержит букву верхнего регистра, то лучше использовать макрокоманду tolower, она будет выполняться быстрее, чем функция. Однако, если точно не известно, что символ является буквой верхнего регистра, то следует использовать функцию tolower. В следующей программе TOLOWER.С демонстрируется использование _tolower и tolower с ошибкой, которая может произойти при использовании макрокоманды с символом, который не является буквой верхнего регистра:

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

212. Работа с ASCII-символами

При работе с символьными строками и использовании различных символьных функций могут возникнуть ситуации, когда требуется гарантировать, что заданный символ является действительным ASCII-символом, т.е. его значение находится в пределах от 0 до 127. В таких случаях может использоваться макрокоманда loascii, определенная в заголовочном файле ctype.h:

Точное представление о работе toascii дает следующая реализация этой макрокоманды:

Следует обратить внимание на то, что макрокоманда выполняет операцию поразрядного «И», которая очищает старший бит в байте значения символа. Это гарантирует попадание значения в диапазон 0-127.

213. Форматированный вывод в строковую переменную

Как известно, функция printf позволяет осуществить форматированный вывод на экран дисплея. В зависимости от потребностей программы может понадобиться, чтобы такой форматированный вывод направлялся не на экран, а в символьную строку. Например, предположим, что служащие имеют пятизначный номер и трехсимвольный идентификатор региона (такой как Sea для Seattle). Предположим также, что требуется хранить информацию о каждом служащем в файле, имя которого является комбинацией этих двух значений (такое как SEA12345). Функция sprintf позволяет осуществить форматированный вывода символьную строку. Эта функция имеет следующий формат:

Программа SPRINTF.C применяет функцию sprintf для создания 8-символьного имени файла служащего:

214. Ввод символов из символьной строки

Как известно, функция scanf позволяет получать форматированный ввод с stdin. В зависимости от потребностей программы, возможны случаи, когда символьная строка содержитполя,которыенужно присваивать определенным переменным. Функция sscansf позволяет программе считывать значения из строки, присваивая их заданным переменным. Функция sscanf имеет следующий формат:

Аргументы, передаваемые функции sscanf, должны быть указателями переменных. При успешном завершении функция sscansf возвращает число присвоенных полей. Функция возвращает 0, если не было присвоенных полей, и EOF, если был достигнут конец строки. В следующей программе SSCANF.С демонстрируется использование функции sscanf:

215. Экономия памяти путем кодирования строк

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

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

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

216. Инициализация строки

В разделе «Массивы, указатели и структуры» будет показано, как присваивается значение массиву при его объявлении. Там же будет сказано, что Си представляет символьные строки как массивы байтов. Таким образом, при объявлении строки можно задать также и ее начальное значение следующим образом:

Компилятор выделяет для строки title байтовый массив, длина которого достаточна для размещения заданного числа символов (плюс символ NULL). В данном случае строка title сможет вместить 19 символов. Если позднее присвоить данной строке более 20 символов, то будут перекрыты (и потеряны) значения других переменных, которые хранились в этой области памяти. Для строки section компилятор выделит строку, способную хранить точно 64 символа. Первым семи байтам строки будут присвоены буквы слова «Strings», а восьмому байту — символ NULL. Оставшиеся байты строки обычно инициализируются в NULL.

Источник

Читайте также:  Поверхность металлического зеркала покрывают слоем серебра пользуясь способом напыления
Оцените статью
Разные способы