FreeBasic
Главная
Вход
Регистрация
Пятница, 29.03.2024, 12:49Приветствую Вас Гость | RSS
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 2
  • 1
  • 2
  • »
Форум » Freebasic » Вопросы по языку FreeBasic » Dir (Русские имена)
Dir
RStandart26Дата: Понедельник, 08.08.2022, 18:01 | Сообщение # 1
Рядовой
Группа: Пользователи
Сообщений: 10
Репутация: 0
Статус: Offline
Вопрос как можно пользоваться Dir в папках с русскими буквами
Papka = Dir("новаяпапка", attribute)
Не работает. Причем пробовал сохранять исходник, т.е. менять кодировку строки, в dos, ansii (unicode функция dir не поддерживает как я понял). Так что же там такое, с ней? Что за кодировку ей надо, или как она устроена что ей ничего не подходит. Вот выяснил, выдает имена она в кодировке ansii, но работать и с ней и с другими не хочет happy bash


Сообщение отредактировал RStandart26 - Понедельник, 08.08.2022, 18:02
 
haavДата: Вторник, 09.08.2022, 06:16 | Сообщение # 2
Генералиссимус
Группа: Администраторы
Сообщений: 1361
Репутация: 49
Статус: Offline
Все работает нормально с русскими буквами.

Первый же пример из справки: https://users.freebasic-portal.de/freebasicru/helprus/KeyPgDir.html


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
zamabuvaraeuДата: Вторник, 09.08.2022, 08:37 | Сообщение # 3
Подполковник
Группа: Друзья
Сообщений: 147
Репутация: 4
Статус: Offline
Код
Выводит:
ў?ї???.txt

А должно быть:
ўѣїѳ₽ѵ.txt

Нет, не работает.
Юникодной версии Dir до сих пор нет.
Dir() возвращает тип String, у этого типа данных всегда проблемы с кодировками.

Разработчики сделали юникодные версии только некоторых функций, например, WChr, WHex, WSpace. Но не все. Например, нет юникодной Command().

Поэтому вам придётся выбирать: использовать неработающую Dir или вызывать функции операционной системы напрямую (FindFirstfileW, FindNextFileW).
 
haavДата: Вторник, 09.08.2022, 08:56 | Сообщение # 4
Генералиссимус
Группа: Администраторы
Сообщений: 1361
Репутация: 49
Статус: Offline
Цитата
Выводит:
ў?ї???.txt

А должно быть:
ўѣїѳ₽ѵ.txt

Что ты туда засовывал? WSTRING? Или кодировку файла какую-то другую воткнул? Естественно это не будет работать.

Я писал про ASCII (кодовую страницу 1251) и с ним все работает нормально.


Цитата
Dir() возвращает тип String, у этого типа данных всегда проблемы с кодировками.


Если весь проект (исходные файлы) в ASCII с нужной кодовой страницей , которая является родной для текущей системы , нет никаких проблем с DIR. И естественно DIR работает с типом STRING , нефиг от нее ждать поддержки юникода.


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
RStandart26Дата: Вторник, 09.08.2022, 12:10 | Сообщение # 5
Рядовой
Группа: Пользователи
Сообщений: 10
Репутация: 0
Статус: Offline
Если указать адрес на латинице, то dir да выдаст имена на русском папок первых вложенных, но глубже искать не удается, вот в чем дело. Если указать адрес на кириллице, то хоть убей он не ищет ничего
 
VitaminДата: Вторник, 09.08.2022, 12:48 | Сообщение # 6
Лейтенант
Группа: Пользователи
Сообщений: 55
Репутация: 4
Статус: Offline
RStandart26, 
Цитата
Если указать адрес на кириллице, то хоть убей он не ищет ничего
Это ограничение можно обойти добавлением своей функции проверки маски поиска. То есть ищем все по маске "*", а затем проверяем каждый найденный с помощью функции.
Вот моя функция:
Код
Function ProverkaMask(ist As String, msk As String, ByVal start As Integer=1,_
                        ByVal ssim As Integer=1, ByVal sm As Integer=0) As Integer
   Dim As Integer poz, start0=start, ssim0=ssim, sm0=sm, razmIst=Len(ist)
   Dim As String*1 sim   
   Do
      If ssim > Len(msk) Then ' если закончилась маска
         If sm = 1 Then ' если в конце звёздочка
            Return 1
         ElseIf start = razmIst+1 Then
            Return 1 
         Else
            If ProverkaMask(ist,msk,start,1,sm) Then Return 1 Else Return 0         
         EndIf
      EndIf
      sim = Mid(msk,ssim,1) ' Сканируем маску по 1 символу со счетчиком
      If sim = "*" Then ' условное начало поиска
         sm = 1 : ssim += 1
         If ProverkaMask(ist,msk,start,ssim,sm) Then Return 1 Else Return 0
      Else
         If start > razmIst Then Return 0      
         If sim = "?" Then ' увеличиваем значение точки старта
            start += 1 : ssim += 1 : sm = 0      
            If ProverkaMask(ist,msk,start,ssim,sm) Then Return 1 Else poz = 0
         Else ' sim = "буква"   
            poz = InStr(start,ist,sim)
            If sm = 0 AndAlso poz <> start Then poz = 0 Else start = poz               
         EndIf
      EndIf
      If poz = 0 Then ' не найден символ подстроки
         If sm0 = 1 AndAlso start < razmIst Then ' на следующий круг   
            start0 += 1 : start = start0 : ssim = ssim0 : sm = 1
         Else
            Return 0
         EndIf
      Else ' к следующему элементу
         start += 1 : ssim += 1 : sm = 0
      EndIf      
   Loop      
End Function


проверка: 
Код
Dim As String s = "Морковка"
? ProverkaMask(s, "Мор*к?") ' возвращает 1 если совпало, иначе  0
Sleep


Функция регистрозависимая, но если входные аргументы для неё привести к одному регистру, то станет регистронезависимой.
 
haavДата: Вторник, 09.08.2022, 13:27 | Сообщение # 7
Генералиссимус
Группа: Администраторы
Сообщений: 1361
Репутация: 49
Статус: Offline
Цитата RStandart26 ()
Если указать адрес на латинице, то dir да выдаст имена на русском папок первых вложенных, но глубже искать не удается, вот в чем дело. Если указать адрес на кириллице, то хоть убей он не ищет ничего


Все ищет. Тот же пример , что я указал по ссылке в справке. Введи примерно следующее для поиска:

Код
list_files "C:\БЛАБЛА\*.*", fbDirectory


Естественно папка "БЛАБЛА" должна существовать и в ней что-то должно быть.


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
zamabuvaraeuДата: Вторник, 09.08.2022, 18:34 | Сообщение # 8
Подполковник
Группа: Друзья
Сообщений: 147
Репутация: 4
Статус: Offline

Цитата
Что ты туда засовывал?
Вот такой код:
Код
Dim As Integer FileCount

var p = Dir("*")
If Len(p) Then
    Print p
    Filecount = 1
    var pp = Dir()
    Do While Len(pp)
        Print pp
        FileCount += 1
        pp = Dir()
    Loop
End If

Print FileCount & " files in the current directory."

Создал в каталоге файл «ўѣїѳ₽ѵ.txt», и он не смог его отобразить.
Ладно бы была проблема с отображением символов не в той кодировке. Но он в принципе не может отобразить символы с кодом больше 256.

Это одна из причин, почему я всегда удаляю рантайм из своих программ и вызываю функции системы напрямую.
 
haavДата: Вторник, 09.08.2022, 19:36 | Сообщение # 9
Генералиссимус
Группа: Администраторы
Сообщений: 1361
Репутация: 49
Статус: Offline
Цитата zamabuvaraeu ()
Создал в каталоге файл «ўѣїѳ₽ѵ.txt», и он не смог его отобразить.

Такое и не должно нормально отображаться. Те символы , которые могут быть преобразованы в ASCII (1251), будут преобразованы. Остальные просто заменяются знаками вопроса. Стандартная логика преобразования. Поэтому ты и имеешь на выходе что-то типа: ў?ї???.txt
Функция DIR ведет себя правильно , как и должна. Точно так же,  как поведут себя FindFirstfileA, FindNextFileA.

Цитата zamabuvaraeu ()
Это одна из причин, почему я всегда удаляю рантайм из своих программ и вызываю функции системы напрямую.

Удаление рантайма и проблема преобразования специфичных имен файлов , имеющих символы , код которых выходит за рамки одного байта,  никак не связаны. Винапи функции можно использовать и не удаляя рантайм. Зато не удаляя рантайм , я имею удобные функции , которые не только сильно помогают в разработке (instr , mid , val , allocate и пр.) , но и в отладке (print , sleep).


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
RStandart26Дата: Вторник, 09.08.2022, 21:34 | Сообщение # 10
Рядовой
Группа: Пользователи
Сообщений: 10
Репутация: 0
Статус: Offline
Все разобрался:
При написании пробного кода банально забыл звездочку.
А при использовании функции вот какая история, файл с функциями в кодировке юникода. Когда попадает строка на латинице, тип String естесственно, подпрограмма добавляет "/*" и ищет норм, кодировка "/*" компилятором автоматом преобразуется из uni в ansi, а вот при кириллице в строке и смешивании кодировок он строку корёжет в неизвестно что))))

В итоге поправил все заработало
(Смесь кодировок автоматом это жесть, неожиданная, не предугадаешь)


Сообщение отредактировал RStandart26 - Вторник, 09.08.2022, 21:38
 
RStandart26Дата: Вторник, 09.08.2022, 21:40 | Сообщение # 11
Рядовой
Группа: Пользователи
Сообщений: 10
Репутация: 0
Статус: Offline
Ну у вас и реклама
Прикрепления: 0705556.jpg (194.1 Kb)
 
haavДата: Среда, 10.08.2022, 06:57 | Сообщение # 12
Генералиссимус
Группа: Администраторы
Сообщений: 1361
Репутация: 49
Статус: Offline
Цитата RStandart26 ()
Ну у вас и реклама

Я никогда не занимался и не занимаюсь рекламами. Рекламу на этом форуме навешивают хозяева UCOZ .


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
RStandart26Дата: Среда, 10.08.2022, 15:42 | Сообщение # 13
Рядовой
Группа: Пользователи
Сообщений: 10
Репутация: 0
Статус: Offline
(Еще отступление про смешивание кодировок, при печати print Stroka+"чего нибудь" коверкает вывод, т.е. перекодирует строку на основании распознания какого то своего внутреннего переменной Stroki. Приходится пользовать через ; элементы печати)

Ну и по теме. Мучения не закончились:
Для проверки создал несколько папок на русском, элементарно копировать вставить, win 11 x64:
Новая папка
Новая папка -- копия
Новая папка -- копия(2)

Так вот в чем дело, винда добавляет -- копия. Длинное тире, unicode символ, и dir преобразует в первое похожее - в тире.
"Новая папка - копия". Но далее работать с таким адресом несуществующем не возможно, не удалить не перейти в каталог. Что делать? "--копия" частое явление. Нужна функция dir или на api dir выдающая юникод строку. Как то винда работает с адресами то своими в юникоде


Сообщение отредактировал RStandart26 - Среда, 10.08.2022, 15:43
 
haavДата: Среда, 10.08.2022, 16:51 | Сообщение # 14
Генералиссимус
Группа: Администраторы
Сообщений: 1361
Репутация: 49
Статус: Offline
Я не могу проверить на win 11 x64 , у меня ее просто нет и вряд ли когда будет. Но я сильно сомневаюсь , что win11 версия отличается от win10 в этом плане. На win10 используется символ длинного тире , но он есть в таблице ASCII 1251 под номером 151 (Dec) или 97(hex). В этот символ и преобразуется и все нормально работает. Почему-то я думаю ты сам что-то намутил.  Судя по этому посту: http://freebasic.ucoz.com/forum/4-563-3049-16-1660070063 ты используешь что-то юникодное в своем проекте. Тогда нафига смешивать? Если работаешь только под винду и с юникодом, просто используй FindFirstfileW, FindNextFileW. Зачем париться с аксишной функцией DIR?

Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
zamabuvaraeuДата: Среда, 10.08.2022, 17:45 | Сообщение # 15
Подполковник
Группа: Друзья
Сообщений: 147
Репутация: 4
Статус: Offline
Тот или иной аналог строковых функций есть в системных библиотеках.

Поиск подстроки: StrStr
Преобразование числа в строку и наборот: многочисленные варианты wtoi. Если недостаточно, можно подключить тяжёлую артиллерию из VariantChangeType.
Allocate и Deallocate — всего лишь псевдонимы для malloc и free, можно вызывать напрямую.
Графическая библиотека — маленькое подмножество GDI. Стоит заметить, что графическую библиотеку нормально выглядит только в DOS, и в современном мире для написания GUI непригодна.

Если использовать только функции ОС, то рантайм остаётся не у дел и лежит мёртвым кодом. В моём случае нет никакого смысла оставлять в екзешнике мёртвый код, у меня даже стартовая точка своя, вместо _mainCRTStartup.
 
Форум » Freebasic » Вопросы по языку FreeBasic » Dir (Русские имена)
  • Страница 1 из 2
  • 1
  • 2
  • »
Поиск: