Вопрос по c++, visual-c++ – Альтернативы MS strncpy_s

4

Какие есть альтернативы расширенным функциям безопасности Microsoft, таким какstrncpy_s или же_itoa_s? При разработке в среде MS цель состоит в том, чтобы написать код, который можно легко перенести на другие платформы.

Для чего вы используете строки C? Связать с C Api? Mykola Golubyev

Ваш Ответ

9   ответов
3
std::string s(Cstring, n);
1

он просто берет минимум длины строки, размера данных источника и назначения и копирует полученное количество символов в место назначения. Если вам так нужно, почему бы не реализовать это самостоятельно?

1

Я бы просто использовал версию Microsoft на данный момент, и если вы решите портировать на другую ОС позже, ТО затем внедрите ее самостоятельно для целевой платформы и используйте команды препроцессора, чтобы указать вашу реализацию на платформах, отличных от Windows.

2

strlcpy, Хотя это и не стандарт C, он существует на нескольких платформах, и вы можете скачать реализации, так как исходный код доступен бесплатно. Видетьhttp://www.gratisoft.us/todd/papers/strlcpy.html

1

что @codeLizard спрашивает о том, как написать совместимый код для обработкивсе функции, которые Microsoft устарела в пользу своих безопасных версий, а не только строковые функции.

Функции, основанные на безопасных функциях Microsoft, включены в Приложение K стандарта C11, но приложение широко не поддерживается за пределами MSVS.

Вы можете написать макросы и встроенные функции во включаемом файле для отображения междунесколько из традиционных и безопасных версий. Я отправилнабор конверсионных макросов здесь, Если вы хотите скопировать их, получите их с понравившейся страницы; более полные, лучшие комментарии, чем ниже.

Однако этот подход не работает для отображения традиционных функций в безопасные версии, которые принимают аргументы размера, если аргументы размера также не присутствуют в традиционных функциях. Кроме того, функции безопасности отличаются поведением исключений, а иногда и возвращаемыми значениями. Мои текущие конверсии не учитывают это. Когда у меня будет время, я постараюсь улучшить их там, где смогу. А пока я оставлю это как упражнение для читателя.

Я рекомендую использовать безопасные функции в новом коде, если вы можете, использовать решение для функции «плюс», если это необходимо, для переносимости в компиляторы не-MS, а также в качестве моста для повторного использования устаревшего кода, пока у вас не будет времени обновить его с помощью безопасных функций.

Вот сокращенная версия вышеупомянутого связанного подхода макроса / встроенной функции:

#pragma once
#if !defined(FCN_S_MACROS_H)
   #define   FCN_S_MACROS_H
   #include <cstdio>
   #include <string> // Need this for _stricmp
   using namespace std;

   #if (defined(_MSC_VER) && (_MSC_VER >= 1400) ) // _MSC_VER==MSVC 2005 

      // The function plus macro strategy could be used to maintain
      // consistent exception behaviors and return values. 
      inline extern
      FILE*   fcnSMacro_fopen_s(char *fname, char *mode)
      {  FILE *fptr;
         fopen_s(&fptr, fname, mode);
         return fptr;
      }
      #define fopen(fname, mode)               fcnSMacro_fopen_s((fname), mode))

      #define fprintf(fptr, ...)               fprintf_s((fptr), __VA_ARGS__)
      #define fscanf                           fscanf_s
      #define strncpy(dest, source, count)     strcpy_s((dest), (count), (source))
      // Can't map sprinf to sprintf_s (size argument unavailable). 
      //    #define sprintf                    ???


      ...
    #else
      #define fopen_s(fp, fmt, mode)          *(fp)=fopen( (fmt), (mode))
      #define fprintf_s                        fprintf
      #define fscanf_s                         fscanf
      #define strcpy_s(dest, count, source)    strncpy( (dest), (source), (count) )
      ...
    #endif //_MSC_VER
#endif // FCN_S_MACROS_H
@Джонатан. Правильно по поводу факультативного Приложения К. Я должен был упомянуть это. Последние несколько лет я пишу код исключительно в Visual Studio. Я думаю, что я видел опцию командной строки компилятора Gnu для Приложения K (не могу вспомнить наверняка), поэтому я предположил, что она широко поддерживается в наши дни. Это правда? Неаккуратный я не подтверждаю это сам. riderBill
Стандарт C ++ 11 ссылается на стандарт C99, а не на стандарт C11. И текущий стандарт C ++ - это C ++ 14, конечно. Jonathan Leffler
Стандарт C ++ 11 не упоминаетstrncpy_s() в явном виде. Стандарт C11 имеетstrncpy_s() в необязательном приложении K (нормативное, но необязательное). К сожалению, версии безопасных функций Microsoft не соответствуют спецификациямTR 24731 или Приложение K, Это делает их проблематичными для переносимости по двум причинам: (1) большинство платформ, не принадлежащих Microsoft, вообще не реализовали функции Приложения K, и (2) если платформа реализовала их, будут различия между тем, что работает с Microsoft, и тем, что работает на других платформах. Jonathan Leffler
Поддержка функций Приложения K за пределами мира Microsoft минимальна по причинам, изложенным в моем первом комментарии, и подробно изложена в перекрестном вопросе. Обратите внимание, что несколько лет назад (что означает, что все могло измениться), ведущий разработчик GNU LibC отказался поддержать добавление функций Приложения K к GNU LibC. Комитет POSIX также скептически относился к их достоинствам. Jonathan Leffler
Я надеюсь, что поддержка для нихявляется широко распространенный. Сначала я возмущался навязыванием Microsoft безопасных вариантов, но, присмотревшись, я вижу необходимость. Я пишу много кода, чтобы ответить на инженерные вопросы. Только моя команда имеет доступ к исходному коду, я единственный пользователь платформы, время выполнения более важно, чем безопасность (Мерфи когда-нибудь окажется другим). Несмотря на это, на практике (я предполагаю) более медленное выполнение безопасных вариантов, вероятно, незначительно; IO и манипуляции со строками редки в самых внутренних циклах. Однако я признаю свою вину в том, что я не описал разницу. riderBill
0

которые не имеют этой функции. Или используйте макрос для уменьшения аргументов на единицу и сопоставления со стандартной строковой функцией.

0

https://rurban.github.io/safeclib/.

Это независимая от платформы реализация Приложения K C11 поверх всех библиотек libc. Он в основном совместим с Windows sec_api. Windows немного отличается от спецификации с некоторыми функциями.

strncpy_s является одним из самых сложных API в sec_api. Windows не обнаруживает переполнение двух длин, а не совпадение двух строк. И что делать, когда 4-й аргумент count = 0 тоже сомнительный. Спецификацияhttp://en.cppreference.com/w/c/string/byte/strncpy говоритНулевое возвращаемое значение подразумевает ... что результат в s1 завершен нулем, но на окнах это неправильно. Это просто прерывается слишком рано. Смотрите, например, реализация вина:https://github.com/mirror/reactos/blob/master/reactos/lib/sdk/crt/wine/heap.c#L577

И для_s Безопасный суффикс следует предполагать, что неправильно скопированные байты в буфер назначения очищаются от посторонних глаз при возникновении ошибки во время выполнения. Не так на винде с их sec_api. Они просто установили самый первый байт в 0.

https://github.com/rurban/safeclib/releases

1

Apache Portable Runtime проект:

Задача проекта Apache Portable Runtime (APR) - создавать и поддерживать библиотеки программного обеспечения, которые обеспечивают предсказуемый и согласованный интерфейс для базовых реализаций, специфичных для платформы.

autoconf также может позаботиться о некоторых из этих специфических для платформы различий (установив #defines и т. д.), хотя мой опыт работы с ним под Windows оставляет желать лучшего.

3

Если вы действительно хотите программировать на C:

Используйте простой старый стандартstrncpy.

Если вы программируете на C ++:

Используйте простой старый стандартный класс строкstd::string.

(подсказка: вы, вероятно, хотите последнее. Строки C - это просто ошибки, ожидающие появления, даже если вы используете «безопасный»*_s функции. C ++ добавил строковый класс по причине)

Похожие вопросы