C# и платформа.NET повредили совместимость между версиями 1.0 и 1.1, а также между 1,1 и 2.0. Запущенные приложения в различных версиях, требуемых, имея несколько версий времени выполнения.NET, установлены.
, По крайней мере, они действительно включали мастер обновления для обновления источника от одной версии до следующего (это работало на большую часть нашего кода).
strncpy
борется с переполнением буфера, требуя указать длину в нем. strcpy
зависит от завершающего \ 0
, что может не всегда встречаться.
Во-вторых, я не понимаю, почему вы решили копировать только 5 символов в строку из 7 символов, но это дает ожидаемое поведение. Это копирование только первых n
символов, где n
- третий аргумент.
Все функции n
используются как защитное кодирование от переполнения буфера. Используйте их вместо старых функций, таких как strcpy
.
Хотя я знаю цель strncpy
, это не совсем хорошая функция. Избегайте обоих. Раймонд Чен объясняет .
Лично я пришел к выводу, что просто избегайте
strncpy
и всех его друзей, если вы имеете дело со строками с завершающим нулем. Несмотря на "str" в имени, эти функции не создают строки с завершающим нулем. Они преобразуют строку с завершающим нулем в буфер необработанных символов. Использование их там, где ожидается строка с завершающим нулем, поскольку второй буфер явно неверен. Мало того, что вы не можете получить правильное завершение нуля, если источник слишком длинный, но если источник короткий, вы получите ненужное заполнение нулем.
См. Также Почему strncpy небезопасен?
strncpy НЕ безопаснее, чем strcpy, он просто заменяет один тип ошибок другим. В C при работе со строками C вам нужно знать размер ваших буферов, нет никакого способа обойти это. strncpy был оправдан для элемента каталога, упомянутого другими, но в противном случае вы никогда не должны его использовать:
Функция strncpy ()
была разработана с учетом очень конкретной проблемы: манипулирование сохраненными строками как оригинальные записи каталога UNIX. В них использовался массив фиксированного размера, а нулевой символ конца использовался только в том случае, если имя файла было короче, чем массив.
Вот что скрывается за двумя странностями strncpy ()
:
Для «более безопасного strcpy ()
» лучше использовать strncat ()
вот так :
if (dest_size > 0)
{
dest[0] = '\0';
strncat(dest, source, dest_size - 1);
}
Результат всегда будет завершаться нулем и не будет копироваться больше, чем необходимо.
манипулирование строками, хранящимися в манере исходных записей каталога UNIX. В них использовался массив фиксированного размера, а нулевой символ конца использовался только в том случае, если имя файла было короче, чем массив. Вот что скрывается за двумя странностями strncpy ()
:
Для «более безопасного strcpy ()
» лучше использовать strncat ()
вот так :
if (dest_size > 0)
{
dest[0] = '\0';
strncat(dest, source, dest_size - 1);
}
Результат всегда будет завершаться нулем и не будет копироваться больше, чем необходимо.
манипулирование строками, хранящимися в манере исходных записей каталога UNIX. Они использовали массив фиксированного размера, а нулевой символ конца использовался только в том случае, если имя файла было короче, чем массив. Вот что скрывается за двумя странностями strncpy ()
:
Для «более безопасного strcpy ()
» лучше использовать strncat ()
вот так :
if (dest_size > 0)
{
dest[0] = '\0';
strncat(dest, source, dest_size - 1);
}
Результат всегда будет завершаться нулем и не будет копироваться больше, чем необходимо.
s что скрывается за двумя странностями strncpy ()
:
Для «более безопасного strcpy ()
» лучше использовать strncat ()
вот так :
if (dest_size > 0)
{
dest[0] = '\0';
strncat(dest, source, dest_size - 1);
}
Результат всегда будет завершаться нулем и не будет копироваться больше, чем необходимо.
s что скрывается за двумя странностями strncpy ()
:
Для «более безопасного strcpy ()
» лучше использовать strncat ()
вот так :
if (dest_size > 0)
{
dest[0] = '\0';
strncat(dest, source, dest_size - 1);
}
Результат всегда будет завершаться нулем и не будет копироваться больше, чем необходимо.
То, что вы ищете, - это функция strlcpy ()
, которая всегда завершает строку нулем и инициализирует буфер. Он также может обнаруживать переполнения. Единственная проблема, он (действительно) не переносимый и присутствует только в некоторых системах (BSD, Solaris). Проблема с этой функцией заключается в том, что она открывает еще одну банку червей, как видно из обсуждений на
http://en.wikipedia.org/wiki/Strlcpy
Лично я считаю, что он намного полезнее, чем strncpy ()
и strcpy ()
. Он имеет лучшую производительность и является хорошим дополнением к snprintf ()
. Для платформ, на которых его нет, это относительно легко реализовать.
(на этапе разработки приложения я заменяю эти две функции ( snprintf ()
и strlcpy ()
) версией с захватом, которая грубо прерывает программу при переполнении или усечении буфера. позволяет быстро вылавливать худших нарушителей. Особенно, если вы работаете с кодовой базой от кого-то другого.
РЕДАКТИРОВАТЬ: strlcpy ()
может быть легко реализован:
size_t strlcpy(char *dst, const char *src, size_t dstsize)
{
size_t len = strlen(src);
if(dstsize) {
size_t bl = (len < dstsize-1 ? len : dstsize-1);
((char*)memcpy(dst, src, bl))[bl] = 0;
}
return len;
}
Функция strncpy ()
является более безопасной: вы должны передать максимальную длину, которую может принять целевой буфер. В противном случае может случиться так, что исходная строка неправильно завершена 0, и в этом случае функция strcpy ()
может записать больше символов в место назначения, повредив все, что находится в памяти после буфера назначения. Это проблема переполнения буфера, используемая во многих эксплойтах
Также для функций API POSIX, таких как read ()
, которые не помещают завершающий 0 в буфер, но возвращают количество прочитанных байтов, вы будете либо вручную введите 0, либо скопируйте его с помощью strncpy ()
.
В вашем примере кода index
фактически не является индексом, но счетчик
- он сообщает, сколько символов не более копировать из источника в место назначения. Если среди первых n байтов источника нет нулевого байта, строка, помещенная в пункт назначения, не будет завершаться нулем
Это может использоваться во многих других сценариях, когда вам нужно скопировать только часть исходной строки в место назначения. Используя strncpy (), вы можете скопировать ограниченную часть исходной строки, в отличие от strcpy (). Я вижу, что вы разместили код с publib.boulder.ibm.com .
strncpy - это более безопасная версия strcpy, на самом деле вы никогда не должны использовать strcpy, потому что это потенциальная уязвимость переполнения буфера, которая делает вашу систему уязвимой для всех видов атак