FreeBasic
Главная
Вход
Регистрация
Вторник, 15.10.2024, 15:07Приветствую Вас Гость | RSS
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 2
  • 1
  • 2
  • »
конвертация строк
sashasoldДата: Среда, 24.11.2021, 12:48 | Сообщение # 1
Лейтенант
Группа: Пользователи
Сообщений: 41
Репутация: 0
Статус: Offline
Здравия всем!
Вопрос такой: как преобразовать строку из DOS(OEM) в Unicode WString
может библиотека какая есть? в WinAPI видел подобную функцию, но там меж ANSI и Unicode
Желательно что бы можно было конвертировать все 3 кодировки меж собой и инвариантно (DOS, ANSI, Unicode)
а то эта тема надоела, мелочь, а не приятно =D
 
haavДата: Среда, 24.11.2021, 15:24 | Сообщение # 2
Генералиссимус
Группа: Администраторы
Сообщений: 1366
Репутация: 49
Статус: Offline
Код
#Include "windows.bi"

function encode(pIn as any ptr , sOptions as string) as any ptr
    
    Dim As DWORD dwNum
    
    select case sOptions
  
  Case "ua"
   
   dwNum = WideCharToMultiByte(CP_ACP , 0 , pIn , -1 , NULL , 0 , NULL , NULL)
   
   Dim As zstring ptr pSZ = Callocate(dwNum+1)
   
   WideCharToMultiByte(CP_ACP , 0 , pIn , -1 , pSZ , dwNum , NULL , NULL)
   
   return pSZ
   
  case "uo"
  
   dwNum = WideCharToMultiByte(866 , 0 , pIn , -1 , NULL , 0 , NULL , NULL)
   
   Dim As zstring ptr pSZ = Callocate(dwNum+1)
   
   WideCharToMultiByte(866 , 0 , pIn , -1 , pSZ , dwNum , NULL , NULL)
   
   return pSZ
  
  case "au"
  
   dwNum = MultiByteToWideChar(CP_ACP , 0 , pIn , -1 , NULL , 0)
   
   Dim As WString Ptr pSZ = CAllocate(dwNum*2+2)
   
   MultiByteToWideChar(CP_ACP , 0 , pIn , -1, pSZ , dwNum)
   
   return pSZ
  
  case "ou"
  
   dwNum = MultiByteToWideChar(866 , 0 , pIn , -1 , NULL , 0)
   
   Dim As WString Ptr pSZ = CAllocate(dwNum*2+2)
   
   MultiByteToWideChar(866 , 0 , pIn , -1, pSZ , dwNum)
   
   return pSZ
  
  case "ao"
   
   Dim As zstring ptr pSZ = Callocate(len(*cast(zstring ptr, pIn))+1)
   
   CharToOem(pIn , pSZ)
   
   return pSZ
  
  case "oa"
  
   Dim As zstring ptr pSZ = Callocate(len(*cast(zstring ptr, pIn))+1)
   
   OemToChar(pIn , pSZ)
   
   return pSZ
   
    End Select
    
End Function

' --------------- TEST -----------------

?

dim as string s = "БЛА..БЛА"

? "Initial text ascii:" , s
?
' ascii to oem
dim as zstring ptr pOEM = encode(strptr(s) , "ao")

? "ascii to oem:" , *pOEM

' oem to ascii
dim as zstring ptr pASCII = encode(pOEM , "oa")

? "oem to ascii:" , *pASCII

' oem to unicode
dim as wstring ptr pUNICODE = encode(pOEM , "ou")

? "oem to unicode:" , *pUNICODE

deallocate(pOEM)

deallocate(pASCII)

deallocate(pUNICODE)

' ascii to unicode
pUNICODE = encode(strptr(s) , "au")

? "ascii to unicode:" , *pUNICODE

' unicode to ascii
pASCII = encode(pUNICODE , "ua")

? "unicode to ascii:" , *pASCII

deallocate(pASCII)

' unicode to oem
pOEM = encode(pUNICODE , "uo")

? "unicode to oem:" , *pOEM

deallocate(pOEM)

deallocate(pUNICODE)

sleep


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


64 работает
Прикрепления: 0880409.png (26.2 Kb) · 4617310.png (16.6 Kb)
 
haavДата: Пятница, 26.11.2021, 07:38 | Сообщение # 4
Генералиссимус
Группа: Администраторы
Сообщений: 1366
Репутация: 49
Статус: Offline
Цитата sashasold ()
это у тебя была функция такая, или для меня набрал по быстрому?)


Была похожая , чуть подправил

Цитата
кстати на 32битном компиляторе вылетает


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


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

Код
#Include "Windows.bi"

Function Perecodirovka(pIn As Any Ptr, kodirovka As String) As Any Ptr
   Dim As DWORD dwNum
   Select Case kodirovka
      Case "Unicode_A"
         dwNum = WideCharToMultiByte(CP_ACP, 0, pIn, -1, NULL, 0, NULL, NULL)
         Dim As ZString Ptr pSZ = Callocate(dwNum+1)
         WideCharToMultiByte(CP_ACP, 0, pIn, -1, pSZ, dwNum, NULL, NULL)
         Return pSZ
         
      Case "Unicode_OEM"
         dwNum = WideCharToMultiByte(866, 0, pIn, -1, NULL, 0, NULL, NULL)
         Dim As ZString Ptr pSZ = Callocate(dwNum+1)
         WideCharToMultiByte(866, 0, pIn, -1, pSZ, dwNum, NULL, NULL)
         Return pSZ
         
      Case "A_Unicode"
         dwNum = MultiByteToWideChar(CP_ACP, 0, pIn, -1, NULL, 0)
         Dim As WString Ptr pSZ = Callocate(dwNum*2+2)
         MultiByteToWideChar(CP_ACP, 0, pIn, -1, pSZ, dwNum)
         Return pSZ
         
      Case "OEM_Unicode"
         dwNum = MultiByteToWideChar(866, 0, pIn, -1, NULL, 0)
         Dim As WString Ptr pSZ = Callocate(dwNum*2+2)
         MultiByteToWideChar(866, 0, pIn, -1, pSZ, dwNum)
         Return pSZ
         
      Case "A_OEM"
         Dim As ZString Ptr pSZ = Callocate(Len(*Cast(ZString Ptr, pIn))+1)
         CharToOem(pIn, pSZ)
         Return pSZ
         
      Case "OEM_A"
         Dim As ZString Ptr pSZ = Callocate(Len(*Cast(ZString Ptr, pIn))+1)
         OemToChar(pIn, pSZ)
         Return pSZ
   End Select
End Function

'---
Dim As String s = "БЛА...бла_123"

Print "Initial text ascii:", s
Print

'A_OEM
Dim As ZString Ptr pOEM = Perecodirovka(StrPtr(s), "A_OEM")
Print "ascii to oem:", *pOEM

'OEM_A
Dim As ZString Ptr pASCII = Perecodirovka(pOEM, "OEM_A")
Print "oem to ascii:", *pASCII

'OEM_Unicode
Dim As WString Ptr pUNICODE = Perecodirovka(pOEM, "OEM_Unicode")
Print "oem to unicode:", *pUNICODE

DeAllocate(pOEM)
DeAllocate(pASCII)
DeAllocate(pUNICODE)

'A_Unicode
pUNICODE = Perecodirovka(StrPtr(s), "A_Unicode") '@ - адрес дескриптора, а не данных, строки
Print "ascii to unicode:", *pUNICODE

'Unicode_A
pASCII = Perecodirovka(pUNICODE, "Unicode_A")
Print "unicode to ascii:", *pASCII

'Unicode_OEM
pOEM = Perecodirovka(pUNICODE, "Unicode_OEM")
Print "unicode to oem:", *pOEM

DeAllocate(pOEM)
DeAllocate(pASCII)
DeAllocate(pUNICODE)

Sleep


Сообщение отредактировал sashasold - Пятница, 26.11.2021, 13:19
 
electrikДата: Понедельник, 10.01.2022, 01:50 | Сообщение # 6
Полковник
Группа: Друзья
Сообщений: 182
Репутация: 3
Статус: Offline
Привет. Я видел в Window9 класс для работы со строками extwstring. Почему для перекодировки используются виндовые функции, ведь есть utfconf.bi? Эти функции вроде от самих создателей юникода, или они кривые? Просто я уже сталкивался с проблемой при использовании виндовых функций в синтезаторе речи. Я перегонял с юникода в cp866, и на английской винде у людей синтезатор не говорил по-русски. Там есть какое-то шаманство, запрятанное в дебрях винды. короче, я написал свою. Теперь проблем нет. Есть ли в планах у создателей FreeBasic всё же делать нормальную поддержку юникода? Бывают случаи, когда одна библиотека работает в utf16, а Lua лучше строки слать в UTF8. Вот тут то и начинаются шаманства. Если сохранять исходник в UTF8, значит подразумевается юзать char *, по аналогии FreeBasic - это zstring ptr. Если это UTF8 с BOM, он начинает ругаться на типы. приводить типы - ну тоже такое. Вобщем, всё не однозначно.
Зачем хранить исходник в utf8? В луа есть удобные функции регистрации lua функций, и проще запилить таблицу при инициализации массива и её передавать в lua. В пурике мы делали массив, аллоцировали нужную память, передавали в lua а потом очищали. Но это костыли великие! функции в utfconf.bi, действительно не для новичков, но думаю это можно поправить. В общем какие есть мысли. Можно заюзать libiconv, но это громоздко и таскание библиотек - не штырно.
 
haavДата: Понедельник, 10.01.2022, 08:37 | Сообщение # 7
Генералиссимус
Группа: Администраторы
Сообщений: 1366
Репутация: 49
Статус: Offline
На винде для перекодировки я не знаю инструментов лучше чем WideCharToMultiByte | MultiByteToWideChar.
libiconv - хорошая библиотека , но на винде она не сравнится с WideCharToMultiByte | MultiByteToWideChar. Хотя , если дело касается кроссплатформы , то очевидно libiconv будет предпочтительнее. libiconv плохо обрабатывает ошибочные данные. То есть встретив ошибку в тексте , она сразу возвращает ошибку. В свою очередь WideCharToMultiByte | MultiByteToWideChar будет конвертировать текст до самого конца , пропуская ошибки или пытаясь преобразовать данные. Насчет скорости их работы не знаю , скорее всего обе конвертируют по таблицам, поскольку ручной метод перекодировки всегда проигрывает. Для Linux в window9 я использую ручной метод (там по сути только UTF8<->UTF32), поскольку не захотел привязывать библиотеку к libiconv. Ручной метод имеет свои плюсы , поскольку можно контролировать проблемы с ошибочным текстом. Я как то писал для себя ручной метод для перекодировки UTF8 , UTF16 , UTF32 , KOI8-R , CP866 , CP1251 , и решил что буду использовать его в проектах , где скорость не критична.

Насчет utfconf.bi. Я попробовал это чудо , когда создавал редактор , но мне показалось , что это вообще нормально не работает. Скорее всего , это что-то вроде wcstombs , mbstowcs.

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


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


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
zamabuvaraeuДата: Понедельник, 10.01.2022, 17:06 | Сообщение # 8
Подполковник
Группа: Друзья
Сообщений: 149
Репутация: 5
Статус: Offline
Я не очень хорошо понимаю, зачем в 21 веке, когда везде работает юникод, нужна возня с 866, 1251. Для вывода на консоль? Но консоль прекрасно работает с юникодом (см. функции WriteConsoleW и ReadConsoleW). Ну разве что когда стандартные потоки ввода‐вывода перенаправлены, но и тогда не нужно полагаться что обязательно будет кодировка 1251 или 866, кодировку следует выяснять через GetConsoleC и GetConsoleOutputCP, самостоятельная установка кодировки — это вообще категории образцовых примеров как не надо делать.

Я раньше все исходники хранил в UTF-16. В старом блокноте эта кодировка загадочно называется «Юникод». И это даже работает в FBEdit.
Все строковые литералы становятся юникодными, это лечится через Str("литерал"). Но главная проблема исходников в UTF-16, что система контроля версий такой файл считает бинарным и не отображает его историю изменений на гитхабе.
Я перекатил все исходники обратно на ASCII. Строковые литералы теперь всегда обрамляю либо в Str("строка"), либо в WStr("строка").
Если в строке встречаются символы, которые не входят в младшую половину ASCII, то это значит, что такие строки требуют локализации, я всегда выношу их в ресурсы программы. Ну а с ресурсами проблем нет, потому что ресурсы всегда хранятся в юникоде.

Добавлено (10.01.2022, 17:11)
---------------------------------------------
Ну и всегда использую обобщённые типы вроде TCHAR и PTSTR для символов и строк.

 
electrikДата: Понедельник, 10.01.2022, 20:11 | Сообщение # 9
Полковник
Группа: Друзья
Сообщений: 182
Репутация: 3
Статус: Offline
Да я  с удовольствием  бы использовал юникод. Дело в том, что синтезатор старый, и написан на asme, и привязан к 866. Новая версия, которая написана на C и опубликована недавно на гитхабе, привязана к koi8. хотя если посмотреть, внутреннее представление подобных программ может быть любым, ибо парсить внутри синта UTF8 удовольствие не для слабонервных. Гораздо удобней юзать кодировки которые чему-то кратны. Тем более, этот синтезатор русский. Мы конечно при помощи обвесок заставляем его говорить и по-грузински, но это всё на основе русских фонем. Я конечно в данную секунду не бегу за кросс-платформенностью, но всё же хочется сделать запил, для возможного будущего, а может и не возможного.
Перекодировку кратных кодировок, думаю напишет пятилетний, меня больше интересует в UTF8 и из неё. Я видел исходник написанный юникодовцами в 2004 году, куски которого находятся в utfconv, но не уверен как оно работает, поэтому тут и спросил.
Если сможешь показать реально рабочий ручной вариант, можно будет подумать о таблицах или о оптимизациях.
Как я понимаю, вариант из utf16 в utf8 будет любой язык, и обратно, а в cp1251 - только кириллица, ибо все языки невозможно засунуть в один байт. Или у тебя только везде кирилица?


Сообщение отредактировал electrik - Понедельник, 10.01.2022, 20:24
 
haavДата: Понедельник, 10.01.2022, 21:48 | Сообщение # 10
Генералиссимус
Группа: Администраторы
Сообщений: 1366
Репутация: 49
Статус: Offline
Цитата electrik ()
Если сможешь показать реально рабочий ручной вариант, можно будет подумать о таблицах или о оптимизациях.


Код
Function EncodeUTF8ToUnicode(sTextUtf8 as string) as Wstring ptr
    
    Dim as Long iIndex
    
    dim as SHORT shUnicodeSymbol
    
    dim as wstring ptr ws = allocate(len(sTextUtf8)*sizeof(wstring)+1)
    
    for i as Long = 0 to len(sTextUtf8) -1
  
  if (sTextUtf8[i] and &hF0)  = &hE0 andalso (sTextUtf8[i+1] and &hC0) = &h80 andalso (sTextUtf8[i+2] and &hC0) = &h80 then ' 3
   
   shUnicodeSymbol = ((sTextUtf8[i] and &hF) shl 12) or (((sTextUtf8[i+1] and &h3F) shl 6) or (sTextUtf8[i+2] and &h3F))
   
   i+=2
   
  elseif (sTextUtf8[i] and &hC0)  = &hC0 andalso (sTextUtf8[i+1] and &hC0) = &h80 then ' 2
   
   shUnicodeSymbol = ((sTextUtf8[i] and &h1F) shl 6) or ((sTextUtf8[i+1] and &h3F))
   
   i+=1
   
  elseif (sTextUtf8[i] and &h80)  = &h0 then ' 1
   
   ' если нужно кодировать строку, содержащую нули в середине строки, но вырезать эти нули , то раскомментировать код ниже
   ' если оставить как есть, то первый попавшийся ноль станет концом строки
   'if s[i] = 0 then continue for  
   
   shUnicodeSymbol = sTextUtf8[i]
   
  else ' суррагаты и прочую фигню заменяем рекомендуемым знаком вопроса
   
   shUnicodeSymbol = &hFFFD
   
  EndIf
  
  (*ws)[iIndex] = shUnicodeSymbol
  
  iIndex+=1
  
    Next
    
    (*ws)[iIndex] = 0
    
    return ws
    
End Function

Function EncodeUnicodeToUTF8(wsText as wstring ptr ) as string    
    
    Dim as Long iSimbol
    
    dim as string sRet
    
    For i as long = 0 to len(*wsText)-1
  
  iSimbol = wsText[i]
  
  If iSimbol < &h80 Then
   
   sRet &= chr(iSimbol)
   
  ElseIf iSimbol < &h800 Then
   
   sRet &= chr(&hC0 or (iSimbol shr 6)) & chr(&h80 or (iSimbol and &h3f))
   
  ElseIf iSimbol < &h10000 Andalso (iSimbol < &hD800 Orelse iSimbol > &hDFFF) Then
   
   sRet &= chr((&he0 or (&hF and (iSimbol shr 12)))) & chr(&h80 or (&h3f and (iSimbol shr 6))) & chr(&h80 or (iSimbol and &h3F))
   
  Else 'нафиг суррогаты , заменим рекомендуемым знаком вопроса
   
   sRet &= Chr(&hEF) & Chr(&hBF) & Chr(&hBD)
   
  End If
  
    Next
    
    return sRet
    
End Function

dim shared as Short ku(&hC0 to &hFF) = {&h44E , &h430 , &h431 , &h446 , &h434 , &h435 , &h444 , &h433 ,_
&h445 , &h438 , &h439 , &h43A , &h43B , &h43C , &h43D , &h43E , &h43F , &h44F , &h440 , &h441 , &h442 ,_
&h443 , &h436 , &h432 , &h44C , &h44B , &h437 , &h448 , &h44D , &h449 , &h447 , &h44A , &h42E , &h410 ,_
&h411 , &h426 , &h414 , &h415 , &h424 , &h413 , &h425 , &h418 , &h419 , &h41A , &h41B , &h41C , &h41D ,_
&h41E , &h41F , &h42F , &h420 , &h421 , &h422 , &h423 , &h416 , &h412 , &h42C , &h42B , &h417 , &h428 ,_
&h42D , &h429 , &h427 , &h42A}

dim shared as Short uk(&h410 to &h44F) = {&hE1 , &hE2 , &hF7 , &hE7 , &hE4 , &hE5 , &hF6 , &hFA , &hE9 ,_
&hEA , &hEB , &hEC , &hED , &hEE , &hEF , &hF0 , &hF2 , &hF3 , &hF4 , &hF5 , &hE6 , &hE8 , &hE3 , &hFE ,_
&hFB , &hFD , &hFF , &hF9 , &hF8 , &hFC , &hE0 , &hF1 , &hC1 , &hC2 , &hD7 , &hC7 , &hC4 , &hC5 , &hD6 ,_
&hDA , &hC9 , &hCA , &hCB , &hCC , &hCD , &hCE , &hCF , &hD0 , &hD2 , &hD3 , &hD4 , &hD5 , &hC6 , &hC8 ,_
&hC3 , &hDE , &hDB , &hDD , &hDF , &hD9 , &hD8 , &hDC , &hC0 , &hD1}

function EncodeUnicodeToKOI8R(wsText as Wstring ptr) as string
    
    dim as Long iLen = len(*wsText)
    
    dim as string sText = space(iLen+1)
    
    for i as Long = 0 to iLen-1
  
  select case (*wsText)[i]
    
   Case &h401
   
    sText[i] = &hB3
    
   case &h451
   
    sText[i] = &hA3
    
   case &h410 to &h44F
   
    sText[i] = uk((*wsText)[i])
    
   case is < 128
   
    sText[i] = (*wsText)[i]

  End Select
  
    Next
    
    sText[iLen] = 0
    
    return sText
    
End Function

function EncodeKOI8RToUnicode(sText as string) as Wstring ptr
    
    dim as Long iLen = len(sText)
    
    dim as wstring ptr ws = allocate(iLen*sizeof(wstring)+1)
    
    for i as Long = 0 to iLen-1
  
  select case (sText)[i]
    
   Case &hB3
   
    (*ws)[i] = &h401
    
   case &hA3
   
    (*ws)[i] = &h451
    
   case &hC0 to &hFF
   
    (*ws)[i] = ku((sText)[i])
    
   case is < 128
   
    (*ws)[i] = (sText)[i]

  End Select
  
    Next
    
    (*ws)[iLen] = 0
    
    return ws
    
End Function

function EncodeUnicodeToCp1251(wsText as Wstring ptr) as string
    
    dim as Long iLen = len(*wsText)
    
    dim as string sText = space(iLen+1)
    
    for i as Long = 0 to iLen-1
  
  select case (*wsText)[i]
    
   Case &h401
    
    sText[i]= &hA8
    
   case &h451
    
    sText[i]= &hB8
    
   case &h410 to &h44F
   
    sText[i]= ((*wsText)[i]) - &h350
    
   case is < 128
   
    sText[i]=(*wsText)[i]
    
  End Select
  
    Next
    
    sText[iLen] = 0
    
    return sText
    
End Function

Function Encode1251ToUnicode(sText1251 as string) as Wstring ptr
    
    dim as Long iLen = len(sText1251)
    
    dim as wstring ptr ws = allocate(len(sText1251)*sizeof(wstring)+1)
    
    for i as Long = 0 to iLen-1
  
  select case (sText1251)[i]
    
   Case &hA8
    
    (*ws)[i]= &h401
    
   case &hB8
    
    (*ws)[i]= &h451
    
   case &hC0 to &hFF
   
    (*ws)[i]= ((sText1251)[i]) + &h350
    
   case is < 128
   
    (*ws)[i]=(sText1251)[i]
    
  End Select
  
    Next    
    
    (*ws)[iLen] = 0
    
    return ws
    
End Function

function EncodeUnicodeToCp866(wsText as Wstring ptr) as string
    
    dim as Long iLen = len(*wsText)
    
    dim as string sText = space(iLen+1)
    
    for i as Long = 0 to iLen-1
  
  select case (*wsText)[i]
    
   Case &h401
    
    sText[i]= &hf0
    
   case &h451
    
    sText[i]= &hf1
    
   case &h410 to &h43F
   
    sText[i]= ((*wsText)[i]) - &h390
    
   case &h440 to &h44F
   
    sText[i]= ((*wsText)[i]) - &h360
    
   case is < 128
   
    sText[i]=(*wsText)[i]
    
  End Select
  
    Next
    
    sText[iLen] = 0
    
    return sText
    
End Function

Function Encode866ToUnicode(sText866 as string) as Wstring ptr
    
    dim as Long iLen = len(sText866)
    
    dim as wstring ptr ws = allocate(len(sText866)*sizeof(wstring)+1)
    
    for i as Long = 0 to iLen-1
  
  select case (sText866)[i]
    
   Case &hf0
    
    (*ws)[i]= &h401
    
   case &hf1
    
    (*ws)[i]= &h451
    
   case &h80 to &hAF
   
    (*ws)[i] = ((sText866)[i]) + &h390
    
   case &hE0 to &hEF
   
    (*ws)[i] = ((sText866)[i]) + &h360
    
   case is < 128
   
    (*ws)[i]=(sText866)[i]
    
  End Select
  
    Next    
    
    (*ws)[iLen] = 0
    
    return ws
    
End Function

function Encode866ToCp1251(sText866 as string) as string
    
    dim as Long iLen = len(sText866)
    
    dim as string sText1251 = space(iLen+1)
    
    for i as Long = 0 to iLen-1
  
  select case (sText866)[i]
    
   Case &h80 to &hAF
    
    sText1251[i] = sText866[i]+ &h40
    
   case &hE0 to &hEF
    
    sText1251[i]= sText866[i]+ &h10
    
   case &hF0
   
    sText1251[i]= &hA8
    
   case &hF1
   
    sText1251[i]= &hB8   
    
   case is < 128
   
    sText1251[i]=sText866[i]
    
  End Select
  
    Next
    
    sText1251[iLen] = 0
    
    return sText1251
    
End Function

function Encode1251ToCp866(sText1251 as string) as string
    
    dim as Long iLen = len(sText1251)
    
    dim as string sText866 = space(iLen+1)
    
    for i as Long = 0 to iLen-1
  
  select case (sText1251)[i]
    
   Case &hC0 to &hEF
    
    sText866[i] = sText1251[i] - &h40
    
   case &hF0 to &hFF
    
    sText866[i]= sText1251[i] - &h10
    
   case &hA8
   
    sText866[i]= &hF0
    
   case &hB8
   
    sText866[i]= &hF1   
    
   case is < 128
   
    sText866[i]=sText1251[i]
    
  End Select
  
    Next
    
    sText866[iLen] = 0
    
    return sText866
    
End Function


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
electrikДата: Понедельник, 10.01.2022, 23:36 | Сообщение # 11
Полковник
Группа: Друзья
Сообщений: 182
Репутация: 3
Статус: Offline
За функции Приогромнейшее спасибо! будем изучать.
 
WQДата: Среда, 12.01.2022, 23:27 | Сообщение # 12
Полковник
Группа: Проверенные
Сообщений: 215
Репутация: 7
Статус: Offline
У меня сложилось мнение, что функцию Chr можно заменить вызовом из заранее созданного массива, будет быстрее
 
zamabuvaraeuДата: Четверг, 13.01.2022, 10:58 | Сообщение # 13
Подполковник
Группа: Друзья
Сообщений: 149
Репутация: 5
Статус: Offline
Я всегда строку рассматриваю как массив символов с индексацией в виде квадратным скобок, и мне кажутся довольно странными такие функции как Chr и Asc.

Добавлено (13.01.2022, 11:01)
---------------------------------------------
Например:
Код
Dim s As WString Ptr = каким‐либо образом получаем строку

' Устанавливаем первым символом пробел
s[0] = 32

' Получаем первый символ в строке
Dim firstChar As Integer = s[0]

Строки типа String не использую, у них много недостатков.


Сообщение отредактировал zamabuvaraeu - Четверг, 13.01.2022, 11:02
 
haavДата: Воскресенье, 23.01.2022, 12:12 | Сообщение # 14
Генералиссимус
Группа: Администраторы
Сообщений: 1366
Репутация: 49
Статус: Offline
Цитата zamabuvaraeu ()
Строки типа String не использую, у них много недостатков.

Ну какие-то недостатки есть , как минимум нежелательно их использовать в сложно-составных структурах. Я уже обжигался. Но в простых структурах использовал и проблем не было. Возможно даже что это уже давно пофиксено и сейчас уже этого недостатка нет. Просто после того случая , когда полезли баги в программе , я теперь использую в структурах только zstring*n , wstring*n , zstring ptr , wstring ptr. Работая с UTF-8 , есть общий недостаток для zstring , string: бесполезность строковых функций mid , left , ucase и пр. для не латинских символов. Выйти из положения можно преобразованием текста в unicode и обратно.

Я перечислю достоинства:

1) избавляет от необходимости заботиться о выделении\освобождении памяти и не трахать мозги по этому поводу
2) безопасны , если конечно не использовать прямой доступ к памяти
3) быстрое получение длины строки (размер попросту лежит в структуре), в отличии от zstring , wstring , где длину надо всегда высчитывать

Я приведу пример со своим редактором. Там где использовался тип string , серьезных багов никогда не было. А вот при использовании zstring , wstring , массивов было с десяток багов , которые иногда приходилось ловить часами или даже днями. И тут отладчик бессилен , поскольку ошибка (креш) происходила там, где ее по определению быть не должно. Так что , если обильно работаешь с текстом , то безопасные динамические строки - это залог того , что меньше будешь париться с ошибками. Да где-то с потерей производительности , но узкие места всегда можно потом оптимизировать.


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
zamabuvaraeuДата: Понедельник, 24.01.2022, 13:00 | Сообщение # 15
Подполковник
Группа: Друзья
Сообщений: 149
Репутация: 5
Статус: Offline
Для моей задачи Я сделал собственный класс строк.

Строка устроена по принципу BSTR: длина + данные + нулевой символ. Строка совместима с WinAPI и КОМ без всяких конвертаций.

Длину строки не нужно вычислять, она хранится.

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

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

Используя правило подсчёта ссылок, потребитель уменьшает счётчик когда объект больше не нужен. Экземпляр строки самоуничтожится тут же, без промедления, когда на него больше нет ссылок.

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

Потребителю строки не нужно думать каким образом была создана строка, чтобы правильно её уничтожить. Аллокатор памяти сам знает каким образом память была создана, и умеет уничтожать такую память. Поэтому строка может быть создана «на массиве» или вообще не в куче, а в разделяемой между процессами памяти.
 
  • Страница 1 из 2
  • 1
  • 2
  • »
Поиск: