What are some alternatives to the Microsoft security enhanced functions such as strncpy_s
or _itoa_s
? Although developing in MS environment the goa
I think @codeLizard is asking about how to write compatible code to handle all the functions that Microsoft has deprecated in favor of their secure versions, not just the string functions.
Functions based on Microsoft's secure functions are included in Annex K of the C11 standard, but the annex is not widely supported outside of MSVS.
You can write macros and inline functions in an include file to map back and forth between some of the traditional and secure versions. I posted a set of conversion macros here, If you want to copy them, get them from the liked page; more complete, better comments than below.
However, the approach doesn't work for mapping traditional functions to the secure versions that take size arguments unless the size arguments are also present in the traditional functions. Also, the secure functions differ in exception behaviors, and sometimes in return values. My current conversions don't account for that. When I have time, I'll attempt to improve them where I can to do just that. In the meantime, I'll leave it as an exercise for the reader.
I recommend using the secure functions in new code if you can, use the macro plus function solution if portability to non-MS compilers if required, and also as a bridge for reusing legacy code until you have time to update it with the secure functions.
Here is an abbreviated version of the above linked macro / inline function approach:
#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
As far as I understand, strncpy_s has no complex logic: just takes minimum of string length, source and destination data sizes and copies resulting amount of chars into destination. If you need it so much, why not to implement it yourself?
Rageous is correct, there is no complex logic behind it.
I would just use Microsoft's version for now and if you decide to port to another OS later, THEN implement it yourself for the target platform and use preprocessor commands to specify your implementation on the non-Windows platform(s).
Try strlcpy. Though not standard C, it exists on a number of platforms and you can download implementations as the source code is available free of charge. See http://www.gratisoft.us/todd/papers/strlcpy.html