Как назначить кодировку при создании текстового файла?

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

Как назначить кодировку при создании текстового файла?

Сообщение Lotreck » 19.05.2008 (Пн) 7:24

Оператор Open:
Код: Выделить всё
Open filename For mode As fileno

создает файлы в ASII кодировке. Каким образом создать файл в Unicode кодировке?

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

Сообщение alibek » 19.05.2008 (Пн) 8:22

Никак. У самих файлов нет никакой кодировки, она имеет смысл только в используемых программах.
Конкретно с Unicode все довольно просто, в памяти VB6 все строки и так хранит, как Unicode. Тебе достаточно создать байтовый массив подходящего размера, скастовать в него твою строку, затем открыть файл для прямого доступа (For Binary), сохранить в него 0xFFFE, а затем вывести байтовый массив.
В случае с другими кодировками тебе надо будет преобразовать текст, что вообщем тоже не сложно, есть готовые API-функции.
Lasciate ogni speranza, voi ch'entrate.

Денис
Доктор VB наук
Доктор VB наук
Аватара пользователя
 
Сообщения: 2734
Зарегистрирован: 07.11.2006 (Вт) 13:55
Откуда: Ейск, Краснодарский край

Сообщение Денис » 19.05.2008 (Пн) 8:25

Ну вы же уже разобрались с юникодом здесь
http://bbs.vbstreets.ru/viewtopic.php?t=36270
теперь просто выводите данные в файл побайтно. :scratch:
__

Ну да, и 0xFFFE не забыть, как я. 0xFFFE - это FF и FE, тоесть "яю". На самом деле это не буквы я и ю, а признак текста в юникоде, тоже юникодный символ.
Программирование — богоизбранная дисциплина! Если бог и есть, то вселенную он скомпилировал, не иначе.

Lotreck
Обычный пользователь
Обычный пользователь
 
Сообщения: 69
Зарегистрирован: 19.03.2008 (Ср) 14:59

Сообщение Lotreck » 19.05.2008 (Пн) 9:36

Я так и делаю. Но файл создается в ANSII и вводимые данные нормально не отображает. Чтобы этого не происходило приходится уже после создания файла и занесения первой записи, вручную заходить в блокнот , удалять запись, менять кодировку на Unicode. Только потом отображение вводимых данных становится нормальным.

Код: Выделить всё
Private Sub Form_Load()
   FontName = "Verdana"
End Sub
Private Sub Form_Click()
Dim z As String
Dim s As String
Dim v As String
Dim f() As Byte
Dim b() As Byte
   ReDim f(1)
   f(0) = &H10
   f(1) = &H1
   z = StrConv(f, vbUnicode)
   ReDim b(1)
   b(0) = &H66
   b(1) = &H1
   s = StrConv(b, vbUnicode)
   v = s + z + s + z + z + s + s
   Open "c:\Unicode.txt" For Binary As #1
   Put #1, , v
  Close #1
End Sub

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

Сообщение alibek » 19.05.2008 (Пн) 9:54

Ты сделал противоположное тому, что я написал.
Код: Выделить всё
Dim buff() As Byte, tag() As Byte, S As String
ReDim tag(0 to 1)
tag(0) = 255
tag(1) = 254
S = "sample text"
ReDim buff(0 To LenB(S)-1)
buff = S
Open "..." For Binary As #1
Put #1, tag
Put #1, buff
Close #1
Lasciate ogni speranza, voi ch'entrate.

Lotreck
Обычный пользователь
Обычный пользователь
 
Сообщения: 69
Зарегистрирован: 19.03.2008 (Ср) 14:59

Сообщение Lotreck » 19.05.2008 (Пн) 10:42

А как быть с символами чей код превышает 255, ваш пример с ними не работает.

Денис
Доктор VB наук
Доктор VB наук
Аватара пользователя
 
Сообщения: 2734
Зарегистрирован: 07.11.2006 (Вт) 13:55
Откуда: Ейск, Краснодарский край

Сообщение Денис » 19.05.2008 (Пн) 12:19

Lotreck
Покажите код, как Вы вносили символы юникода чей код превышает 255 в переменную buff?
___________

(у меня все работает)
Последний раз редактировалось Денис 19.05.2008 (Пн) 12:40, всего редактировалось 1 раз.
Программирование — богоизбранная дисциплина! Если бог и есть, то вселенную он скомпилировал, не иначе.

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

Сообщение alibek » 19.05.2008 (Пн) 12:22

Lotreck писал(а):А как быть с символами чей код превышает 255, ваш пример с ними не работает.

А ты вначале разберись в работе кода, прежде чем глупости говорить.
Lasciate ogni speranza, voi ch'entrate.

ALX_2002
Мега гуру
Мега гуру
 
Сообщения: 2054
Зарегистрирован: 25.11.2002 (Пн) 20:03

Сообщение ALX_2002 » 19.05.2008 (Пн) 12:34

Код: Выделить всё

Set Stream = CreateObject("ADODB.Stream")
Stream.Open
Stream.Type = 2
Stream.Charset = "UTF-8"
Stream.WriteText "Произвольный текст"
Stream.SaveToFile "C:\1.txt",2


А так не пойдёт ? :) Так можно указывать необходимую кодировку при сохранении.

Lotreck
Обычный пользователь
Обычный пользователь
 
Сообщения: 69
Зарегистрирован: 19.03.2008 (Ср) 14:59

Сообщение Lotreck » 19.05.2008 (Пн) 13:47

При загрузке формы создается файл UU.txt в него вносится запись состоящая из символов с кодами U+0110 и U+0166 взятыми из таблицы символов. Файл создается нормально можно посмотреть запись. По команде кнопки запись из UU.txt заносится в переменную A и затем присваивается переменной s. Дальше ваш код.

Код: Выделить всё
Private Sub Command1_Click()
Dim buff() As Byte, tag() As Byte, s As String
Dim A As String
Open "c:\UU.txt" For Input As #2
Do Until EOF(2)
Line Input #2, A
Loop
Close #2
ReDim tag(0 To 1)
tag(0) = 255
tag(1) = 254
s = A
ReDim buff(0 To LenB(s) - 1)
's = A
buff = s
Open "c:\Unicode.txt" For Binary As #1
Put #1, , tag
Put #1, , buff
Close #1
End Sub

Private Sub Form_Load()
FontName = "Verdana"
Dim z As String
Dim k As String
Dim v As String
Dim f() As Byte
Dim b() As Byte
ReDim f(1)
f(0) = &H10
f(1) = &H1
z = StrConv(f, vbUnicode)
ReDim b(1)
b(0) = &H66
b(1) = &H1
k = StrConv(b, vbUnicode)
v = k + z + k + z + k + z
Open "c:\UU.txt" For Binary As #1
Put #1, , v
Close #1
End Sub

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

Сообщение alibek » 19.05.2008 (Пн) 13:54

Lotreck, ты опять не понял.
Lasciate ogni speranza, voi ch'entrate.

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Сообщение Andrey Fedorov » 19.05.2008 (Пн) 13:59

Из Help-а:

Код: Выделить всё
   Dim fso, MyFile
   Set fso = CreateObject("Scripting.FileSystemObject")
   Set MyFile = fso.CreateTextFile("c:\testfile.txt", True, True)
   MyFile.WriteLine("This is a test.")
   MyFile.Close


То бишь третий параметр CreateTextFile...

P.S
Надо сказать что в данном случае первые два байта файла - признак того что файл сохранен в уенкоде. В случае если просто сбрасывать массив байт, то их нет...
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

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

Сообщение alibek » 19.05.2008 (Пн) 14:46

Andrey Fedorov писал(а):Надо сказать что в данном случае первые два байта файла - признак того что файл сохранен в уенкоде.

Не совсем. Это в первую очередь указатель, в каком порядке идут байты, в прямом или обратном. Ну и заодно указатель, что файл является юникодным.
Lasciate ogni speranza, voi ch'entrate.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 20.05.2008 (Вт) 5:39

В уникоде на каждую букву два байта. В бейсике в строковых переменных - как ни странно, тоже два байта на букву. А вот при сохранении в файл бейсик преобразует страку так, чтобы на каждую букву приходилось по одному байту. Поэтому, чтобы не потерять всю юникодную красату, нужно сохранять не строки, а байтовые массивы.

Байтовые массивы и строку внутри себя устроены одинаково. Поэтому байтовому массиву можно напрямую присваивать строку и наоборот - ни каких преобразований при этом не происходит.

А с уникодом, мы же действительно уже разобрались раньше:
Выведим что-нибудь чисто конкретно на греческом. Например, ΏΞΘ
Смотрим коды в таблице:
038f
039e
0398
Собираем в кучу:
Код: Выделить всё

dim s as string,b() as byte
s=chrw(&hfeff) 'признак уникода
s=s &  chrw(&h038f) & chrw(&h039e) & chrw (&h0398)

b=s 'присваиваем строку массиву байтов (чтобы не растерять уникод)

Open "c:\UU.txt" For Binary As #1
Put #1, , b
Close #1


Осталось найти грека, чтобы перевёл.

v = k + z + k + z + k + z
Не складывай строки плюсами. Пиши всместо плюса &
Артур
 
   

Lotreck
Обычный пользователь
Обычный пользователь
 
Сообщения: 69
Зарегистрирован: 19.03.2008 (Ср) 14:59

Сообщение Lotreck » 20.05.2008 (Вт) 6:31

arthur2 подскажите пока вы здесь, может быть я вообще не в ту сторону двигаюсь. При печати текста необходимо было постоянно использовать около десятка юникодовских символов, чтобы не лазить каждый раз в таблицу символов, заменил их комбинациями обычных букв. Когда текст был готов попытался программно заменить эти комбинации на соответствующие им юникодовские знаки с помощью Replace. Юникодовские символы вводил в переменную по предложенному Вами варианту. Когда не получилось я предположил что это возможно от несовпадения кодировок файла и вводимого текста, больше нечего в голову не пришло, так собственно возник этот вопрос. Если есть какие-нибудь идеи решения проблемы с заменой подскажите.

Денис
Доктор VB наук
Доктор VB наук
Аватара пользователя
 
Сообщения: 2734
Зарегистрирован: 07.11.2006 (Вт) 13:55
Откуда: Ейск, Краснодарский край

Сообщение Денис » 20.05.2008 (Вт) 8:12

Ну, все как всегда. Столкнемся с проблемой, придумаем кривое решение, а потом лезем на форум за помощью в реализации корявого решения.

1. При печати текста - ГДЕ? (Редактор вообще поддерживает юникод?)
2. Программно заменить - зачем? (ведь есть Ctrl+H (Ctrl+R)
Программирование — богоизбранная дисциплина! Если бог и есть, то вселенную он скомпилировал, не иначе.

Lotreck
Обычный пользователь
Обычный пользователь
 
Сообщения: 69
Зарегистрирован: 19.03.2008 (Ср) 14:59

Сообщение Lotreck » 20.05.2008 (Вт) 8:40

Текст набирался в блокноте. Насчет второго пункта не понял о чем идет речь, разъясните если нетрудно.

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

Сообщение alibek » 20.05.2008 (Вт) 8:43

Lotreck, опиши свою задачу. Не то, как ты ее делаешь, а то, что нужно сделать.
Lasciate ogni speranza, voi ch'entrate.

Lotreck
Обычный пользователь
Обычный пользователь
 
Сообщения: 69
Зарегистрирован: 19.03.2008 (Ср) 14:59

Сообщение Lotreck » 20.05.2008 (Вт) 9:23

Я уже говорил об этом. Печатается текст содержащий различные символы, вроде ⅝, ↺, ↻,∠,√ , всего около пятнадцати видов, текст довольно большой и общее количесто этих символов тоже, за тысячу.
Чтобы не отрываться на копирование каждого символа отдельно я их при печатании заменял другими знаками, ⅝ на 11, ↺ на 22, и так далее. Теперь когда текст готов нужно зделать обратную замену.

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

Сообщение alibek » 20.05.2008 (Вт) 10:19

Я спрашивал не об этом.
Что вообще нужно сделать? Замена символов не является самоцелью.
Lasciate ogni speranza, voi ch'entrate.

Lotreck
Обычный пользователь
Обычный пользователь
 
Сообщения: 69
Зарегистрирован: 19.03.2008 (Ср) 14:59

Сообщение Lotreck » 20.05.2008 (Вт) 11:47

Не знаю как еще объяснить. Нужно напечатать в блокноте текст содержащий символы отстутствующие на клавиатуре,подмена символов используется как прием ускоряющий печать.
Способ который предложил Денис работает только в том случае если заменяемое слово того шрифта что и остальной текст. Если этот шрифт не содержит нужного символа, и приходится вводить из другого шрифта то оно не отображается.

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

Сообщение alibek » 20.05.2008 (Вт) 12:09

Если ты не умеешь формулировать задачу, это не значит, что она именно такая и есть.
Какова цель? Создать текстовый файл в Unicode, содержащий определенные символы?
Если я правильно понял, у тебя уже есть текстовый файл в Unicode, но в нем последовательности символов надо заменить на unicode-символы? Такое возможно только если изначально был выбран кривой способ решения задачи.
Тем не менее, можно делать примерно так:
Код: Выделить всё
Dim tag() As Byte, buff() As Byte, N As Long, S As String
Open ... For Binary As #1
Seek #1, 1
ReDim tag(0 To 1)
Get #1, , tag
N = LOF(1) - 2
ReDim buff(0 To N-1)
Get #1, , buff
S = buff
S = Replace$(S, "11", ChrW$(...))
S = Replace$(S, "12", ChrW$(...))
...
S = Replace$(S, "99", ChrW$(...))
buff = S
Seek #1, 1
Put #1, , tag
Put #1, , buff
Close #1

Синтаксис Seek, Get и Put лучше уточни по справке, я писал прямо тут, мог где-то ошибиться.
Lasciate ogni speranza, voi ch'entrate.

Денис
Доктор VB наук
Доктор VB наук
Аватара пользователя
 
Сообщения: 2734
Зарегистрирован: 07.11.2006 (Вт) 13:55
Откуда: Ейск, Краснодарский край

Сообщение Денис » 20.05.2008 (Вт) 13:03

Блокнот эт, конечно, круто, не спорю.

... Но в ворде автозамена юникодных символов делается в один присест
Программирование — богоизбранная дисциплина! Если бог и есть, то вселенную он скомпилировал, не иначе.

Lotreck
Обычный пользователь
Обычный пользователь
 
Сообщения: 69
Зарегистрирован: 19.03.2008 (Ср) 14:59

Сообщение Lotreck » 20.05.2008 (Вт) 13:06

Каким на Ваш взгляд мог бы быть не "кривой" способ решения задачи? На будущее.

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

Сообщение alibek » 20.05.2008 (Вт) 13:21

Чтобы со способом решения определиться, надо вначале знать, что вообще требуется.
Если нужно набрать в блокноте текст с Unicode-символами, то тут вообще ничего делать не надо, достаточно было изначально вводить те символы, которые требуются. Чтобы упростить их ввод, можно пользоваться более функциональным редактором, который позволит вводить специальные символы нажатием одной кнопки (за отсутствием, к примеру, EditPlus или UltraEdit можно использовать хоть Word).
Замена этих символов на какие-то последовательности с дальнейшем заменой их обратно — сама по себе порочна, если только для этого нет других причин, помимо неудобства ввода с клавиатуры.
Lasciate ogni speranza, voi ch'entrate.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 20.05.2008 (Вт) 15:47

необходимо было постоянно использовать около десятка юникодовских символов

Вообще, трудно понять конкретно. но мне кажется, что ты в ANSII-строке пытаешься только некоторые символы сделать уникодными. Уникодной должна быть вся строка. В том числе и латиница.

Юникодовские символы вводил в переменную по предложенному Вами варианту
Есил как в процетированном коде - то это был вариант, первым пришедший в голову и довольно корявый. Ниже в том топике мы добрались до более удобного и правильного - как выяснилось, chrw() нормально работает.

Ты хочешь в своей программе печатать уникодом? Или тебе подходит сделать уникодный файл чем угодно, но чтобы потом его читать? Если второе - пиши в водре. Там и автозамена нормально работает, и просто замена. Потом сохраняй в тхт в юникод.

Если первое - то это задача нетревиальная. Но с ней вполне справляется тот контрол, который я выложил тебе в конце того топика.

Ещё в чём может быть проблема: строка набрана по-русски? юникодные знаки для русских букв далеко не совпадают с их Acs. Тебе нужно и их заменять. Вряд ли это будет очень просто, так что если текст уже набран, чтобы ему не пропадать, отредактируй его в ворде.
Артур
 
   

Lotreck
Обычный пользователь
Обычный пользователь
 
Сообщения: 69
Зарегистрирован: 19.03.2008 (Ср) 14:59

Сообщение Lotreck » 20.05.2008 (Вт) 22:28

Благодарю всех откликнувшихся за помощь.


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

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

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

    TopList