purebasic.info

PureBasic forum
Текущее время: Пн июн 18, 2018 8:16 am

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 48 ]  На страницу Пред.  1, 2, 3, 4  След.
Автор Сообщение
 Заголовок сообщения: Re: PokeS и PeekS с флагом #PB_UTF8
СообщениеДобавлено: Вс июн 26, 2016 10:42 pm 
Не в сети
доцент

Зарегистрирован: Чт июн 23, 2016 8:15 pm
Сообщений: 31
Благодарил (а): 0 раз.
Поблагодарили: 4 раз.
Пункты репутации: 0
Сергейчик писал(а):
Ну будет буфер с нулями и что это как то повлияет на строку и программу в дальнейшем?

Зачем выделять буфер больше, чем требуется? Я действительно не понимаю. Вместо StringByteLength(string.s, #PB_Unicode) достаточно выделить StringByteLength(string.s, #PB_UTF8) или еще +1 при записи нуля в конце строки. И ни байта больше. А то давайте тогда уж мегабайт выделим под буфер, условившись, что строки больше мегабайта использоваться не будут. Пусть будет "буфер с нулями", памяти сейчас у всех много, мегабайт туда, мегабайт сюда - какая разница? Заодно сэкономим несколько строк исходного кода и несколько сот байтов программы на вычислении длины строки и размера буфера.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: PokeS и PeekS с флагом #PB_UTF8
СообщениеДобавлено: Пн июн 27, 2016 2:20 am 
Не в сети
профессор

Зарегистрирован: Пн июл 22, 2013 11:00 pm
Сообщений: 570
Благодарил (а): 2 раз.
Поблагодарили: 32 раз.
Пункты репутации: 9
puric писал(а):
Сергейчик писал(а):
Ну будет буфер с нулями и что это как то повлияет на строку и программу в дальнейшем?

Зачем выделять буфер больше, чем требуется? Я действительно не понимаю. Вместо StringByteLength(string.s, #PB_Unicode) достаточно выделить StringByteLength(string.s, #PB_UTF8) или еще +1 при записи нуля в конце строки. И ни байта больше. А то давайте тогда уж мегабайт выделим под буфер, условившись, что строки больше мегабайта использоваться не будут. Пусть будет "буфер с нулями", памяти сейчас у всех много, мегабайт туда, мегабайт сюда - какая разница? Заодно сэкономим несколько строк исходного кода и несколько сот байтов программы на вычислении длины строки и размера буфера.

Функция StringByteLength(string.s, #PB_UTF8) считает байты в строке с определённой кодировкой а не так что исходная строка ucs-2 и нужно посчитать сколько понадобится байт для utf8 :D


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: PokeS и PeekS с флагом #PB_UTF8
СообщениеДобавлено: Пн июн 27, 2016 10:13 am 
Не в сети
доцент

Зарегистрирован: Чт июн 23, 2016 8:15 pm
Сообщений: 31
Благодарил (а): 0 раз.
Поблагодарили: 4 раз.
Пункты репутации: 0
Сергейчик писал(а):
Нет, ну можно конечно написать процедуру len чтобы считала сколько нужно выделить байт под utf8 из строки ucs-2.
или наоборот для ucs-2 из utf8.

При чем тут utf-8 vs. ucs-2 и vice versa? Кодировка, в которой эта строка хранится в сегменте данных, нас вообще не волнует; StringByteLength считает размер строки в байтах в целевой кодировке - именно тот объем, который строка займет в куче, вне зависимости от использованной кодировки исходного кода и от режима компиляции (Ascii/Unicode).

Вот вы тоже для чего-то предложили использовать buff_size.i = StringByteLength(string.s, #PB_Unicode). Почему #PB_Unicode, если мы используем UTF-8? Да, оно работает и так. В нашем конкретном примере. Но это потенциальный источник ошибок. Ну а память экономить нам как бы незачем, что такое эти 30 байтов, когда на дворе XXI век, а в кармане почти у каждого телефон с 2 Гб оперативной памяти. :D


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: PokeS и PeekS с флагом #PB_UTF8
СообщениеДобавлено: Пн июн 27, 2016 4:39 pm 
Не в сети
профессор

Зарегистрирован: Пн июл 22, 2013 11:00 pm
Сообщений: 570
Благодарил (а): 2 раз.
Поблагодарили: 32 раз.
Пункты репутации: 9
puric писал(а):
Сергейчик писал(а):
Нет, ну можно конечно написать процедуру len чтобы считала сколько нужно выделить байт под utf8 из строки ucs-2.
или наоборот для ucs-2 из utf8.

При чем тут utf-8 vs. ucs-2 и vice versa? Кодировка, в которой эта строка хранится в сегменте данных, нас вообще не волнует; StringByteLength считает размер строки в байтах в целевой кодировке - именно тот объем, который строка займет в куче, вне зависимости от использованной кодировки исходного кода и от режима компиляции (Ascii/Unicode).

Вот вы тоже для чего-то предложили использовать buff_size.i = StringByteLength(string.s, #PB_Unicode). Почему #PB_Unicode, если мы используем UTF-8? Да, оно работает и так. В нашем конкретном примере. Но это потенциальный источник ошибок. Ну а память экономить нам как бы незачем, что такое эти 30 байтов, когда на дворе XXI век, а в кармане почти у каждого телефон с 2 Гб оперативной памяти. :D

То то и оно что исходная строка в ucs-2 и StringByteLength если и имеет различные флаги для кодировок то это отнюдь не говорит что подсчитывая байты в исходной строке ucs-2 ,(как сам выразился будь она где угодно) с другими флагами для кодировок подсчитает нужный результат. :D
Поэтому и написал что нужна спец функция типа смотрим ucs-2 а подсчёт байтов ведём не для неё а для другой предпологаемой кодировки,того же utf8 ,так понятно :?:


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: PokeS и PeekS с флагом #PB_UTF8
СообщениеДобавлено: Пн июн 27, 2016 7:39 pm 
Не в сети
доцент

Зарегистрирован: Чт июн 23, 2016 8:15 pm
Сообщений: 31
Благодарил (а): 0 раз.
Поблагодарили: 4 раз.
Пункты репутации: 0
StringByteLength вычисляет байтовую длину строки в УКАЗАННОЙ кодировке. Что ее попросите показать, то она и покажет. В каком виде хранится исходная строка в коде программы - Ascii или Unicode - роли не играет. Также на результат не влияет и кодировка файла-исходника, будь то Ascii или UTF-8. Эта функция корректно отрабатывает во всех возможных режимах и нам не надо изобретать велосипед. В данном примере следует использовать ее с флагом #PB_UTF8. Во-первых, это гарантирует результат, во-вторых, улучшает читаемость и понятность программы: сразу видно, что нас интересует длина строки именно в этой кодировке и именно ее мы собираемся использовать при записи в память функцией PokeS. А то давайте тогда использовать "магические числа": buff_size = 2 * Len(string) - и потом будем ломать голову, почему выделили удвоенную длину строки, а не утроенную или учетверенную. Читаемость исходного кода от таких фокусов резко падает, хоть программа и сохраняет работоспособность.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: PokeS и PeekS с флагом #PB_UTF8
СообщениеДобавлено: Пн июн 27, 2016 11:12 pm 
Не в сети
профессор

Зарегистрирован: Пн июл 22, 2013 11:00 pm
Сообщений: 570
Благодарил (а): 2 раз.
Поблагодарили: 32 раз.
Пункты репутации: 9
puric писал(а):
StringByteLength вычисляет байтовую длину строки в УКАЗАННОЙ кодировке. Что ее попросите показать, то она и покажет. В каком виде хранится исходная строка в коде программы - Ascii или Unicode - роли не играет. Также на результат не влияет и кодировка файла-исходника, будь то Ascii или UTF-8. Эта функция корректно отрабатывает во всех возможных режимах и нам не надо изобретать велосипед. В данном примере следует использовать ее с флагом #PB_UTF8. Во-первых, это гарантирует результат, во-вторых, улучшает читаемость и понятность программы: сразу видно, что нас интересует длина строки именно в этой кодировке и именно ее мы собираемся использовать при записи в память функцией PokeS. А то давайте тогда использовать "магические числа": buff_size = 2 * Len(string) - и потом будем ломать голову, почему выделили удвоенную длину строки, а не утроенную или учетверенную. Читаемость исходного кода от таких фокусов резко падает, хоть программа и сохраняет работоспособность.

Не обнадеживайся по поводу исходной строки и файла кодировки...
Вот код где строка ucs-2 и вроде бы да StringByteLength правильно считает что если переводить из 2-х байт ucs-2 в utf8 будет уже по 3 байта,а вот если строка ascii с 12 байтами то зачем в utf8 18 байт?
Код:
1
2
3
4
5
6
7
8
9
10
 
Global string_ucs.s = Chr($263A)+Chr($263A)+Chr($263A)+Chr($263A)+Chr($263A)+Chr($263A);Строка ucs-2 12 bait 6 символов
Global string_ascii.s=Chr($263A)+Chr($263A)+Chr($263A)+Chr($263A)+Chr($263A)+Chr($263A)
PokeS(@string_ascii,string_ucs,12,#PB_Ascii);ASCII 12 символов
 
Debug string_ucs
Debug string_ascii
Debug StringByteLength(string_ucs, #PB_UTF8)
Debug StringByteLength(string_ascii, #PB_UTF8)
 



Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: PokeS и PeekS с флагом #PB_UTF8
СообщениеДобавлено: Вт июн 28, 2016 10:24 am 
Не в сети
доцент

Зарегистрирован: Чт июн 23, 2016 8:15 pm
Сообщений: 31
Благодарил (а): 0 раз.
Поблагодарили: 4 раз.
Пункты репутации: 0
Сергейчик, вы прикалываетесь? Какая же она Ascii, когда вы в нее напихали иероглифов из исходной Unicode (вы ведь идете в ногу со временем, не так ли?)? Более того, записали терминирующий строку нуль (один!), который в режиме компиляции Unicode за конец строки не считается и чудесным образом склеивается с остатком исходной Unicode-строки (исходная строка была 12 байт, функцией PokeS вы записали 6 байт строки и один нолик, а еще 5 байт никуда не делись). Стоит перед PokeS затереть нулями буфер, как StringByteLength(string_ascii, #PB_UTF8) "чудесным образом" показывает правильное значение - 9 (три раза по $4F4F в кодировке Unicode - это три символа по три байта в режиме UTF-8).


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: PokeS и PeekS с флагом #PB_UTF8
СообщениеДобавлено: Вт июн 28, 2016 11:24 am 
Не в сети
доцент

Зарегистрирован: Чт июн 23, 2016 8:15 pm
Сообщений: 31
Благодарил (а): 0 раз.
Поблагодарили: 4 раз.
Пункты репутации: 0
Да, а зато ваша строка символов $263A отлично демонстрирует пагубность предложения уч. MrF вычислять размер буфера с флагом #PB_Unicode вместо #PB_UTF-8. Буфер под нее нужен длиной 18 байт, выделяется всего 12, но записываются (реально записываются в память!) все 18. Русская рулетка в действии - никогда заранее не угадаешь, что будет затерто.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: PokeS и PeekS с флагом #PB_UTF8
СообщениеДобавлено: Пн мар 26, 2018 12:29 pm 
Не в сети
профессор

Зарегистрирован: Сб фев 06, 2016 6:18 pm
Сообщений: 259
Благодарил (а): 14 раз.
Поблагодарили: 29 раз.
Пункты репутации: 0
Winows 10 добавляет бяку, на XP такого не наблюдается. Была мысля отсеять через Case а может есть что проще? :roll:

Изображение
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
string.s = PeekS(?utf_8, -1, #PB_UTF8)
len.i = StringByteLength(string, #PB_UTF8)
 
For i = 0 To len
  TextUnicode.u = PeekU(?utf_8+i)
  Text.s + PeekS(@TextUnicode, 1, #PB_UTF8)
Next i
 
Debug Text
 
 
DataSection
  utf_8:
  Data.a        $D0, $AD, $D1, $82, $D0, $B0, $20, $D1, $81, $D1, $82, $D1, $80, $D0, $BE, $D0
  Data.a        $BA, $D0, $B0, $20, $D0, $B2, $20, $D1, $84, $D0, $BE, $D1, $80, $D0, $BC, $D0
  Data.a        $B0, $D1, $82, $D0, $B5, $20, $55, $54, $46, $2D, $38, $0
EndDataSection


P.S. PeekS(?utf_8, -1, #PB_UTF8) не подходит ибо нужен каждый символ. DataSection в качестве примера.


Вложения:
Win 10.jpeg [24.54 KiB]
Скачиваний: 0
Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: PokeS и PeekS с флагом #PB_UTF8
СообщениеДобавлено: Пн мар 26, 2018 12:51 pm 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11178
Благодарил (а): 4 раз.
Поблагодарили: 414 раз.
В #PB_UTF8 символ может занимать больше одного байта. https://ru.wikipedia.org/wiki/UTF-8
Цитата:
UTF-8 (от англ. Unicode Transformation Format, 8-bit — «формат преобразования Юникода, 8-бит») — распространённый стандарт кодирования текста, позволяющий более компактно хранить и передавать символы Юникода, используя переменное количество байт (от 1 до 4), и обеспечивающий полную обратную совместимость с 7-битной кодировкой ASCII.

_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: PokeS и PeekS с флагом #PB_UTF8
СообщениеДобавлено: Пн мар 26, 2018 1:42 pm 
Не в сети
профессор

Зарегистрирован: Сб фев 06, 2016 6:18 pm
Сообщений: 259
Благодарил (а): 14 раз.
Поблагодарили: 29 раз.
Пункты репутации: 0
Пётр писал(а):
В #PB_UTF8 символ может занимать больше одного байта.
Почему на XP работает то? :) Пробую так:
Код:
1
2
3
4
5
For i = 0 To len
  TextUnicode.u = PeekU(?utf_8+i)
  len2.i = StringByteLength(Chr(TextUnicode), #PB_UTF8)
  Text.s + PeekS(@TextUnicode, len2, #PB_UTF8|#PB_ByteLength)
Next i

Не хочет :roll:


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: PokeS и PeekS с флагом #PB_UTF8
СообщениеДобавлено: Пн мар 26, 2018 3:05 pm 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11178
Благодарил (а): 4 раз.
Поблагодарили: 414 раз.
Такой подход работать не будет. Эта часть кодируется двумя байтами на символ.
Код:
1
$D0, $AD, $D1, $82, $D0, $B0,

Пробел одним байтом.
Код:
1
$20

Эта часть тоже кодируется одним байтом на символ.
Код:
1
$20, $55, $54, $46, $2D, $38, $0

Если это не учитывать, то нормально преобразовать данные в строку не получится.

Должно быть примерно так.
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
string.s = PeekS(?utf_8, -1, #PB_UTF8)
len.i = StringByteLength(string, #PB_UTF8)
 
For i = 0 To len
  TextUnicode.u = PeekU(?utf_8+i)
  If TextUnicode&255>=128
    i+1
  Else
    TextUnicode&255
  EndIf
  Text.s + PeekS(@TextUnicode, 1, #PB_UTF8)
Next i
 
Debug Text
 
 
DataSection
  utf_8:
 Data.a        $D0, $AD, $D1, $82, $D0, $B0, $20, $D1, $81, $D1, $82, $D1, $80, $D0, $BE, $D0
  Data.a        $BA, $D0, $B0, $20, $D0, $B2, $20, $D1, $84, $D0, $BE, $D1, $80, $D0, $BC, $D0
  Data.a        $B0, $D1, $82, $D0, $B5, $20, $55, $54, $46, $2D, $38, $0
EndDataSection

Это будет работать если символ занимает не больше двух байт.

_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: PokeS и PeekS с флагом #PB_UTF8
СообщениеДобавлено: Пн мар 26, 2018 5:16 pm 
Не в сети
профессор

Зарегистрирован: Сб фев 06, 2016 6:18 pm
Сообщений: 259
Благодарил (а): 14 раз.
Поблагодарили: 29 раз.
Пункты репутации: 0
Ох уж эти биты. Спасибо, Пётр, буду изучать.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: PokeS и PeekS с флагом #PB_UTF8
СообщениеДобавлено: Пн мар 26, 2018 8:13 pm 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11178
Благодарил (а): 4 раз.
Поблагодарили: 414 раз.
Просто нужно читать документацию, хотя бы википедию, ссылку на которую дал выше viewtopic.php?p=88840#p88840
Там написано.
Цитата:
Для символов Юникода с номерами от U+0000 до U+007F (занимающими один байт c нулём в старшем бите) кодировка UTF-8 полностью соответствует 7-битной кодировке US-ASCII.

2. Установить старшие биты первого октета в соответствии с необходимым количеством октетов, определённом на первом этапе:
0xxxxxxx — если для кодирования потребуется один октет;
110xxxxx — если для кодирования потребуется два октета;
1110xxxx — если для кодирования потребуется три октета;
11110xxx — если для кодирования потребуется четыре октета.

Если для кодирования требуется больше одного октета, то в октетах 2-4 два старших бита всегда устанавливаются равными 102 (10xxxxxx). Это позволяет легко отличать первый октет в потоке, потому что его старшие биты никогда не равны 102.

_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: PokeS и PeekS с флагом #PB_UTF8
СообщениеДобавлено: Пн мар 26, 2018 9:14 pm 
Не в сети
профессор

Зарегистрирован: Сб фев 06, 2016 6:18 pm
Сообщений: 259
Благодарил (а): 14 раз.
Поблагодарили: 29 раз.
Пункты репутации: 0
Пётр писал(а):
ссылку на которую дал выше
Это я прозондировал еще месяц назад. Как оно работает, мне +- ясно. Но, то что я получаю при экспериментах, вызывает у меня, как минимум, когнитивный диссонанс. Например:
Код:
1
2
3
4
5
6
7
8
TextUnicode.u = PeekU(?utf_8)
 
Debug Bin(TextUnicode, #PB_Unicode) ; 10101101 11010000
 
DataSection
  utf_8:
 Data.a $D0, $AD
EndDataSection


Ну видно же что в "младшем?" байте 110 то есть для кодировки используется 2 байта.

Код:
1
Debug StringByteLength(Chr(TextUnicode), #PB_UTF8) ; 3


Вот чего оно показывает 3?


Вернуться наверх
 Профиль  
 
Показать сообщения за:  Сортировать по:  
Начать новую тему Ответить на тему  [ Сообщений: 48 ]  На страницу Пред.  1, 2, 3, 4  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

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


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group (блог о phpBB)
Сборка создана CMSart Studio
Русская поддержка phpBB