LINUX.ORG.RU

зачем столько функций

 , , vc


0

1

понадобилось мне написать проект на msvcpp (уже можете закидать тряпками, ССЗБ, знаю). задача простая-получить строку, которая содержит значение текущей директории. ок, есть такая функция, но возвращает она зачем то значение в богомерзком TCHAR. и оказывается, что мелкософт наплодило кучу форматов, среди которых есть char, wchar, tchar, и еще черт знает сколько форматов. и, внимание, с каждым форматом работает только своя функция! например, сконкатенировать 2 строчки - своя функция. но если 2 строчки разного формата, то начинается веселье-нужна куча макросов, функций, переменных и определений. мой вывод-как закончу этот проект-больше не буду соприкасаться с vc (только ассемблер, только хардкор). слава Линуксу!

Коротко: во мудак

GetCurrentDirectory - это макрос, а не функция. В зависимости от настроек проекта (Юникод или нет), раскрывается на:

  • GetCurrentDirectoryA работает с char.
  • GetCurrentDirectoryW работает с wchar_t.

Что тебе мешает явно юзать GetCurrentDirectoryW?

Pavval ★★★★★ ()
Последнее исправление: Pavval (всего исправлений: 1)

Потому что эти функции делались для чистого Си. Там нет перегрузки функций. Ещё с 90-х тянется. Enjoy your WinAPI.

schizoid ★★★ ()

Ты о wcscat, wcscpy и прочих? Это тяжелое наследие богомерзкого высера под названием ANSI C. И, соответственно, в прославляемом линуксе это тоже всё есть. Вообще если ты пишешь программу с использованием Windows API, то ты хочешь использовать широкие строки, т.к. не для всех функций существуют ANSI варианты.

Begemoth ★★★★★ ()
Последнее исправление: Begemoth (всего исправлений: 1)

Неосилятор вспетушился!

anonymous ()

если нет желания соприкасаться с VC, то можно использовать более легковесные компиляторы, тот же TinyC или OpenWatcom

anonymous ()

Присоединяюсь к первому оратору.

А, прикол вспомнил: у нас в одном проекте есть некий юнион, один из вариантов которого носит имя CreateProcess.

Так вот, в дебаггере он таки виден как CreateProcessW.

Miguel ★★★★★ ()

Проблема на в MS VC, а в неумении пользоваться MSDN.

andreyu ★★★★★ ()

Компилируй с флагом _UNICODE, используй только wchar_t. и префикс L у строк, например L"Some text". Если нужно куда-то отдавать однобайтные строки, например при запмси в файл, пользуйся WideCharToMultiByte()

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

А, прикол вспомнил: у нас в одном проекте есть некий юнион, один из вариантов которого носит имя CreateProcess.

Так вот, в дебаггере он таки виден как CreateProcessW.

Прикол с #define Sleep SleepEx даже вошел в книгу Мейерса.

Absurd ★★★ ()

какой то неосилятор этот ТС самую передовую айде не смог использовать и поднял вой уйди не позорься

m4 ()

слава Линуксу!

Для военов УПА поясню: то, что ты описал, это проблемы не с вижулстудией или ейным компилятором, или виндовым API.

Если не умеешь элементарный Си, зачем вообще брался?

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

Собсна этот уродский и богомерзкий MultiByteToWideChar позволяет задать кодировку многобайтной строки, в отличие от.

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

Собсна плюсую, кроме уродского и богомерзкого MultiByteToWideChar.

У меня обычно есть функция на базе MultiByteToWideChar, которая конвертирует std::wstring в std::vector<uint8_t>. MultiByteToWideChar хорош тем что позволяет предварительно посчитать размер выходного буфера чтобы создать вектор нужного размера. А любая константа размера буффера это бомба с часовым механизмом.

Absurd ★★★ ()
Последнее исправление: Absurd (всего исправлений: 1)
Ответ на: комментарий от Absurd

MultiByteToWideChar хорош тем что позволяет предварительно посчитать размер выходного буфера чтобы создать вектор нужного размера

По POSIX'у mbstowcs тоже позволяет посчитать размер выходного буфера, а для mbsrtowcs это стандартно.

Begemoth ★★★★★ ()

А по теме топика - *A функции нужны чтобы работали разные копролиты написанные для Win95-98-ME. А *T барахло нужно чтобы можно было кросскомпилировать код написанный под платформу NT на те же самые Win95-98-ME. Поскольку сейчас совместимость с Win95-98-ME никого не е^Wволнует, используются только W-функции.

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

с какого подзмелья вы вылезли... в VC++ это делается так

std::string toUtf8(string cp_acp)
{
	CStringA sAnsi = cp_acp.c_str();
	CStringW sUtf16 = CA2W(sAnsi, CP_ACP);
	CStringA sUtf8 = CW2A(sUtf16, CP_UTF8);
	return sUtf8.GetBuffer();
}

std::string fromUtf8(string sUtf8)
{
	CStringA s = CW2A(CA2W(sUtf8.c_str(), CP_UTF8), CP_ACP);
	return s.GetBuffer();
}
m4 ()
Ответ на: комментарий от m4

MFC это никому ненужный копролит.

PS: Один тип (std::string) отвечает за хранение и уникодных и однобайтных строк. Проект со временем превратится в могилу для идиота, где часть текста выводится нормально, а часть - непонятно как возникающими кракозаблами.

Absurd ★★★ ()
Последнее исправление: Absurd (всего исправлений: 1)
Ответ на: комментарий от Absurd

MultiByteToWideChar хорош тем что позволяет предварительно посчитать размер выходного буфера чтобы создать вектор нужного размера.

man mbstowcs:

If dest is NULL, n is ignored, and the conversion proceeds as above, except that the converted wide characters are not written out to mem‐ ory, and that no length limit exists.

In order to avoid the case 2 above, the programmer should make sure n is greater or equal to mbstowcs(NULL,src,0)+1.

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

If dest is NULL, n is ignored, and the conversion proceeds as above, except that the converted wide characters are not written out to mem‐ ory, and that no length limit exists.

In order to avoid the case 2 above, the programmer should make sure n is greater or equal to mbstowcs(NULL,src,0)+1.

Тут такого нет

http://www.cplusplus.com/reference/cstdlib/mbstowcs/

If dest does not point to an array long enough to contain the translated sequence, or if src is either not null-terminated or does not contain enough bytes to generate max wide characters (or if it does not begin in the initial shift state), it causes undefined behavior

Хотя описание из MSDN примерно соответствует линуксовому, да. Остается аргумент с кодировкой.

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

Остается аргумент с кодировкой.

ну вообще-то эта функция и так уже перекодирует из одной юникод-кодировки в другую (utf8->utf16le), а больше, по сути и не надо.

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

ну вообще-то эта функция и так уже перекодирует из одной юникод-кодировки в другую (utf8->utf16le), а больше, по сути и не надо.

Под оффтопиком часто приходится 1251 читать.

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

Шла вторая половина 2013-го года...

И да, она перекодирует не в 1251, а в то, что выставлено в настройках, например, в 1252 у немцев.

invy ★★★★★ ()
Последнее исправление: invy (всего исправлений: 1)
Ответ на: комментарий от invy

Шла вторая половина 2013-го года...

Ну да, под виндой много разных интересных копролитов. Вышеотписавшийся оратор MFC еще использует, например.

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

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

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

Там 4 строчки 1) Измерение длины выходного буфера через первый вызов WideCharToMutiByte 2) Создание std::vector<uint8_t> нужного размера 3) Конверсия через второй вызов WideCharToMutiByte 4) return

отказываться из за каких то догм

Каждая зависимость это дополнительный кариес. Одно дело когда это API девайса для распознования речи, например, другое - примитивная конверсия кодировки реализованная в стандартной поставке ОС. Желательно локализовать все кариесы для случаев подобных первому. И даже тогда их будет слишком много.

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

Это тяжелое наследие богомерзкого высера под названием ANSI C. И, соответственно, в прославляемом линуксе это тоже всё есть.

В Linux всё гораздо более вменяемо, добавлены лишь новые типы, а сами функции остались такими же. Ну и использовать ЭТО тебя никто не заставляет (кроме случая совместимости с вендой).

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

А ещё они изобрели интернет

в смысле 100500 идиотов, генерящих бред фконтакте? А толку с того?

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

да ладно, некоторые по привычке продолжают ASCII версии WinAPI функций использовать в современных программах, или считают, что UNICODE им не нужен

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

да ладно, некоторые по привычке продолжают ASCII версии WinAPI функций использовать в современных программах, или считают, что UNICODE им не нужен

Жаль что я не умею изображать Луговского.

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

Ты о wcscat, wcscpy и прочих? Это тяжелое наследие богомерзкого высера под названием ANSI C

Сразу видно специалиста. Это наследие POSIX.

tailgunner ★★★★★ ()

как закончу этот проект-больше не буду соприкасаться с vc (только ассемблер, только хардкор)

Пральна! Зачем юзать все эти богомерзкие функции, если можно написать собственные кривые аналоги?

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

Во сколько времени прошло. Я свалил с windows когда все писали на A функциях и забивали болт на W )

Вообще прочитал тред, дрожь прошла по телу

vertexua ★★★★★ ()
Последнее исправление: vertexua (всего исправлений: 2)
Ответ на: комментарий от vertexua

Я далеко не эксперт в С++, вы имеете ввиду что если просто использовать std::string, то будут проблемы?

Да нет, я про то что все стринги должны быть в одинаковых кодировках. Если нужно две кодировки, нужно использовать два разных типа. Я использую std::vector<uint8_t> для однобайтных строк при приеме или перед отправкой наружу программы, и std::wstring внутри. Иначе будут неявные конверсии в непредсказуемых контекстах, адъ и израиль.

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

Там 4 строчки 1) Измерение длины выходного буфера через первый вызов WideCharToMutiByte 2) Создание std::vector<uint8_t> нужного размера 3) Конверсия через второй вызов WideCharToMutiByte 4) return

но вы почувствуйте как усложнился код... по сравнению с mfc'шным вариантом... надо что то выделять... подсчитывать длинну... по мне так это тоже кариес...

с остальным согласен...

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

богомерзкого высера под названием ANSI C.

Ты чего на святое замахиваешься?

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