Сохранение текста в файле UTF-8

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Alexey24
Начинающий
Начинающий
 
Сообщения: 7
Зарегистрирован: 20.09.2006 (Ср) 15:59

Сохранение текста в файле UTF-8

Сообщение Alexey24 » 20.09.2006 (Ср) 16:16

Поиск в течение 3 часов ничего не дал, потому - вопрос:

Я из VBA (Excel) хочу сохранить текст (это сгенерированные RSS новости своего сайта) в кодировке UTF-8.

>>
Dim theRssNews as String

theRssNews="<?xml version="1.0" encoding="utf-8"?>...

Open "rss.xml" for Output as #1
Print #1 theRssNews
Close #1
>>

Строка сохраняется в ANSI, и русские буквы в новостях становятся квадратиками.

Сохраняю через Print #1 StrConv(theRssNews, vbUnicode, &H419) и ставлю <?xml version="1.0" encoding="utf-16"?> для браузера, но всё равно в файле возникает лишний символ, который надо убирать вручную через Notepad.

Как сделать сохранение в UTF-8 (или уже пусть в UTF-16, но без этого "лишнего" символа)?

Debugger
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1667
Зарегистрирован: 17.06.2006 (Сб) 15:11

Сообщение Debugger » 20.09.2006 (Ср) 16:31

Пише через FSO. Лишний символ - это и есть особенность Print :D

Alexanbar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1727
Зарегистрирован: 13.04.2004 (Вт) 23:04
Откуда: Волгоградская обл.

Сообщение Alexanbar » 20.09.2006 (Ср) 16:34

Код: Выделить всё
Public Function WinToUTF8(ByRef inString As String) As String
Dim res As Long
Dim UTF8Buffer() As Byte
Dim UTF16Buffer() As Integer
Dim length As Long
Dim Uc$

length = Len(inString)
If length = 0 Then Exit Function

ReDim UTF16Buffer(0 To length + 1) As Integer
CopyMemory UTF16Buffer(0), ByVal StrPtr(inString), length * 2
'

' First, find out how big a UTF8 buffer we need:
res = WideCharToMultiByte(CP_UTF8, 0, UTF16Buffer(LBound(UTF16Buffer)), length, 0, 0, vbNullString, 0)
If res = 0 Then Exit Function

' OK, now do the conversion:
ReDim UTF8Buffer(0 To res - 1)
res = WideCharToMultiByte(CP_UTF8, 0, UTF16Buffer(LBound(UTF16Buffer)), length, UTF8Buffer(0), res, vbNullString, 0)
If res = 0 Then Exit Function

' I never got this far in the function to see if this works correctly...
WinToUTF8 = StrConv(UTF8Buffer, vbUnicode)
End Function

Alexey24
Начинающий
Начинающий
 
Сообщения: 7
Зарегистрирован: 20.09.2006 (Ср) 15:59

UTF-8

Сообщение Alexey24 » 20.09.2006 (Ср) 17:40

Предложенное UTF преобразование "теряет" русские буквы. Я ещё порылся в Интернете на англоязычных форумах - все подобные преобразования дают "абракадабру" вместо русского.

Совет о FSO - работает и последний символ изчез. Но! теперь мой rss.xml читает только FireFox, а парсер IE его не берёт...

Ну блин

Alexanbar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1727
Зарегистрирован: 13.04.2004 (Вт) 23:04
Откуда: Волгоградская обл.

Сообщение Alexanbar » 20.09.2006 (Ср) 18:53

похоже, не тот кусок дал
Код: Выделить всё
Public Function UTF8ToWin(ByRef inString As String) As String

Dim iStrSize    As Long
Dim Uc As String
If Len(inString) = 0 Then Exit Function
'iStrSize& = MultiByteToWideChar(CP_UTF8, 0&, inString, &HFFFF, UTF8ToWin, 0)
iStrSize& = MultiByteToWideChar(CP_UTF8, 0&, inString, &HFFFF, Uc, 0)
If Len(iStrSize) Then
     Uc = String$(iStrSize * 2, 0&)
     Call MultiByteToWideChar(CP_UTF8, 0&, inString, &HFFFF, Uc, iStrSize)
     UTF8ToWin = StrConv(Uc, vbFromUnicode)
End If
End Function

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 20.09.2006 (Ср) 19:21

Debugger писал(а):Лишний символ - это и есть особенность Print :D

...когда руки кривые.
Точку с запятой надо ставить.
Lasciate ogni speranza, voi ch'entrate.

Alexey24
Начинающий
Начинающий
 
Сообщения: 7
Зарегистрирован: 20.09.2006 (Ср) 15:59

Сообщение Alexey24 » 20.09.2006 (Ср) 21:41

Думаю, что первый код был правильный...

А вот о "руках". Так это уж точно, т.к. я поставил ";" и сразу избавился от проблем с лишним символом. Спасибо!

Но UTF-8 проблема всё-таки не закрыта.

В благодарность всем VB-профи за совет хочу поделиться ссылкой (про-пиарюсь) на GUI для regsvr32. Называется Xmployer, успешно пользуюсь для dll, ocx, ActiveX exe во время частіх build'ов оных.

Ну, чем сам богат...

http://wissenhafen.narod.ru/soft/download_r.htm

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 20.09.2006 (Ср) 21:46

Можно нескромный вопрос... а зачем regsvr GUI? Если можно создать очень маленький текстовый файл с раширением reg, запустить его один раз, после чего в контекстном меню всех exe, ocx и dll появятся пункты register и unregister?
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Matew
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 894
Зарегистрирован: 28.06.2004 (Пн) 17:44
Откуда: Дальний Восток, г. Ха

Сообщение Matew » 21.09.2006 (Чт) 4:46

GSerg, поделись, плиз...
Алкоголь и сканеры-ваши враги! Не верите-смотрите аватару :-)

Alexey24
Начинающий
Начинающий
 
Сообщения: 7
Зарегистрирован: 20.09.2006 (Ср) 15:59

Сообщение Alexey24 » 21.09.2006 (Чт) 7:54

Согласен, можно и через контекстное меню. Но у меня (как и многих) контекстное .default меню уже и так полно всякими "удобствами". Получается длиною в аршин. Даже если элементы и вложенные.

Поэтому я сделал через Drag-n-Drop. Кроме того сразу индицируется версия контрола и есть выбор регить/анрегить в разных папках.

Другими словами - _мне_так_удобнее_.

P.S. О UTF-16.

Оказывается IE не хочет воспринимать XML в Юникоде, если нет заголовка файла "ÿþ" (или FFFE).
>>
Print #1, "ÿþ"; StrConv(strRSS, vbUnicode, &H419);
>>

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 21.09.2006 (Чт) 7:58

VB не умеет работать с UTF.
Поэтому либо вообще никак не модифицируй получаемый текст (без всяких StrConv), пиши в файл то, что получил.
Либо перекодируй вручную, как показал Alexanbar.
FFFE это не волшебное заклинание, это стандартная метка для Unicode-файлов. Иногда используется FEFF.
Lasciate ogni speranza, voi ch'entrate.

CodeName33
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 297
Зарегистрирован: 01.09.2004 (Ср) 13:25
Откуда: SPb

Сообщение CodeName33 » 21.09.2006 (Чт) 8:37

Если только русские символы нужно перекодировать в UTF8, то я использую вот это:

Код: Выделить всё
Public Function ToUTF8(Text As String) As String
Dim i As Long, IC As Long

IC = Len(Text)
For i = 1 To IC
  ToUTF8 = ToUTF8 & ConvertToUTF8(Mid$(Text, i, 1))
Next
End Function

Private Function ConvertToUTF8(Char As String) As String
If Char = "Ё" Then
  ConvertToUTF8 = Chr$(208) & Chr$(129)
ElseIf Char = "ё" Then
  ConvertToUTF8 = Chr$(209) & Chr$(145)
ElseIf (Asc(Char) >= 192 And Asc(Char) <= 223) Then
  ConvertToUTF8 = Chr$(208) & Chr$(Asc(Char) - 48)
ElseIf (Asc(Char) >= 224 And Asc(Char) <= 239) Then
  ConvertToUTF8 = Chr$(208) & Chr$(Asc(Char) - 48)
ElseIf (Asc(Char) >= 240 And Asc(Char) <= 255) Then
  ConvertToUTF8 = Chr$(209) & Chr$(Asc(Char) - 112)
Else
  ConvertToUTF8 = Char
End If
End Function


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

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 21.09.2006 (Чт) 9:28

alibek писал(а):FFFE это не волшебное заклинание, это стандартная метка для Unicode-файлов. Иногда используется FEFF.

Это один и тот же символ, только при разном порядке байтов в слове.
Изображение

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 21.09.2006 (Чт) 10:29

Matew писал(а):GSerg, поделись, плиз...
Вложения
NewRegsvr.zip
Регистрация RegSvr32 и regtlib
(974 байт) Скачиваний: 131
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 115

    TopList