Каковы некоторые альтернативы расширенным функциям безопасности Microsoft, таким как strncpy_s
или _itoa_s
? Хотя разработка в среде MS является задачей написания кода, который легко переносится на другие платформы.
Альтернативы MS strncpy_s
Ответ 1
Ярость правильная, за ней нет сложной логики.
Я бы просто использовал версию Microsoft на данный момент, и если вы решите позже перейти на другую ОС, THEN внедрите ее самостоятельно для целевой платформы и используйте команды препроцессора, чтобы указать вашу реализацию на платформах, отличных от Windows.
Ответ 2
std::string s(Cstring, n);
Ответ 3
Если вы действительно хотите запрограммировать в C:
Используйте простой старый стандарт strncpy
.
Если вы программируете на С++:
Используйте простой стандартный класс строк std::string
.
(подсказка: вы, вероятно, захотите последнего. Строки C - это просто ошибки, ожидающие своего появления, даже если вы используете "безопасные" функции *_s
. С++ добавил класс строк по какой-то причине)
Ответ 4
Попробуйте strlcpy. Хотя он и не является стандартным C, он существует на нескольких платформах, и вы можете загружать реализации, поскольку исходный код доступен бесплатно. См. http://www.gratisoft.us/todd/papers/strlcpy.html
Ответ 5
Просто используйте strncpy и отключите предупреждение в VС++.
Ответ 6
Насколько я понимаю, strncpy_s не имеет сложной логики: просто берет минимум длины строки, размеры источника и места назначения и копирует итоговое количество символов в пункт назначения. Если вам это нужно, почему бы не реализовать его самостоятельно?
Ответ 7
Вам может быть интересен проект Apache Portable Runtime:
Миссия проекта Apache Portable Runtime (APR) заключается в создании и обслуживании программных библиотек, которые обеспечивают предсказуемый и последовательный интерфейс для базовых реализаций платформы.
autoconf также может позаботиться о некоторых из этих различий в конкретной платформе (установив #defines и т.д.), хотя мой опыт работы с ним под Windows оставляет желать лучшего.
Ответ 8
Я думаю, @codeLizard спрашивает о том, как написать совместимый код для обработки всех функций, которые Microsoft устарела в пользу своих безопасных версий, а не только строковых функций.
Функции, основанные на защищенных функциях Microsoft, включены в приложение К стандарта C11, но приложение не поддерживается широко за пределами MSVS.
Вы можете писать макросы и встроенные функции в файле include для сопоставления между традиционными и безопасными версиями. Я разместил набор макросов преобразования здесь. Если вы хотите скопировать их, получите их с любимой страницы; более полные, лучшие комментарии, чем ниже.
Однако этот подход не работает для сопоставления традиционных функций с безопасными версиями, которые принимают аргументы размера, если аргументы размера также не присутствуют в традиционных функциях. Кроме того, защищенные функции различаются по типу исключений, а иногда и в возвращаемых значениях. Мои текущие преобразования не учитывают этого. Когда у меня будет время, я попытаюсь улучшить их, где я могу это сделать. Тем временем я оставлю это упражнение для читателя.
Я рекомендую использовать защищенные функции в новом коде, если можно, используйте решение макросов плюс функция, если это необходимо для совместимости с компиляторами, отличными от 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
Ответ 9
Вы можете либо предоставить собственную реализацию для платформ, для которых эта функция отсутствует. Или используйте макрос, чтобы уменьшить аргументы по одному и сопоставить стандартную строковую функцию.
Ответ 10
Да, попробуйте https://rurban.github.io/safeclib/.
Это независимая от платформы реализация C11 Annex K поверх всех 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
следует предположить, что ошибочно скопированные байты в буфер назначения очищаются от любопытных глаз при возникновении ошибки времени выполнения. Не так в Windows с их sec_api. Они просто устанавливают самый первый байт в 0.