Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> поведение wcstombs 
:(
    Опции темы
mrgloom
Дата 26.11.2013, 12:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 8.6.2011

Репутация: нет
Всего: нет



Код

bool func( const TCHAR* fileName)
{
    #ifdef _UNICODE
        char path[MAX_PATH];
        wcstombs(path, fileName, ARRAYSIZE(path));
    #else
        const char* path = strFileName;
    #endif


почему то wcstombs обрезает путь, то ли из-за того что русские буквы в названии папок то ли из-за того что пробелы, в чём причина?
PM MAIL   Вверх
Static
Дата 26.11.2013, 13:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 185
Регистрация: 6.11.2008

Репутация: 1
Всего: 2



Первый раз вижу макрос ARRAYSIZE, быстрое гугление показало, что он возвращает количество элементов в массиве. А функция wcstombs третьим параметром принимает количество байт
--------------------
Я не настолько безнадежен, как кажется...
PM MAIL   Вверх
mrgloom
Дата 26.11.2013, 14:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 8.6.2011

Репутация: нет
Всего: нет



замена на sizeof(path) не дала результата, тем более что вроде как размер char это и есть 1 байт.

похоже отрезает путь именно до папки с русским названием.

Добавлено через 3 минуты и 13 секунд
например D:\Новая папка\file.dat
превращается в D:\

а например D:\test folder\file.dat  работает
PM MAIL   Вверх
mrgloom
Дата 26.11.2013, 16:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 8.6.2011

Репутация: нет
Всего: нет



по всей видимости
Цитата


If wcstombs encounters a wide character it cannot convert to a multibyte character, it returns –1 cast to type size_t and sets errno to EILSEQ.


как раз возвращает -1.


только непонятно почему не может сконвертировать русские буквы?
PM MAIL   Вверх
Static
Дата 26.11.2013, 16:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 185
Регистрация: 6.11.2008

Репутация: 1
Всего: 2



mrgloom, а что функция возвращает при этом? -1?

опередил smile Вот тут не знаю. Может, надо текущую локаль установить?

Это сообщение отредактировал(а) Static - 26.11.2013, 16:04
--------------------
Я не настолько безнадежен, как кажется...
PM MAIL   Вверх
mrgloom
Дата 26.11.2013, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 8.6.2011

Репутация: нет
Всего: нет



http://habrahabr.ru/post/164193/
боль


вообще функция определена как
Код

bool func( const TCHAR* fileName)

а вызывается
Код

func(dlg.GetPathName())

т.е. передается CString вроде как, может он там автоматом конвертируется?
т.е. даже не надо писать 
Код

func((LPCTSTR)dlg.GetPathName())


и да у меня юникод проект, если это важно.

Это сообщение отредактировал(а) mrgloom - 26.11.2013, 17:01
PM MAIL   Вверх
mrgloom
Дата 26.11.2013, 17:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 8.6.2011

Репутация: нет
Всего: нет



вообщем так вроде работает
Код

CT2CA path(fileName);

PM MAIL   Вверх
smalcom
Дата 28.11.2013, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 494
Регистрация: 16.10.2004
Где: Dnepr

Репутация: нет
Всего: 7



а wcslen заюзать, не?


--------------------
What DA F...???
PM MAIL WWW Skype Jabber   Вверх
mrgloom
Дата 28.11.2013, 18:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 8.6.2011

Репутация: нет
Всего: нет



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

хоть вместо
Код

char path[MAX_PATH];
wcstombs(path, fileName, ARRAYSIZE(path));


напиши
Код

wcstombs(path, fileName,MAX_PATH);


Это сообщение отредактировал(а) mrgloom - 28.11.2013, 18:21
PM MAIL   Вверх
vinter
Дата 28.11.2013, 18:36 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Ну что же не читаем документацию на функции?
Цитата(MSDN)

wcstombs  uses the current locale for any locale-dependent behavior; _wcstombs_l is identical except that it uses the locale passed in instead

Цитата(cplusplus.com)

The behavior of this function depends on the LC_CTYPE category of the selected C locale.



--------------------
Мой блог
PM MAIL WWW   Вверх
mrgloom
Дата 29.11.2013, 09:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 8.6.2011

Репутация: нет
Всего: нет



ну да можно и через изменение локали, но я решил с этим не разбираться, потому что непонятно какую ставить и она как я понял меняется глобально, т.е. потом её надо менять обратно?
PM MAIL   Вверх
vinter
Дата 29.11.2013, 09:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



да, менять придётся на всё приложение. Вообще, нужно использовать юникод везде и не переводить в ANSI+codepage. 


--------------------
Мой блог
PM MAIL WWW   Вверх
mrgloom
Дата 29.11.2013, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 8.6.2011

Репутация: нет
Всего: нет



дело в том, что в функцию передаётся TCHAR* , а внутри используется библиотечная функция которая хочет char* .
PM MAIL   Вверх
xvr
Дата 2.12.2013, 12:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



TCHAR у вас Unicode, а char - ANSI. Перевод из Unicode в ANSI вещь неоднозначная, и сама по себе зависит от локали, в которой вы хотите этот  самый ANSI получить. Так что для любой функции перевода Unicode -> ANSI нужно так или иначе задавать локаль (или кодовую страницу). Для wcstombs это делается настройкой локали в CRT, для WideCharToMultiByte кодовая страница задается при вызове


PM MAIL   Вверх
akizelokro
Дата 14.12.2013, 13:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Крокодил
**


Профиль
Группа: Участник
Сообщений: 761
Регистрация: 30.7.2007

Репутация: 1
Всего: 5



TCHAR это TCHAR, в случае если определен _UNICODE это wchar_t (из башки вылетело как wide string символ обозначается, wchar_t или wchar), в ином случае это char (multibyte string character). Это подставляется на стадии компиляции.

В случае, если идут проблемы с конвертацией национальных симоволов (кириллицы в том числе) в символьный массив char[] порядок действий следующий:
1. Проверяется locale на соответствие национальной кодировке
2. Если и это не срабатывает, проверяется на размер массива-приёмника (на каком символе обрезается, на первом национальном или в другом месте). судя по тому, что размер массива установлен в MAX_PATH, в данном случае проблемка с установкой национальной кодовой страницы.

В данном случае можно переписать
Код

        char path[MAX_PATH];
        wcstombs(path, fileName, ARRAYSIZE(path));

на
Код

        char path[MAX_PATH];
        wcstombs(path, fileName, MAX_PATH);


В случае с CString уже на стадии копиляции происходит преобразование TCHAR в wchar_t или char, а дальше подыскивается способ преобразования CStringA или CStringW к TCHAR* (используемый по умолчанию при компиляции тип CString тоже зависит от наличия либо отстутсвия _UNICODE)


--------------------
a = a + b; b = a - b; a = a - b;
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1324 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.