Обновление: Думаю, что я попытаюсь связать воедино некоторые ответы, ответы, которые убедили меня в том, что мой собственный оригинальный ответ на коленный удар был плохим.
Во-первых, как отметил АндрейТ в комментариях к этому вопросу, методы усечения (snprintf, strlcpy и strncpy) часто не являются хорошим решением. Часто лучше проверять размер строки string.size()
по длине буфера и возвращать / выдавать ошибку или изменять размер буфера.
Если в вашей ситуации с усечением все в порядке, ИМХО, strlcpy - лучшее решение, являющееся самым быстрым / с наименьшими издержками методом, обеспечивающим нулевое завершение. К сожалению, это не во многих / всех стандартных дистрибутивах и поэтому не переносимо. Если вы делаете много из них, возможно, стоит предоставить собственную реализацию, AndreyT привел пример . Он работает в O ( длина результата ). Также эталонная спецификация возвращает количество скопированных байтов, что может помочь в обнаружении усеченного источника.
Другими хорошими решениями являются sprintf и snprintf . Они являются стандартными и поэтому являются переносимыми и обеспечивают безопасный нулевой завершенный результат. Они имеют больше накладных расходов, чем strlcpy (анализ спецификатора строки формата и списка переменных переменных), но если вы не выполняете много из них, вы, вероятно, не заметите разницу. Он также работает в O ( длина результата ). snprintf всегда безопасен, и этот sprintf может переполниться, если вы неправильно укажете спецификатор формата (как уже отмечали другие, строка формата должна быть "%.<N>s"
, а не "%<N>s"
). Эти методы также возвращают количество скопированных байтов.
Особый вариант решения: strncpy . Он работает в O ( длина буфера ), потому что, если он достигает конца src, он обнуляет оставшуюся часть буфера. Полезно, только если вам нужно обнулить хвост буфера или вы уверены, что длина строки назначения и исходной строки совпадают. Также обратите внимание, что это небезопасно в том смысле, что не обязательно завершать строку нулем. Если источник обрезан, то значение null добавляться не будет, поэтому вызовите последовательность с нулевым присваиванием, чтобы гарантировать завершение нуля: strncpy(buffer, str.c_str(), BUFFER_LAST); buffer[BUFFER_LAST] = '\0';