Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Power Basic

Страница: 1 |

 

  Вопрос: UTF-8 -> ANSI Добавлено: 09.01.09 00:03  

Автор вопроса:  Lapex
С прошедшими праздничками!

Что-то не выходит конвертировать строку из UTF-8 в ANSI кодировку :(.

Насколько я понял UTF-8 строка может быть, как ANSI так и Unicode. Т.к. мне нужно конвертировать текст(UTF-8) из текстового файла, то считаю, что у меня UTF-8 представлена, как ANSI.

Следующий код позаимствован у Josй Roca:
http://www.forum.it-berater.org/index.php?topic=157.0;prev_next=prev
#COMPILE EXE
#DIM ALL
#INCLUDE "Win32API.inc"


FUNCTION WideCharToUTF8 (BYVAL pWideStr AS DWORD) AS STRING

  LOCAL hr AS LONG
  LOCAL l AS LONG
  LOCAL Buffer AS STRING

  l = lstrlenW (BYVAL pWideStr)

  hr = WideCharToMultiByte (%CP_UTF8, %NULL, BYVAL pWideStr, l, _
                            BYVAL %NULL, 0, BYVAL %NULL, BYVAL %NULL)

  IF hr = 0 THEN EXIT FUNCTION
  Buffer = SPACE$(hr)

  hr = WideCharToMultiByte (%CP_UTF8, %NULL, BYVAL pWideStr, l, _
                            BYVAL STRPTR(Buffer), LEN(Buffer), BYVAL %NULL, BYVAL %NULL)

  IF hr = 0 THEN EXIT FUNCTION

  FUNCTION = Buffer
END FUNCTION

'==========================================================================

FUNCTION PBMAIN () AS LONG

  DIM strAnsiString AS STRING
  DIM strUTF8WidecharString AS STRING
  DIM strUTF8AnsiString AS STRING

  strAnsiString = "Р_С_Р_Р+Р°"    ' ANSI строка в UTF-8 кодировке ("Проба")

  ' Конвертируем из Ansi в Unicode
  strAnsiString = UCODE$(strAnsiString)
  ' Конвертируем из Unicode в UTF8 Unicode строку
  strUTF8WidecharString = WideCharToUTF8(STRPTR(strAnsiString))
  ' Конвертируем из UTF8 Unicode в Ansi
  strUTF8AnsiString = ACODE$(strUTF8WidecharString)
  
  MSGBOX strUTF8AnsiString

END FUNCTION

Почему-то результат: "????????", вместо "Проба"?

Ответить

  Ответы Всего ответов: 8  

Номер ответа: 1
Автор ответа:
 Sharp


Лидер форума

ICQ: 216865379 

Вопросов: 106
Ответов: 9979
 Web-сайт: sharpc.livejournal.com
 Профиль | | #1
Добавлено: 09.01.09 01:27
UTF-8 строка может быть, как ANSI так и Unicode

Жестоко.

Ответить

Номер ответа: 2
Автор ответа:
 Lapex



Вопросов: 6
Ответов: 56
 Профиль | | #2 Добавлено: 09.01.09 02:10
Сделал вывод из коментариев автора к своим примерам:
Note: Since WideCharToUTF8 expects a pointer to an Unicode string, if you have to convert an UTF-8 encoded Ansi string use:

Note: Since UTF8ToWideChar expects a pointer to an Unicode UTF8-encoded string, if you have to convert an UTF-8 encoded Ansi string use:

Finally, here are two functions to convert from Ansi to Ansi UTF8 and from Ansi UTF8 to Ansi:
Возможно не точно перевел.

Ответить

Номер ответа: 3
Автор ответа:
 Kalte



Вопросов: 1
Ответов: 11
 Профиль | | #3 Добавлено: 09.01.09 17:37
UCODE$(str, 866)

Ответить

Номер ответа: 4
Автор ответа:
 Kalte



Вопросов: 1
Ответов: 11
 Профиль | | #4 Добавлено: 09.01.09 17:47
ээ не то...
вот это
  1.  
  2. FUNCTION AsciiToUtf8 (BYVAL strAscii AS STRING) AS STRING
  3.  
  4.    LOCAL i AS LONG                ' // Loop counter
  5.    LOCAL strUtf8 AS STRING        ' // UTF-8 encoded string
  6.    LOCAL idx AS LONG              ' // Position in the string
  7.    LOCAL c AS LONG                ' // ASCII code
  8.    LOCAL b2 AS LONG               ' // Second byte
  9.    
  10.    IF LEN(strAscii) = 0 THEN EXIT FUNCTION
  11.    
  12.    ' // The maximum length of the translated string will be
  13.    ' // twice the length of the original string.
  14.    ' // We are pre-allocating the buffer for faster operation
  15.    ' // than concatenating each character one by one.
  16.    strUtf8 = SPACE$(LEN(strAscii) * 2)
  17.  
  18.    ' // Intialize index position in the string buffer
  19.    ' // used to store the UTF-8 encoded string
  20.    idx = 1
  21.    
  22.    ' // Examine the contents of each character in the Ascii string
  23.    FOR i = 1 TO LEN(strAscii)
  24.       ' // Get the Ascii code of the character
  25.       c = ASC(MID$(strAscii, i, 1))
  26.       ' // If it is betwen 0 and 127...
  27.       IF c < 128 THEN
  28.          ' // ...we simply copy it to the string buffer...
  29.          MID$(strUtf8, idx, 1) = MID$(strAscii, idx, 1)
  30.          ' // ...and increase the position by 1.
  31.          idx = idx + 1
  32.       ELSE
  33.          ' // We need to split the character into two characters.
  34.          ' // For the second byte, we only need the lower six bits of the character,
  35.          ' // and to ensure that the two upper bits will be 10 (in binary),
  36.          ' // i.e. (00111111 AND xxxxxxxx) OR 10000000
  37.          b2 = (c AND &H3F) OR &H80
  38.          ' // For the first byte, we need only the upper two bits from the character,
  39.          ' // and to ensure that the three upper bits will be 110 (in binary).
  40.          SHIFT RIGHT c, 6
  41.          c = c OR &HC0
  42.          ' // Copy the bytes to the buffer string and increase the index position by 2.
  43.          MID$(strUtf8, idx, 2) = CHR$(c, b2)
  44.          idx = idx + 2
  45.       END IF
  46.    NEXT
  47.  
  48.    ' // Return the encoded string
  49.    FUNCTION = LEFT$(strUtf8, idx - 1)
  50.  
  51. END FUNCTION



и это
  1.  
  2. FUNCTION Utf8ToAscii (BYVAL strUtf8 AS STRING) AS STRING
  3.  
  4.    LOCAL i AS LONG                ' // Loop counter
  5.    LOCAL strAscii AS STRING       ' // Ascii string
  6.    LOCAL idx AS LONG              ' // Position in the string
  7.    LOCAL c AS LONG                ' // ASCII code
  8.    LOCAL b2 AS LONG               ' // Second byte
  9.    LOCAL fSkipChar AS LONG        ' // Flag
  10.  
  11.    IF LEN(strUtf8) = 0 THEN EXIT FUNCTION
  12.    
  13.    ' // The maximum length of the translated string will be
  14.    ' // the same as the length of the original string.
  15.    ' // We are pre-allocating the buffer for faster operation
  16.    ' // than concatenating each character one by one.
  17.    strAscii = SPACE$(LEN(strUtf8))
  18.  
  19.    ' // Intialize index position in the string buffer
  20.    ' // used to store the converted Ascii string
  21.    idx = 1
  22.    
  23.    ' // Examine the contents of each character in the UTF-8 encoded string
  24.    FOR i = 1 TO LEN(strUtf8)
  25.       ' // If fSkipChar is set we have to skip this character
  26.       IF fSkipChar THEN
  27.          fSkipChar = 0
  28.          ITERATE FOR
  29.       END IF
  30.       ' // Get the Ascii code of the character
  31.       c = ASC(MID$(strUtf8, i, 1))
  32.       ' // If it is betwen 0 and 127...
  33.       IF c < 128 THEN
  34.          ' // ...we simply copy it to the string buffer...
  35.          MID$(strAscii, idx, 1) = MID$(strUtf8, idx, 1)
  36.          ' // ...and increase the position by 1.
  37.          idx = idx + 1
  38.       ELSEIF c < 224 THEN
  39.          ' // We need to join this byte and the next byte.
  40.          b2 = ASC(MID$(strUtf8, i + 1, 1))
  41.          IF b2 > 127 THEN
  42.             c = (c - 192) * 64 + (b2 - 128)
  43.             MID$(strAscii, idx, 1) = CHR$(c)
  44.             ' // Set the flag to skip the next character
  45.             fSkipChar = %TRUE
  46.             ' // Increase the position by 1.
  47.             idx = idx + 1
  48.          END IF
  49.       END IF
  50.    NEXT
  51.  
  52.    ' // Return the encoded string
  53.    FUNCTION = LEFT$(strAscii, idx - 1)
  54.  
  55. END FUNCTION



....


  strAnsiString = AsciiToUtf8("Проба";)
  ? UTF8ToAscii(strAnsiString)
----

оставь слово 'Проба' в HEX UTF8... посмотрю...

Ответить

Номер ответа: 5
Автор ответа:
 Lapex



Вопросов: 6
Ответов: 56
 Профиль | | #5 Добавлено: 09.01.09 18:54
Это я пробовал в первую очередь.
То, что этот пример прекрасно перегоняет в какую-то кодировку и извлекает назад строку ,без порчи, еще не говорит о том, что было кодирование в UTF-8.

Попробуй сохранить результат UTF8-кодирования в текстовый файл и посмотри его, например с помощью NotePad++, он умеет показывать текст в кодировке UTF-8. Текст будет не читабелен.
  1. DIM strUTF8 AS STRING
  2. strUTF8 = AsciiToUtf8("Проба")
  3.  
  4. OPEN "C:\utf-8.txt" FOR OUTPUT AS #1
  5. WRITE #1, strUTF8
  6. CLOSE #1

Ответить

Номер ответа: 6
Автор ответа:
 Kardinal



ICQ: 360041513 

Вопросов: 1
Ответов: 164
 Web-сайт: kg7.ru
 Профиль | | #6
Добавлено: 10.01.09 02:04
А обязательно использовать изложенный выше код? Можно просто перекодировать самому - будет понятней что происходит.
p.s. код "А" в утф=1090(из двух символов) преобразовывать в соотв. в анси

Ответить

Номер ответа: 7
Автор ответа:
 Lapex



Вопросов: 6
Ответов: 56
 Профиль | | #7 Добавлено: 10.01.09 12:49
А обязательно использовать изложенный выше код?

Нет, не обязательно, но хотелось бы с помощью API, т.к. будет возможность перегонять и в другие кодировки, да и скорость будет повыше IMHO.

P.S. извеняюсь за дизу в первом посте:
strAnsiString = "Р_С_Р_Р+Р°" ' ANSI строка в UTF-8 кодировке ("Проба";)
Строка "Проба" выглядит не так - ни с того файла скопировал. Да и вид строки привел только для примера, на самом деле строку беру из текстового файла. Но все равно нужного результата нет.

Ответить

Номер ответа: 8
Автор ответа:
 Lapex



Вопросов: 6
Ответов: 56
 Профиль | | #8 Добавлено: 10.01.09 20:44
Вообщеи удалось получить желаемый результат:
  1. FUNCTION AnsiToUtf8 (BYVAL S AS STRING) AS STRING
  2.   LOCAL Buffer AS STRING
  3.   LOCAL length AS LONG
  4.  
  5.   Buffer = SPACE$(LEN(S) * 2)
  6.   MultiByteToWideChar %CP_ACP, 0, BYVAL STRPTR (S), -1, BYVAL STRPTR(Buffer), LEN (Buffer)
  7.   S = Buffer
  8.   length = LEN (S)
  9.   Buffer = SPACE$(length)
  10.   WideCharToMultiByte %CP_UTF8, 0, BYVAL STRPTR (S), -1, BYVAL STRPTR (Buffer), LEN (Buffer), BYVAL (0), BYVAL (0)
  11.   FUNCTION = Buffer
  12. END FUNCTION
  13.  
  14. FUNCTION Utf8ToAnsi (BYVAL S AS STRING) AS STRING
  15.   LOCAL Buffer AS STRING
  16.   LOCAL length AS LONG
  17.  
  18.   Buffer = SPACE$(LEN(S) * 2)
  19.   MultiByteToWideChar %CP_UTF8, 0, BYVAL STRPTR (S), -1, BYVAL STRPTR (Buffer), LEN (Buffer)
  20.   S = Buffer
  21.   length = LEN (S)
  22.   Buffer = SPACE$(length)
  23.   WideCharToMultiByte %CP_ACP, 0, BYVAL STRPTR (S), -1, BYVAL STRPTR(Buffer), LEN(Buffer), BYVAL (0), BYVAL (0)
  24.   FUNCTION = Buffer
  25. END FUNCTION
  26.  
  27. FUNCTION PBMAIN () AS LONG
  28.   DIM S1 AS ASCIIZ * %MAXIMUM_REPARSE_DATA_BUFFER_SIZE
  29.   S1 = "Проба!"
  30.   S1 = AnsiToUtf8 (S1)
  31.   ? S1
  32.   S1 = Utf8ToAnsi(S1)
  33.   ? S1
  34. END FUNCTION

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам