FreeBasic
Главная
Вход
Регистрация
Пятница, 19.04.2024, 02:15Приветствую Вас Гость | RSS
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Форум » Freebasic » Исходники » Свой вариант UCASE\LCASE (Windows+Linux)
Свой вариант UCASE\LCASE (Windows+Linux)
haavДата: Вторник, 16.04.2019, 16:25 | Сообщение # 1
Генералиссимус
Группа: Администраторы
Сообщений: 1361
Репутация: 49
Статус: Offline
Привет всем!

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

Код
dim as string szText = "Некий текст" & chr(0) & "еще текст..."


Функции Lcase\Ucase , а так же например charUpper\charLower в Windows обломятся с преобразованием текста , содержащего нуль-терминаторы. Точнее они преобразуют только часть текста (до символа нуля). Код ниже должен решать задачу преобразования , независимо от содержимого буфера. Конечно же получив большую функциональность, теряется скорость.

Мои результаты тестирования кода:

Цитата
Система Linux (кодировка UTF-8)
Брал буфер с кол-вом символов - 1904 (русские + английские символы вперемешку)
Размер буфера в байтах - 3259

Средний результат преобразования:  0.0001074607021263772


В принципе, я думаю неплохо, однако в защиту стандартных Ucase\Lcase могу сказать, что они справятся с таким кол-вом текста в 2-3 раза быстрее. Если кто-то создаст код быстрее моего , но с такой же функциональностью на Linux\Windows , я буду рад.

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

Собственно сам код:


Код
#include once "crt.bi"

#ifndef __FB_WIN32__
extern "C"
   
   declare function towlower (ch as wint_t) as Long
   
   declare function towupper (ch as wint_t) as Long
   
End Extern
#endif

function S_Ucase(sText as string) as string
   
   dim as Ubyte ptr pBytes = sadd(sText)
   
   dim as integer iNBytes
   
   dim as Long pwByte
   
   for i as integer = 0 to len(sText)-1
      
      iNBytes = mbtowc(cast(any ptr,@pwByte), pBytes+i, 6)
      
      pwByte = towupper(pwByte)
      
      wctomb(pBytes+i, pwByte)
      
      if iNBytes > 1 then 
         
         i = i + (iNBytes - 1)
         
      EndIf      
      
   Next
   
   return sText
   
End Function 

function S_Lcase(sText as string) as string
   
   dim as Ubyte ptr pBytes = sadd(sText)
   
   dim as integer iNBytes
   
   dim as Long pwByte
   
   for i as integer = 0 to len(sText)-1
      
      iNBytes = mbtowc(cast(any ptr,@pwByte), pBytes+i, 6)
      
      pwByte = towlower(pwByte)
      
      wctomb(pBytes+i, pwByte)
      
      if iNBytes > 1 then 
         
         i = i + (iNBytes - 1)
         
      EndIf      
      
   Next
   
   return sText
   
End Function

dim shared as string sz 
sz = "РеГиСтР"
? sz
S_Ucase(sz) : ? sz
S_Lcase(sz) : ? sz
sleep


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
DarkDemonДата: Пятница, 19.04.2019, 07:17 | Сообщение # 2
Полковник
Группа: Друзья
Сообщений: 188
Репутация: -2
Статус: Offline
Стас,  ты не поверишь, но у меня функции LCASE\UCASE работают(компилятор 1.05.0). Жопа вся заключена в том,функции
печати не всегда печатают всё, что дальше нулевого чара(что довольно логично). Сыммитировать печать
всего буфера можно так:

Код
FOR i = 1 TO LEN(sz)
   PRINT  MID(sz, i, 1) + !"\u";
NEXT: PRINT


Твой текст у меня отображается крякозябрами, поэтому я добавил !"\u" для того, чтобы оно печаталось нормально.
MESSAGEBOX - обрезает, PRINT\WRITE - обрезают при !"\u"

Ну или можешь написать кейс в котором стандартная функция не работает, мне интересно.
Просто может я что-то делаю не так, или не в той кодировке.
Или может быть оно не работает только в линуксе? Тогда в этом случае надо идти к разрабам компилятора.
 
haavДата: Пятница, 19.04.2019, 20:20 | Сообщение # 3
Генералиссимус
Группа: Администраторы
Сообщений: 1361
Репутация: 49
Статус: Offline
Цитата DarkDemon ()
Или может быть оно не работает только в линуксе? Тогда в этом случае надо идти к разрабам компилятора.


То что в Linux не работает преобразование русского текста с помощью LCASE\UCASE  - это точно.  Там либо так преобразовывать: UCASE(WSTR(text)) , но при этом до первого нуля, либо никак. Нет я не буду спорить, может надо как-то , чтобы звезды сошлись и тогда на Linux будет работать, но я таких секретов не знаю.

Другое дело что у меня и в винде нихера не работало абсолютно точно на момент создания этой темы. Ведь я тестировал lcase\ucase , а также winapi charUpper\charLower. Сейчас работает... , похоже компилятор пошутил надо мной, либо дыры в матрице или у меня в голове shock


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
DarkDemonДата: Понедельник, 22.04.2019, 10:27 | Сообщение # 4
Полковник
Группа: Друзья
Сообщений: 188
Репутация: -2
Статус: Offline
Стас, я через неделю приеду от родственников, поставлю Mint на виртуалку(а тестить на железе буду с Live CD),
будем решать вопрос.
Мне самому для себя нужно уже разгрести эти кодировки и доку нормальную человеческую накатать.
Если есть такая дыра в функционале - поправим. Это же чистый софтвар, тут хардвара нет никакого,
значит ASM проканает.

Добавлено (04.05.2019, 02:59)
---------------------------------------------
Короче скачал Mint поставил на VirtualPC 2007, а он работает как говно, разрешение 640x480, звука тоже нет...
Пипец дожили, ОС не может найти 4 Мб видеопамяти на буфер и халявный Sound Blaster.
С таким разрешением работать на системе невозможно, разумеется поменять его нельзя.
При этом система затребовала у меня 12 Гигов диска, хотя сама нагло установилась всего лишь на 7.
Собственно суть понятна, качаешь x86 - размер один, x64 - другой, но вот лохи разрабы инсталятор
подправить походу не могут. Куда им править ОС, если они этого сделать не могут, из-за чего, собственно,
приходится заводить диск совсем иного размера. В комплекте фаерфокс, опен офис, GIMP и калькулятор = 7 Гигабайт.
Самое весёлое при всём при этом, что в Live режиме разрешение нормальное и ещё более весёлая хрень,
когда в live грузишься можно нажать CTRL + ALT + DEL, выкидывает на меню с паролем(типа Win Lock),
разумеется пароль не задан, но пустой ввод не прокатывает))). Мне всегда это нравилось, типа угадай пароль,
если сможешь.
Короче всё как обычно, делают какие-то коренные халатные ослы. Что было 10 лет назад, что сейчас,
одна фигня, ничего не делают для людей. С чем придётся столкнуться обычному человеку, чтобы поставить
простой FreeBasic - даже и не знаю(хотя в винде его и ставить не надо, скопировал в папку и он работает,
создаёшь батник с параметрами в этой же папке и сразу можно компилировать). Вангую пол сотни строк
терминала и недели две возьни только чтобы поставить его.

 
haavДата: Суббота, 04.05.2019, 07:44 | Сообщение # 5
Генералиссимус
Группа: Администраторы
Сообщений: 1361
Репутация: 49
Статус: Offline
Цитата DarkDemon ()
Короче скачал Mint поставил на VirtualPC 2007, а он работает как говно, разрешение 640x480, звука тоже нет...


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


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
DarkDemonДата: Понедельник, 06.05.2019, 00:46 | Сообщение # 6
Полковник
Группа: Друзья
Сообщений: 188
Репутация: -2
Статус: Offline
Стас, думаю найти VMWare варезный, VirtualBox мне уже давно доверия не внушает.
Раньше это был надёжный софт, но потом в дело вступило "поколение Z" и он чётко перестал запускаться на ряде
конфигураций, после чего его установка превращается в рулетку, а я сейчас очень бережно ставлю софт на второй комп,
там свежая винда для рабочих нужд(т.е. 100% корректно работающий комп).
Стоило бы конечно иметь отдельный жёсткий диск для таких штук, но и так уже прилично бабла в компы угрохал,
- так работает и ладно.

Хотел спросить в какой кодировке у тебя исходник(соотв. исп. строка компиляции) и какой конкретно сорс косячит.
Просто читаю документацию по towlower\towupper и понимаю, что там не всё так просто, универсальное и быстрое
сделать 100% не выйдет. Но можно ограничиться только русским и английским языком(хотя и есть вариант
нагло прогнать эти функции и закопировать результат в толстый файл, я не знаю могут ли за это дать по башке копирайтом).
Ботлнек даёт преобразование в мультибайт (4 байта как понимаю) и обратно, но сильного ускорения то и не будет,
потому что по факту это сжатие\распаковка, но в одном цикле должно работать быстрее, для длинных строк
можно использовать мультипоток, после чего бенчмарком определить границу где это эффективно.

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

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

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


Сообщение отредактировал DarkDemon - Понедельник, 06.05.2019, 00:48
 
haavДата: Понедельник, 06.05.2019, 09:00 | Сообщение # 7
Генералиссимус
Группа: Администраторы
Сообщений: 1361
Репутация: 49
Статус: Offline
Привет Леха!

Цитата
Хотел спросить в какой кодировке у тебя исходник(соотв. исп. строка компиляции) и какой конкретно сорс косячит.


На линуксах у меня все исходники в UTF-8 (без BOM). Что касается косяков , то в принципе вот пример:

Код
? lcase ("Привет Мир") ' не работает вообще
? Lcase (wstr("Привет" & chr(0) & "Мир")) 'работает только до нулевого символа
sleep


результат работы примера:

Цитата
Привет Мир
привет


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

Что касается применения моей функции в первом посте, то как пример поисковая утилита для любых файлов. Сам понимаешь, что в бинарных файлах нулей может быть даже больше чем текста smile Но поиск может понадобится в любых файлах и с поддержкой регистронезависимости. Стандартные LCASE\UCASE обламываются здесь начисто.


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
DarkDemonДата: Понедельник, 06.05.2019, 23:32 | Сообщение # 8
Полковник
Группа: Друзья
Сообщений: 188
Репутация: -2
Статус: Offline
Цитата haav ()
Конечно , если тебе самому интересно , то это твое дело, но лично я бы не стал точно.


На самом деле мне много чего интересно, много "белых пятен", стыдно признаться но Unicode - одно из них.
Когда изучаю тот или иной вопрос, то обычно пишу подробную документацию для себя и складываю исходники
в одно место, чтобы потом при необходимости их быстро поднять и вспомнить, постоянно держать всё в голове
не удаётся, слишком много информации.

Цитата haav ()
Что касается применения моей функции в первом посте, то как пример поисковая утилита для любых файлов.


А ну тогда да.

Цитата haav ()
еха, если такая канитель с вытаскиванием таблицы, то думаю это нецелесообразно.


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

Добавлено (12.05.2019, 07:38)
---------------------------------------------
Стас, извиняй, короче не потестирую я на линуксе, запарился этим анонизмом страдать с виртуалками.
Хотел делом заняться, но не тут то было. Там даже аддишены ставил через терминал с правами админа,
оно меня раз 20 что-то спрашивало - честно отвечал, а в итоге такая лажа. По-моему баги и линукс
- это уже синонимы, к этому стоит относиться по-философски.
Оф. сборка, приличное железо(в идеальном состоянии), свежая винда - к компу претензий 0, он идеально
работает.

 
haavДата: Воскресенье, 12.05.2019, 11:26 | Сообщение # 9
Генералиссимус
Группа: Администраторы
Сообщений: 1361
Репутация: 49
Статус: Offline
Цитата DarkDemon ()
Стас, извиняй, короче не потестирую я на линуксе


Привет Леха! Я же уже написал выше , забей на это.


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
Форум » Freebasic » Исходники » Свой вариант UCASE\LCASE (Windows+Linux)
  • Страница 1 из 1
  • 1
Поиск: