- 1
- 2
- 3
- 4
filename_size = strlen(dest_dir) + strlen(basename) + 6;
ctx.mtl_file = (char *) malloc(filename_size);
ctx.obj_file = (char *) malloc(filename_size);
sprintf(ctx.mtl_file, "%s/%s.mtl", dest_dir, basename);
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
+118
filename_size = strlen(dest_dir) + strlen(basename) + 6;
ctx.mtl_file = (char *) malloc(filename_size);
ctx.obj_file = (char *) malloc(filename_size);
sprintf(ctx.mtl_file, "%s/%s.mtl", dest_dir, basename);
Долго соображали, почему вылезает сегфолт во free...
Почему нельзя редактировать и удалять запощенный код?
А запили расширение для файла другой длины - ещё подумаешь...
З.Ы. Как заметил коллега: Если компилятор _за_такой_код_ иногда предупреждает, ябзатакое просто сразу бы пи#дил.
Причем без предупреждения.
"Мсье, Вы только что отгребли"
1) почему по кускам, а не полный путь весь и сразу?
2) Для чего расширение зашито? Если что: ждите ща скомпилим и вышлем либу с другим расширением.
с именем расширения файла.
А если завтра '.mtl2', '.xmtl', '.tlm', etc?
Ну там потестить разные версии, функционал расширили/добавили/убавили.
"Счастливого сопровождения!"(с)
Ещё один вопрос, чем так различны
ctx.mtl_file и ctx.obj_file, если вы в них храните один и тот же путь?
P.S. Если мне не изменяет память с цпу, то:
1) (char *) для malloc() не обязателен;
2) при передаче строки целиком можно посмотреть в сторону strdup().
Нам, имхо, просто не показана еще одна строчка в духе:
sprintf(ctx.obj_file, "%s/%s.obj", dest_dir, basename);
Это библиотека для конвертации 3DS в OBJ. На вход функции передаётся имя исходного 3DS-файла, путь к выходной папке и имя желаемой пары файлов (MTL и OBJ) без расширения.
Папка передаётся отдельно, потому что в неё, кроме MTL и OBJ, ещё может понадобиться писать текстуры.
> (char *) для malloc() не обязателен;
Только в C. В C++ обязателен.
А зачем вам, простите, malloc, sprintf и strlen в c++?
Вдруг кто-то возьмёт и вправду в .cpp вставит. Прецеденты были.
Его личные проблемы. Библиотеки, имхо, не копипастят в свои файлы, а подключают и используют. Поэтому достаточно написать *.h так, чтобы он нормально компилировался и в С и в С++. А *.c всегда компилировать в режиме си.
Thank you for submitting this issue. Unfortunately, we are already have our hands full with C++0x and other FE work. At this point, we do not have plans to add C99 support to the compiler.
Thanks,
Mark Roberts
Visual C++ Compiler Team
правда я их не менял, как и их расширение
Да ну... был бы он оформлен как нормальная библиотека... а так почему бы не скопировать его к себе в 3rdparty/minizip... что я и сделал месяц назад, когда нужно было генерить zip'ки. (Тоже ничего не правил и не менял, ну разве что приложил readme с описанием что это, зачем это, и откуда оно добыто).
Именно в этом коде действительно используется C99 - одна из причин, по которой приходится компилировать mingw вместо MSVC (другая причина - кроссплатформенность). Так что в крестовый код просто так всё равно не скопипастить.
Что-то мне подсказывает, что для решения данной задачи С вам не нужен.
Мне так представляется, что можно так str= ''path_to_3ds|dest_dir|mtl|obj'';
В либе парсим и собираем пути. А с учётом возможностей кое-каких плюсовых
либ, решения значительно упроститься.
Как точно подметили: «писать прикладнуху на С, действительно, не самая удачная идея.»
Тем более в винде.
А если писать полностью приложение без рантайма Java/.NET - то тогда уж либо на C+GObject, либо на более вменяемом OO-языке, чем кресты. D, например, или там Vala.
UPD: хотя да, проблема, надо строку парсить и т.п. Половину логики printf'а переписать придется ;(
я вообще не понимаю, как на сишечке в 2012 году можно пилить что то приличное прикладное - я каждый раз плачу кровавыми слезами, когда открываю наши сишные проекты с миллионом глобальных extern и static переменных
в принципе вспомнил, писал как-то года 4 назад на сишечке новый проект, вполне добротно вышло
Ну вот писать прикладнуху на С, действительно, не самая удачная идея.
Обработка ошибок опущена.
http://msdn.microsoft.com/en-us/library/1kt27hek(v=vs.90).aspx If buffer or format is NULL, or if count is less than or equal to zero, these functions invoke the invalid parameter handler, as described in Parameter Validation. If execution is allowed to continue, these functions return -1 and set errno to EINVAL.
vsnprintf(NULL, 0, format, argptr);
Во втором:
vsnprintf(*strp, size, format, argptr);
MS, как всегда, несовместим со стандартом (лечится сборкой с mingw и #define vsnprintf __mingw_vsnprintf). Вот что пишет стандарт C99:
http://www.codecogs.com/reference/computing/c/stdio.h/printf.php?alias=snprintf
Also, they return the number of characters printed (not including the trailing \0 used to end output to strings) or a negative value if an output error occurs, except for snprintf and vsnprintf, which return the number of characters that would have been printed if the size were unlimited (again, not including the final \0 ).
потому микрософт даже чесаться не будет соответствовать
Отрефакторю код, используя самописный аналог asprintf/g_strdup_printf, поверх стандартного C99-того vsnprintf.
Заодно отовсюду исчезнут все эти головняки с ручными malloc, strlen и захардкоженными добавками к длинам, сопровождать проще. А то ошибёшься на единичку, и у заказчика всё падает, причём непредсказуемо и машинозависимо.
Жаль всё-таки, что нет стандартной функции malloc+s_сколько_нужно_printf.