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

Предыдущая тема Следующая тема Перейти вниз

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

Сообщение  tux в Пт Авг 22, 2008 8:49 am

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


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


создание строки

Строка это произвольный набор символов, ограниченных двойными кавычками (").

Например:
Код:

print "Hello, world!"

Здесь текст, который находиться в нутри кавычек (Hello, world!) и являеться строкой.
Это такой же тип данных, как число.

Во FreeBASIC есть спецальный тип string предназначеный для работы со строкой.

Код:

dim as string str1
str1 = "Hello, world!"
print str1

В этом примере создаёться строковая переменная str1. Затем ей присваиваеться строка (Hello, world!).
Функция print печатает эту строку на экране.

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

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

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



Объединение строк (Конкадинация)

Тут ничего особо сложного нет. Для объединения строк во FreeBASIC-е используется либо знак "&", либо "+".
К примеру так:

Код:

dim as string pStr1, pStr2, pStr3, pStrOut
pStr1 = "Hello"
pStr2 = "Wor"
pStr3 = "ld!!!"
pStrOut = pStr1 + pStr2 & pStr3
print pStrOut

В результате, программа выведет уже собранную строку

Hello, world!


Однако есть серьезное отличие меж операторов конкадинации. Знак "&" используется для объединения только строковых значений, поэтому если в качестве операндов будут числовые переменные, то они объединятся как строка цифр, а знак "+" также используется и в математических операциях, поэтому при использовании его с числами, он просто выдаст результат их суммы, но при этом компилятор потребует преобразовать число в строку. Для этого служит функция Str:

Код:

dim as string pStrOut
dim as integer pVal1, pVal2
pVal1=65
pVal2=57
pStrOut=pVal1 & pVal2
print pStrOut
pStrOut=str(pVal1 + pVal2)
print pStrOut
pStrOut=str(pVal1) + str(pVal2)
print pStrOut

Выведет

6557
122
6557

Если же необходимо строку, в которой записано число преобразовать к числовому типу (допустим для проведения каких либо математических операций), то можно воспользоваться функцией Val:

Код:

dim as string pStrOut, pStr1, pStr2
dim as integer pVal
pStr1="65"
pStr2="56"
pStrOut=pStr1 + pStr2
print pStrOut
pVal=val(pStr1) + val(pStr2)
pStrOut=str(pVal)
print pStrOut

В результате получим

6556
121

Все же если требуется объединять строки, я порекомендую пользоваться именно символом "&".

Работа с сиволами

Иногда требуется работать не со всей строкой, а тока с определенными символами, для этого существуют тоже специальные функции.
Как извесно каждому сиволу строки принадлежит свой однобайтовый код (юникод пока не рассматриваем). Чтобы узнать код символа, используется функция Asc, и обратная ей Chr, которая позволяет из кода символа получит сам символ:

Код:

print asc("Z")
print chr(65)

В результате увидим

90
A

В качестве первого аргумента для функции Asc используется строка, а вторым необязательным агрументом является номер нужного символа из этой строки. Если номер не указан, то берется первый символ строки.
Для Chr в качестве аргумента необходимо число в диапазоне от 0 до 255.
К примеру если нам необходимо вывести допустим первые 10 символов английского алфавита, то можно сделать так:

Код:

dim as ubyte pVar, i
pVar=asc("a")
for i=0 to 9
    print chr(pVar+i)
next i

Выведет

a
b
c
d
e
f
g
h
i
j

Или если нам надо вывести все коды символов строки:

Код:

dim as string pStr
dim i as byte
pStr="qwerty"
for i=1 to len(pStr)
    print asc(pStr, i)
next i

Мы получим

113
119
101
114
116
121

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

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

Код:

dim as string pStr
dim as ubyte pByte
pStr="HelloWorld"
pByte=pStr[5]
print "code=" & pByte
print "char=" & chr(pByte)

Результатом будет

code=87
char=W

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


Выбор части строки

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

Код:

dim as string pStr="FreeBASIC is a free 32-bit compiler for the BASIC language."
print left(pStr, 10) & "..."

Получим

FreeBASIC ...

Аналогично функции Left, которая берет символы слева, есть функция Right, которая берет символы справа, синтаксис у нее аналогичный.
А что если нам надо взять кусок строки из середины? Для этого конечно можно воспользоваться функциями Left и Right, обрезать строку сначала с одного края, потом с другого, но для этого существует специальная функция Mid.
В качестве параметров ей нужно указать исходную строку, позицию, с которой начинаем выбирать символы, количество выбираемых символов. Последний параметр является необязательным, если его не указать, то строка выбирается до конца.
Для примера возьмем 8 символов, начиная с 5-го:

Код:

dim as string pStr="FreeBASIC is a free 32-bit compiler for the BASIC language."
print mid(pStr, 5, 8)

И получим

BASIC is

Это все конечно хорошо, но что если нам нужно взять строку с заранее неизвесного места, но извесным в том месте символом или символами? Для этого существует функция InStr, которая позволяет найти заданный символ/строку в исходной строке, и возвращает номер его позиции.
Допустим нам нужна строка после знака ":", это делается так:

Код:

dim as string pStr
dim as integer pPos
pStr="FreeBASIC: free 32-bit compiler for the BASIC language."
pPos=instr(pStr, ":")
print mid(pStr, pPos+1)

Получаем

free 32-bit compiler for the BASIC language.

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

В следующем примере разобъем строку на слова, соответственно будем искать пробелы в предложении:

Код:

dim as string pStr
dim as integer pPosStart, pPosFinish
pStr="FreeBASIC: free 32-bit compiler for the BASIC language."
pPosStart=1 'начинаем с первой позиции
pPosFinish=instr(pStr, " ") 'ищем первый пробел
while pPosFinish<>0 'продолжаем искать, пока не переберем все пробелы
    print mid(pStr, pPosStart, pPosFinish-pPosStart) 'выводим слово,
        'где его длинна - это разность между позициями двух пробелов
    pPosStart=pPosFinish+1 'в следующий раз выбираем слово после следующего пробела
    pPosFinish=instr(pPosStart, pStr, " ") 'получаем положение следующего пробела
wend
print mid(pStr, pPosStart) 'выводим оставшееся слово

Выведет

FreeBASIC:
free
32-bit
compiler
for
the
BASIC
language.

Это довольно сложный пример, но он хорошо иллюстрирует практическое применение функций.

Бывают случаи, когда необходимо взять строку без каких либо крайних символов (кавычки или лишние пробелы), для этого существуют функции LTrim, RTrim, Trim, которые обрезают эти символы соотсветственно лева, справа, или с обоих краев.
Синтаксис у этих функций аналогичен, поэтому рассмотрим только Trim, тк она чаще используется:

Код:

dim as string pStr
pStr="  Hello  "
print ">" & trim(pStr) & "<"

И получим

<Hello>

Без указания необязательных параметров, функция обрезает только пробелы, но можно в качестве параметра указать символ или строку, которую нужно обрезать:

Код:

dim as string pStr
pStr=":::Hello:"
print ">" & trim(pStr, ":") & "<"

Снова получим

<Hello>



Или так:

Код:

dim as string pStr
pStr="=>Hello=>"
print ">" & trim(pStr, "=>") & "<"

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

Код:

dim as string pStr
pStr="-=:He:l:lo:=-"
print ">" & trim(pStr, any ":-=") & "<"

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


Преобразование регистра символов

Существуют функции LCase, UCase необходимые для преобразования регистра символов в строке, которые преобразуют символ соответсвенно в нижний и верхний регистры.
Пример:

Код:

dim as string pStr
pStr="-=:Hello:=-"
print ucase(pStr)
print lcase(pStr)

Выведет

-=:HELLO:=-
-=:hello:=-

К сожалению они корректно работают только для латинских букв.


заполнение символами

Есть две функции space и string для создания строки содержащей набор символов.

Функция space возвращает строку состоящую из пробелов (код 32) указанной длины.

Код:

print "<" & space(3) & ">"

Выведет

< >

Первым параметром у функции string так же задаёться длина нужной строки, а вторым можно указать символ заполнения.

Код:

print "<" & string(3, "=") & ">"
print "<" & string(3, 33) & ">"

В результате получим

<===>
<!!!>






Заключение

Вот список основных функций, необходимых для работы со строками во FreeBASIC. Но это далеко не все. Более подробно с ними можно ознакомиться в справочнике.


Последний раз редактировалось: Eric-S (Вс Сен 13, 2009 8:16 am), всего редактировалось 13 раз(а) (Обоснование : Добавил ещё два подраздела.)
avatar
tux

Сообщения : 365
Дата регистрации : 2008-04-06
Возраст : 29
Откуда : Сибирь

Посмотреть профиль http://tux.nsk.ru/

Вернуться к началу Перейти вниз

Re: Работа со строками

Сообщение  Eric-S в Пн Авг 25, 2008 6:17 pm

Tux, всё хочу спросить, нафиг ты главу так размножил? Поудалял чтоли лишнии сообщения из этой темы!



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

во-первых unicode однозначно не испортиться, чего я боялся.
во-вторых asc() в некоторых случаях просто не заменим.

Код:

' создаём строчку
dim s as wstring *4
s = "a"

' создаём указатель
dim p as wstring ptr
p = @s

' код однозначно привышающий 255
p[0] = 258

' выводим число
print asc(p[0])

' кстати показывает не число, а символ
rem print p[0]
sleep

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: Работа со строками

Сообщение  tux в Вт Авг 26, 2008 6:08 am

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

а в примерчике походу ты сам запутался и народ путаеш
Квадратные скобки используются в двух случаях: для работы со строками и для работы с памятью.
В моих примерах они исмользуются именно для работы сос троками (и выводят именно код символа), а у тя указатель на область памяти и тут ты прав, возвращается какраз значение, размерностью в один символ в уникоде, ну и соответственно раз указатель на уникодовскую строку, то и печатается не его код а элемент строки, те символ
avatar
tux

Сообщения : 365
Дата регистрации : 2008-04-06
Возраст : 29
Откуда : Сибирь

Посмотреть профиль http://tux.nsk.ru/

Вернуться к началу Перейти вниз

Re: Работа со строками

Сообщение  Eric-S в Вт Авг 26, 2008 7:39 am

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

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: Работа со строками

Сообщение  gromov в Вс Авг 31, 2008 11:50 pm

В целом хорошо, и побольше музы в Ваших начинаниях .
Хотелось обратить внимание на следущее:
- исторически в книгах описание работы с функциями начинаются с полного описания синтаксиса функции с указанием всех возможных параметров и их типов (в некоторых случаях необходимо указывать и допустимые значения - если есть ограничения), а то негоже читать книгу и уточнять прочитанное в help'е.
Не сочтите за придирку.
Удачи !!!!!

gromov

Сообщения : 7
Дата регистрации : 2008-08-31
Возраст : 39
Откуда : Украина, Броды

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Работа со строками

Сообщение  Eric-S в Пн Сен 01, 2008 1:08 am

gromov, благодарим вас за замечание. Мы надеемся вообще сделать русский перевод официального руководства, ну а пока...
Tux сделал такое ускоренное погружение в тему работы со строками. (Я кстати сейчас прочитал последний вариант и также хочу высказать своё одобрение.)

Это очень большая тема и каждую функцию с ньюансами и примерами нужно разбирать подробно.

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

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

Чтоже касаеться госпожи Музы, то сначало разберитесь с товарищем Хроносом, он дядька суръёзный.

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Маленькая отсебятинка

Сообщение  justar в Пт Сен 05, 2008 4:33 pm

Вроде бы этот нюанс не отражён - сорри, если повторяюсь...

tux пишет:FreeBASIC также позволяет брать символ из строки посредством указания смещения относительно начала строки квадратных скобках сразу после переменной (те отсчет номера символа начинается от нуля). При этом мы получаем не сам символ, а его код. Ну а как из кода получить символ мы уже знаем.
Можно получить и сам символ - например, код:
Код:

Dim pStr As String
Dim pChar As String * 1 ' Ключевое место - не байт, а единичный стринг
pStr = "Hello, World"
pChar = pStr [7]
Print pChar
Sleep
напечает "W"

justar

Сообщения : 135
Дата регистрации : 2008-05-12
Возраст : 43
Откуда : Кишинёв, Республика Молдоа

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Работа со строками

Сообщение  DiG. GeRR в Вс Сен 06, 2009 9:00 pm

интересно, а почему asc возвращает значение integer - 4 байта, а не byte ну или хотя бы word для юникода?

DiG. GeRR

Сообщения : 101
Дата регистрации : 2009-01-30
Возраст : 25
Откуда : Рудный, Казахстан

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Работа со строками

Сообщение  Eric-S в Вс Сен 06, 2009 9:18 pm

Правильно, что вспомнили про юникод. word - всего 2 байта, да и воообще такого типа во фрибэйсике нет.

Нужна же была именно переменная, чтобы хранила 4 байта. А integer подходит. Вообще-то должна быть uinteger... Я не помню, надо в справочник глянуть.

А делать две функции, которые будут возвращать byte или uinteger... Перегрузка тут безсильна. Вот и унифицировали по максимуму.

Не забываем, что только под windows sizeof(wchar_t) равен 2, обычно это 4.

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: Работа со строками

Сообщение  Eric-S в Пт Сен 11, 2009 9:06 pm

Я дополнил главу ещё двумя подразделами.
А так же подправил несколько опечаток.
Ну и ещё чучка от себя, результаты выполнения программ, и несколько примечаний.

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: Работа со строками

Сообщение  trew в Пт Окт 15, 2010 3:57 pm

Очень хороший раздел, все понятно и доступно, благодарю!
P.S
Код:
dim as string pStr1, pStr2, pStr3, pStrOut
pStr1 = "Hello"
pStr2 = "Wor"
pStr3 = "ld!!!"
pStrOut = pStr1 + pStr2 & pStr3
print pStrOut
В результате, программа выведет уже собранную строку

Hello, world!

Сразу видать от руки простейшие примеры писали. Результат правильный: Helloworld!!! Но это ни коим образом не портит статью, а наоборот даже: при обучении нужно заносить код в редактор и разбирать что к чему....

trew

Сообщения : 331
Дата регистрации : 2010-10-14

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Работа со строками

Сообщение  Спонсируемый контент


Спонсируемый контент


Вернуться к началу Перейти вниз

Предыдущая тема Следующая тема Вернуться к началу


 
Права доступа к этому форуму:
Вы не можете отвечать на сообщения