LINUX.ORG.RU

fopen() со строкой wchar_t


0

0

Поискал на форуме, ниего не смог найти.

Как известно, прототип fopen() имеет вид

FILE *fopen(const char *fname, const char *mode);

Если в качестве fname будет Unicode строка (тип wchar_t), функция не сработает:

const wchar_t fname[] = L"牧野由依江語晨/index.html";

FILE *f = fopen(fname, "r");

предупреждение: passing argument 1 of ‘fopen’ from incompatible pointer type

Вопрос: как в Linux открывать файлы с не ASCII-именами? Под Windows есть _wfopen(), у себя (Ubuntu 8.04, GCC 4.2.4) я в stdio.h не нашел ничего подобного. Помогите, пожалуйста.


Ответ на: комментарий от one_more_hokum

>http://www.linuxquestions.org/questions/programming-9/how-to-use-fopen-or-som...

>Ы?

Я читал эту тему перед тем как писать на ЛОР. Там написано: "Linux does not support "wide" path strings so there are no equivalent functions for them." Как тогда реализовать открытие файла, имя которого состоит из не-ASCII символов?

olo
() автор топика
Ответ на: комментарий от olo

fopen работает с именами файлов в UTF-8. UTF-8 обладает хорошим свойством что он обратно совместим с ASCII-7.

Переведи имя файла в UTF-8 и открывай.

dilmah ★★★★★
()
Ответ на: комментарий от dilmah

imho нужно не в utf-8 переводить а в кодировку локали, через wcsrtombs - convert a wide-character string to a multibyte string

если у пользователя локаль koi8-r а Вы ему имена файлов в utf-8 насоздаёте... он будет не рад :)

Eshkin_kot ★★
()
Ответ на: комментарий от Eshkin_kot

> imho нужно не в utf-8 переводить а в кодировку локали, через wcsrtombs - convert a wide-character string to a multibyte string

Разве "multibyte string" - это не utf-8?

> если у пользователя локаль koi8-r а Вы ему имена файлов в utf-8 насоздаёте... он будет не рад :)

Если у пользователя локаль koi8-r, а он пытается создавать файлы с иероглифами в названии - видимо ему это зачем-то нужно, не?

anonymous
()
Ответ на: комментарий от anonymous

wchar - два байта
char - 1 байт

utf-16 - два байта ,
utf-8 - 1 байт
но "ю" в utf-8 занимает char[2] а вообще есть ман где все это поулярно описанл

wfrr ★★☆
()
Ответ на: комментарий от anonymous

> Разве "multibyte string" - это не utf-8?

нет. это кодировка локали. она может быть utf-8, koi8-r, Shift-JIS и т.д.

> Если у пользователя локаль koi8-r, а он пытается создавать файлы с иероглифами в названии - видимо ему это зачем-то нужно, не?

и давно у Вас иероглифы в koi8-r появились ? в koi8-r нет иероглифов и он никаким способом не сможет создать файл с иероглифами в имени и потом с ним нормально работать. просто потому что их нет в его кодировке.

почитайте про кодировки используемые в японии, корее, китае... те кто использует иероглифы обычно юзают кодировку типа Shift-JIS а это совсем не utf-8 ! и пихать название файла в жёстко заданную utf-8 вместо того что бы сконвертировать его в кодировку локали - это ошибка.

anonymous
()
Ответ на: комментарий от anonymous

что-то неубедительно. Файловая система и имена ее объектов -- это глобальное явление. Локали же у разных процессов могут быть разными.

dilmah ★★★★★
()
Ответ на: комментарий от anonymous

> Разве "multibyte string" - это не utf-8?

В данном случае "multibyte string" - непонятно что (спасибо составителям документации), но скорее всего это то, что указано в LC_CTYPE.

> Если у пользователя локаль koi8-r, а он пытается создавать файлы с иероглифами в названии - видимо ему это зачем-то нужно, не?


У пользователя еще много чего может стоять кроме utf-8, поэтому гладиолус.

ShprotX
()
Ответ на: комментарий от anonymous

> нет. это кодировка локали. она может быть utf-8, koi8-r, Shift-JIS и т.д.

Да верно, в мане пишут wcsrtombs конвертит в кодировку, соотв. текущей локали

> и давно у Вас иероглифы в koi8-r появились ? в koi8-r нет иероглифов и он никаким способом не сможет создать файл с иероглифами в имени и потом с ним нормально работать. просто потому что их нет в его кодировке.

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

Т.е. пример почему должна быть перекодировка: файловая система смонтирована с какой-то локалью, например win-1251, а юзер у нас поставил KOI8-r в окружении. Ответственность за перекодирование символов лежит не на прикладной программе, она просто вызывает свои fopen'ы..

В винде-то вон правильно сделано - вызовы функций продублированы для юникода и текущей локали..

> пихать название файла в жёстко заданную utf-8 вместо того что бы сконвертировать его в кодировку локали - это ошибка.

Наоборот, ошибка - это как оно сейчас.

anonymous
()
Ответ на: комментарий от ShprotX

> В данном случае "multibyte string" - непонятно что (спасибо составителям документации), но скорее всего это то, что указано в LC_CTYPE.

Да, догадался только по косвенным признакам:

The conversion can stop for three reasons:

1. A wide character has been encountered that can not be represented as a multibyte sequence (according to the current locale).

А про ФОПЕН и этого не написано..

> У пользователя еще много чего может стоять кроме utf-8, поэтому гладиолус.

Под вендой чарсет локали используется как дефолтный при конвертировании символов в юникод. Т.е. если не указано иное, символы считаются принадлежащими заданной в настройках локали. Просто, понятно и логично. А в юниксах - похоже да, гладиолус. С другой стороны это и не плохо: раньше сдохнут неюникодные локали, эти пережитки страшного прошлого..

anonymous
()
Ответ на: комментарий от anonymous

> Вопрос в том, как будет интерпретировать имя файла fopen если у процесса стоит не-utf локаль. В принципе действительно он должен бы считать, что ему данные переданы в текущей локали и попытаться конвертить их в юникод.

никак. ничего fopen не считает и не думает. он передаёт строку как есть в ядро где она попадает в драйвер файловой системы, который эту строку "как есть" вставляет в качестве имени.

драйвер некоторых файловых систем может дополнительно сконвертировать из одной (заранее известной !) кодировки в другую (пример vfat из iocharset=[локаль linux] в codepage=[локаль dos]).

>> пихать название файла в жёстко заданную utf-8 вместо того что бы сконвертировать его в кодировку локали - это ошибка.

> Наоборот, ошибка - это как оно сейчас.

то как сейчас - это мега ошибка, потому что open не прнимает широких символов wchar_t :) и считать что open принимает только utf-8 - такая же мега ошибка.

open принимает любую мультибайтную/однобайтную кодировку, а как потом эти строки интерпретируются в выводе ls на экран - это не его задача.

anonymous
()
Ответ на: комментарий от anonymous

> Под вендой чарсет локали используется как дефолтный при конвертировании символов в юникод. Т.е. если не указано иное, символы считаются принадлежащими заданной в настройках локали.

хм, так и в Linux же абсолютно так же ! здесь просто нет другого способа: "символы считаются принадлежащими заданной в настройках локали." всё. точка. Просто, понятно и логично. и запутаться то негде ! :)

anonymous
()
Ответ на: комментарий от dilmah

> что-то неубедительно. Файловая система и имена ее объектов -- это глобальное явление. Локали же у разных процессов могут быть разными.

а Вы попробуйте и убедитесь. никогда не видели "?????" вместо имён файлов ? :)

anonymous
()
Ответ на: комментарий от anonymous

> так и в Linux же абсолютно так же ! здесь просто нет другого способа: "символы считаются принадлежащими заданной в настройках локали." всё. точка. Просто, понятно и логично. и запутаться то негде ! :)

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

По крайней мере эти высказывания противоречат друг другу. У венды, на НТ-шном ядре, функции юникодные. Дубликаты вызовов для неюникодных строк преобразуют переданные им байты в юникод перед вызовом функций ядра. Информацию о том, какому символу соответствует байт 0хХУ они получают из текущей локали, если кодировка не задана явно. Это и называется "символы считаются принадлежащими заданной в настройках локали". А если байты передаются без перекодирования - это называется "все положили на локаль и производят мусор". Я что-то очень сомневаюсь, что такое возможно. Даже под Линуксом.

anonymous
()
Ответ на: комментарий от anonymous

> никогда не видели "?????" вместо имён файлов ? :)

И как часто такие имена свидетельствуют о том, что имя файла записано в неправильной кодировке? По сравнению с теми случаями когда текущая консоль не поддерживает символы из названия файла или диск смонтирован с неверной кодировкой.

anonymous
()
Ответ на: комментарий от anonymous

seb@seb:/tmp/p$ echo русский | iconv -t koi8-r | (export LANG=ru_RU.KOI8-R; read a; touch $a)

локаль правильная ? (export LANG=ru_RU.KOI8-R) - правильная.
кодировка правильная ? (echo русский | iconv -t koi8-r) - правильная.
и что в результате ? - имя файла в кодировке koi8-r.

seb@seb:/tmp/p$ ls
???????
seb@seb:/tmp/p$ ls | hd
00000000 d2 d5 d3 d3 cb c9 ca 0a |........|
00000008
seb@seb:/tmp/p$ ls | iconv -f koi8-r
русский

Eshkin_kot ★★
()
Ответ на: комментарий от dilmah

>fopen работает с именами файлов в UTF-8. UTF-8 обладает хорошим свойством что он обратно совместим с ASCII-7.

>Переведи имя файла в UTF-8 и открывай.

dilmah спасибо, действительно работает. Оказалось легче, чем я думал хехе :)

olo
() автор топика
Ответ на: комментарий от Eshkin_kot

> seb@seb:/tmp/p$ ls > ???????

М-да... А создавал его просто чем-нить типа touch русский?

Если даже системные утилиты так себя ведут, то, видимо, никакого универсального подхода к избежанию локализационных проблем не существует?

anonymous
()
Ответ на: комментарий от olo

>>Переведи имя файла в UTF-8 и открывай.

> dilmah спасибо, действительно работает. Оказалось легче, чем я думал хехе :)

хехе, лёгким движением руки мы будем срать в каталоги пользователям с НЕ UTF-8 локалью нечитабельным мусором... браво ! :)

anonymous
()
Ответ на: комментарий от anonymous

> Если даже системные утилиты так себя ведут, то, видимо, никакого универсального подхода к избежанию локализационных проблем не существует?

Каких проблем, конкретно ? Вы проблему сформулируйте словами :)

А отсутствие нужных шрифтов или символов в текущей локали пользователя - это не проблема, для этого придумали переводить на разные языки нужные строки :) и вместо тех иероглифов в русской локали был бы написан их перевод, на русском. и никаких проблем.

anonymous
()
Ответ на: комментарий от anonymous

> Каких проблем, конкретно ? Вы проблему сформулируйте словами :)

Ёшкин Кот же чётко сформулировал.

> А отсутствие нужных шрифтов или символов в текущей локали пользователя - это не проблема, для этого придумали переводить на разные языки нужные строки :) и вместо тех иероглифов в русской локали был бы написан их перевод, на русском. и никаких проблем.

Как бы вот это:

seb@seb:/tmp/p$ ls | iconv -f koi8-r русский

нам намекает на наличие русских шрифтов.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.