strncpy_s не соответствует стандарту?

У меня этот код работает нормально с 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 с таким же поведением ???

0

Решение

как Microsoft ожидает от нас замены strncpy от strncpy_s с таким же поведением?

Если бы у них было такое же поведение, у них неизбежно была бы та же самая проблема безопасности: потенциальное отсутствие завершения. Параметры, принятые strncpy приоритетное копирование большего количества исходных данных NUL прекращение, и новые функции в основном рассматривают случаи, когда этот выбор был бы важен для предупреждения предупреждений:

  • изменение кода либо:
    • покажите, что программист рад за копирование меньшего количества исходных символов или,
    • измените размер буфера назначения, чтобы принять дополнительный символ, иначе
  • переход к другой функции, такой как memcpy (который может потребовать дополнительного предварительного звонка strlen() или же .size()) или придерживаться strncpy (возможно с _CRT_SECURE_NO_WARNINGS).

Поскольку эти функции специально поддерживают строки ASCIIZ, в которых только один трейлинг NUL является обязательным — неудобство случайного использования последнего варианта, очевидно, считается приемлемым.

1

Другие решения


По вопросам рекламы [email protected]