У меня этот код работает нормально с Visual Studio 2010:
std::string s = "Ceci est le test du StrnCpy";
char buffer_standard[5];
strncpy( buffer_standard, s.c_str(), 5 );
assert( strncmp( buffer_standard, "Ceci ", 5 ) == 0 );
Но компилятор сообщает, что strncpy небезопасен, потому что я не хочу устанавливать _CRT_SECURE_NO_WARNINGS (потому что они могут быть правы, это небезопасно), я пытаюсь использовать версию MSDN strncpy_s. Но это не ведет себя так же, как !!!
Это поднимает утверждение (слишком маленький буфер), поэтому вы должны адаптировать параметр размера:
std::string s = "Ceci est le test du StrnCpy";
char buffer_msdn[5];
strncpy_s( buffer_msdn, s.c_str(), 5 );
Итак, я попробовал это, но тогда buffer_msdn [4] будет «\ 0» вместо «»:
std::string s = "Ceci est le test du StrnCpy";
char buffer_msdn[5];
strncpy_s( buffer_msdn, s.c_str(), 5-1 );
assert( strncmp( buffer_msdn, "Ceci ", 5 ) == 0 ); // asserts!
И это терпит неудачу так же:
strncpy_s( buffer_msdn, sc.c_str(), _TRUNCATE );
Способ обработки дополнительных символов отличается:
std::string s = "Ceci";
char buffer_standard[20];
strncpy( buffer_standard, s.c_str(), 20 );
char buffer_msdn[20];
strncpy_s( buffer_msdn, s.c_str(), s.size() );
buffer_standard
это «Сеси», а затем 16 ‘\ 0’
buffer_msdn
это «Сеси», за которым следует только один «\ 0» (тогда это мусор)
Итак, как Microsoft ожидает, что мы заменим strncpy на strncpy_s с таким же поведением ???
как Microsoft ожидает от нас замены
strncpy
отstrncpy_s
с таким же поведением?
Если бы у них было такое же поведение, у них неизбежно была бы та же самая проблема безопасности: потенциальное отсутствие завершения. Параметры, принятые strncpy
приоритетное копирование большего количества исходных данных NUL
прекращение, и новые функции в основном рассматривают случаи, когда этот выбор был бы важен для предупреждения предупреждений:
memcpy
(который может потребовать дополнительного предварительного звонка strlen()
или же .size()
) или придерживаться strncpy
(возможно с _CRT_SECURE_NO_WARNINGS
).Поскольку эти функции специально поддерживают строки ASCIIZ, в которых только один трейлинг NUL
является обязательным — неудобство случайного использования последнего варианта, очевидно, считается приемлемым.