Программирование >>  Операторы преобразования типа 

1 ... 144 145 146 [ 147 ] 148 149 150 ... 239


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

О Аргумент, определяющий индекс, должен быть действительным для данной строки. Его значение должно быть меньше количества символов в строке (как обычно, индекс первого символа равен 0). Кроме того, для определения конца может использоваться индекс позиции за последним символом.

Как правило, при обращении по индексу, превышающему фактическое количество символов, генерируется исключение out of range.

О Аргумент, определяющий количество символов, может иметь произвольное значение. Если он больше количества оставшихся символов в строке, то используются все оставшиеся символы. В частности, конструкция string::npos всегда может обозначать все оставшиеся символы .

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

filename.sub5tr(filename,findC .))

С другой стороны, показанное ниже выражение будет выполнено без исключений:

filename.substrCO. filename.findC ,))

Если точка не найдена, возвращается все имя файла.

Но даже при наличии точки расширение, возвращаемое при вызове substr(), может оказаться пустым, если за точкой нет ни одного символа. Данная ситуация проверяется условием:

if (extname.emptyC))

Если условие истинно, то имя временного файла состоит из обычного имени файла с заранее определенным расширением;

tmpname = filename; tmpname += suffix;

Расширение присоединяется оператором +=.

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

if (extname == suffix)

Если это условие истинно, то обычное расширение временных файлов заменяется расширением ххх:

tmpname = filename;

tmpname,replace (idx+1. extname.size(). xxx );

Выражение extname.size() возвращает количество символов в строке extname. Вместо size() также можно воспользоваться эквивалентной функцией length(). Таким образом, обе функции size() и iength() возвращают количество символов.



Помните, что функция size() не имеет отношения к объему памяти, выделяемой для хранения строки.

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

tmpname = filename;

tmpname.replace Cidx+1. string:;npos, suffix);

Конструкция string::npos в данном случае обозначает все остальные симво-лы>. Иначе говоря, все символы после точки заменяются строкой suffix. Замена работает н в том случае, если имя файла содержит точку без дальнейших символов - пустое расширением заменяется строкой suffix.

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

cout filename => tmpname endl:

1ример чтения слов и вывода символов I обратном порядке

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

Str1ng/5tr1ng2.cpp #1nclude <105tream> #1nclude <str1ng> using namespace std:

lnt main (lnt argc. char** argv) {

const string dellmsC \t..; ): string line:

Для каждой успешно прочитанной строки while CgetlineCdn.line)) {

string::size type begldx. endldx:

Поиск начала первого слова

begldx - line.find first not ofCdel1ms):

Пока удается найти начало очередного слова...

while Cbegldx != string::npos) {

Существование двух эквивалентных функций связано с фактическим слиянием двух архитектурных подходов. Функция Iength() возвращает длину строки и является аналогом функции str!en() для обычных С-строк, тогда как функция size() по;шерживает-ся всеми контейнерными классами и возвращает количество элементов в соответствии с архитектурными канонами STL.



Поиск конца текущего слова

endldx = 1ine.find first of Cdelims. begldx):

if (endldx == string: ;npos) {

Конец слова совпадает с концом строки

endldx = line.lengthO;

Вывод символов в обратном порядке for (int i=endldx-l: i>=static cast<int>(begldx): --i) { cout line[i]:

cout :

Поиск начала следующего слова

begldx = line.find first not of (delims. endldx):

cout end!:

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

const string delimsC \t..: ):

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

Внешний цикл работает до тех пор, пока в переменную line успешно читается очередная строка:

string line;

while (getline(cin,line)) {

Функция getllne() предназначена для чтения из потока данных в строковую неременную. Она читает все символы до ближайшего разделителя строк, которым но умолчанию является символ новой строки. Разделитель извлекается из потока данных, но не присоединяется к прочитанным данным. Передавая собственный разделитель строк в необязательном третьем аргументе, можно перевести функцию getline() в режим чтения лексем, разделенных заданными символами.

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

begldx = line.find first not of(delims):

Функция find first not of() возвращает индекс первого символа, не входящего в переданный строковый аргумент. Иначе говоря, функция возвращает первый символ, не указанный в переменной delims как разделитель. Как и прочие функции поиска, при отсутствии совпадения функция find first not of() возвращает string: inpos.

Внутренний цикл выполняется до тех нор, пока в потоке данных обнаруживается начало очередного слова:



1 ... 144 145 146 [ 147 ] 148 149 150 ... 239

© 2006 - 2025 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика