FreeBasic
Главная
Вход
Регистрация
Вторник, 15.10.2024, 15:40Приветствую Вас Гость | RSS
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
WString
sashasoldДата: Четверг, 02.09.2021, 23:35 | Сообщение # 1
Лейтенант
Группа: Пользователи
Сообщений: 41
Репутация: 0
Статус: Offline
Помогите разобраться с WString.
в справке написано "WString является массивом фиксированного размера расширенных символов, который никогда не переполняется, если размер известен во время компиляции. Он не имеет дескриптора, и  никогда не изменяется в размере, если это не указатель и Allocate/Reallocate/Deallocate не используются для него"
но 


Код
Dim As WString Ptr Wstroka
Wstroka = Callocate (2*5)
*Wstroka = "Привет!"
Print *Wstroka

*Wstroka = "1234567890Привет12345678901234567890Привет!"
Print *Wstroka
Sleep

во первых размер указан явно меньше длины строки "Привет!" 7 символов, 2*7=14, остальное должно обрезать, но такого нет.
во вторых интеренсо работа с нулями в строке. 1.00 выдает вот такое чудо))

Возможно из-за "Конец строки отмечен символом 0, так что символ нуля не должен быть частью WString или содержимое будет усечено"

а вот на 1.05 уже нормально


но позволяет выделять для строки любое количество, например Аllocate (1)
собственно вопрос:
все-так не фиксированный массив там?
Тогда зачем вообще нужен Allocate если без разницы сколько указывать хоть 1 хоть 100000 =)
и почему нельзя сделать как нормальный String для обращения без *, @ и прочих костылей
Прикрепления: 5319259.png (3.3 Kb) · 3799676.png (15.0 Kb)
 
haavДата: Пятница, 03.09.2021, 05:54 | Сообщение # 2
Генералиссимус
Группа: Администраторы
Сообщений: 1366
Репутация: 49
Статус: Offline
Цитата
все-так не фиксированный массив там?


нет

Цитата
но позволяет выделять для строки любое количество, например Аllocate (1)


Из-за таких ошибок (когда выделятся память меньше , чем требуется) в больших программах вылет происходит не в этом месте , а там , где все кажется сделано безупречно. Конечно программист не намеренно делает подобные ошибки , но зато потом долгими часами ищет проблему smile

Цитата
и почему нельзя сделать как нормальный String для обращения без *, @ и прочих костылей


Обещают сделать динамическую unicode строку , но пока это находится в списке будущих работ. Я сам для себя и для своей библиотеки написал свой вариант: https://www.freebasic.net/forum/viewtopic.php?f=8&t=29169


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
sashasoldДата: Пятница, 03.09.2021, 22:20 | Сообщение # 3
Лейтенант
Группа: Пользователи
Сообщений: 41
Репутация: 0
Статус: Offline

Цитата
сложновато для моего уровня программиста)
и кстати не работает =) " error 28: Expected pointer in 'type extWstring extends WString' "
не от сюда, не при подключении твоей библиотеки, не на x32 не x64

Что им мешает сделать полный аналог String только не для 1 байтной кодировки, а 2 байта на символ?
или заморочка из-за распознания нескольких стандартов Unicode?
Оно же как то реализовано на других языках, например Си!? FB в основном использует обвертки функций, обернули бы smile 
неужели везде так плохо...
 
haavДата: Суббота, 04.09.2021, 06:27 | Сообщение # 4
Генералиссимус
Группа: Администраторы
Сообщений: 1366
Репутация: 49
Статус: Offline
Цитата
и кстати не работает =) " error 28: Expected pointer in 'type extWstring extends WString' "


На старых версиях компилятора не работает (там не было поддержки наследования wstring\zstring). Работает на компиляторах , начиная с версии 1.07.


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
VitaminДата: Воскресенье, 05.09.2021, 19:46 | Сообщение # 5
Лейтенант
Группа: Пользователи
Сообщений: 59
Репутация: 4
Статус: Offline
Цитата sashasold ()
сложновато для моего уровня программиста)
Вот вариант попроще: загоняем WString строку в UShort массив, а дальше обращаемся с ней как со строкой WString

Код
#Include "windows.bi"

Type WstMas ' тип для хранения WString строки
   Declare Constructor()
   Declare Operator Cast() ByRef As WString ' Тип возвратит строку
   Declare Function Stroka() ByRef As WString ' функция возврата строки
   Declare Operator Let(wss As WString) ' присваивание строки Типом
   Private:
   sim(Any) As UShort ' массив для двухбайтных кодов строки
End Type

Constructor WstMas()
   ReDim sim(0) ' начальное состояние - 1 элемент, значение = 0
End Constructor

Operator WstMas.Cast() ByRef As WString ' Возврат строки из массива
   Return Peek(WString,@sim(0))
End Operator

Function WstMas.Stroka() ByRef As WString ' Возврат строки из массива
   Return Peek(WString,@sim(0))
End Function

Operator WstMas.Let(wss As WString) ' Приём строки в массив
   Var dlina = Len(wss) : ReDim sim(dlina) ' создаём на 1 ячейку больше - она и будет завершающим кодом = 0
   CopyMemory(@sim(0), @wss[0], dlina * 2)   
End Operator

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

Код
Dim wMas As WstMas ' создаём переменную для хранения строки WString в Ushort массиве

wMas = "Абракадабра" ' запись строки
? wMas, Len(wMas.Stroka()), Left(wMas.Stroka(), 2) & "+" & Mid(wMas.Stroka(), 7, 2)

wMas = "АбракадабраАбракадабра" ' перезапись строки
? wMas, Len(wMas.Stroka()), Left(wMas.Stroka(), 2) & "+" & Mid(wMas.Stroka(), 18, 2)

Sleep




Сообщение отредактировал Vitamin - Воскресенье, 05.09.2021, 20:54
 
sashasoldДата: Воскресенье, 05.09.2021, 23:06 | Сообщение # 6
Лейтенант
Группа: Пользователи
Сообщений: 41
Репутация: 0
Статус: Offline
Спасибо! По изучаю)

Еще вопрос

Код
Function f_abc(Stroka As WString) As Byte
   Print Stroka
   Return 1
End Function

Print f_abc("Привет")

Sleep

при таком использовании Wstring, не указывается размер выделяемый под строку. Не будет ли ошибок. Компилируется то, но в будущем не вылетит ли?
 
bxusinboyДата: Понедельник, 06.09.2021, 14:26 | Сообщение # 7
Рядовой
Группа: Пользователи
Сообщений: 16
Репутация: 2
Статус: Offline
Строка "Привет" храниться в exe файле как константа, поэтому для него не надо выделять память.
 
zamabuvaraeuДата: Среда, 15.09.2021, 16:21 | Сообщение # 8
Подполковник
Группа: Друзья
Сообщений: 149
Репутация: 5
Статус: Offline

Цитата
во первых размер указан явно меньше длины строки
Нет конечно. Вы указали сколько памяти выделить динамически. Вы не создавали строку статически, вы создали указатель на WString, поэтому компилятор не знает её размер.
Объявление статической WString выглядит так:
Код
Dim wszHelloWorld As WString * (количество символов + 1)
Именно так: количество символов (а не байт) + 1 символ для нулевого. Величина «количество символов» должна быть константой. Именно в таком случае компилятор будет знать длину строки; и при присваивании копировать туда столько символов, чтобы не произошло переполнение и затирание нулевого символа.

Вот так правильно:

Код
Dim Wstroka As WString * (12 + 1)
Wstroka = "Привет!"
Print Wstroka

Wstroka = "1234567890Привет12345678901234567890Привет!"
Print Wstroka
Sleep



Цитата
при таком использовании Wstring, не указывается размер выделяемый под строку. Не будет ли ошибок
Компилятор знает размер строки только в своей области видимости, внутри функции другая область видимости и эта информация теряется. Если ваша функция записывает данные в строку и вообще в любой буфер, то общая рекомендация состоит в том, чтобы функция принимала указатель на буфер и его длину.

(Не транслитерируйте имена переменных kirillitsei, potomu chto eto vaglyadit ploho i nevozhmozhno chitat')
 
  • Страница 1 из 1
  • 1
Поиск: