31

I have a C program that uses sprintf_s. It works fine in Windows, but when I compile my code in Linux it gives this error:

sprintf_s was not declared in this scope.

Why does this happen and how can I fix it?

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
SPB
  • 4,040
  • 16
  • 49
  • 62

6 Answers6

43

It's not standard, you won't find such function on Linux.

Standard function snprintf should have a similar semantics.

peoro
  • 25,562
  • 20
  • 98
  • 150
9

sprintf_s is only part of Annex K, an optional Annex to the C11 standard:

Annex K

...

K.2 Scope

  1. This annex specifies a series of optional extensions that can be useful in the mitigation of security vulnerabilities in programs, and comprise new functions, macros, and types declared or defined in existing standard headers.

...

K.3.5.3.6 The sprintf_s function

Synopsis

#define __STDC_WANT_LIB_EXT1__1
#include <stdio.h>
int sprintf_s(char * restrict s, rsize_t n,
const char * restrict format, ...);

(emphasis added)

It never made it into POSIX (or Linux) (and is not missed at all, there are even arguments about its usefulness in the committee).

For better portability, use snprintf which is part of the core standard and provides all the functionality you'll need.

Mark Amery
  • 143,130
  • 81
  • 406
  • 459
Deduplicator
  • 44,692
  • 7
  • 66
  • 118
9

sprintf_s is not part of the standard C library, so it is not portable, thus you are not able to use it in Linux. BUT you have snprintf, which is very similar and it should help you to accomplish what you want.

gnclmorais
  • 4,897
  • 5
  • 30
  • 41
6

sprintf_s is not part of the standard C library, and you won't be able to use it in Linux.

However, snprintf is standard and should do the same task.

1

During a porting of my program from Windows to Linux, I wrote following implementation in my own windows.h:

inline int sprintf_s(char* buffer, size_t sizeOfBuffer, const char* format, ...)
{
    va_list ap;
    va_start(ap, format);
    int result = vsnprintf(buffer, sizeOfBuffer, format, ap);
    va_end(ap);
    return result;
}

template<size_t sizeOfBuffer>
inline int sprintf_s(char (&buffer)[sizeOfBuffer], const char* format, ...)
{
    va_list ap;
    va_start(ap, format);
    int result = vsnprintf(buffer, sizeOfBuffer, format, ap);
    va_end(ap);
    return result;
}
Andrey
  • 927
  • 11
  • 12
  • 1
    There are many C11 features missing: Argument checks, error handling, %n checks, restrict. The return value must not exceed sizeOfBuffer. – rurban Oct 16 '17 at 10:19
0

snprintf is insecure, only sprintf_s is secure. snprintf does not guarantee to add a final \0, leading to possible subsequent overflows. look at https://github.com/rurban/safeclib for a proper implementation.

rurban
  • 4,025
  • 24
  • 27
  • 2
    *snprintf is insecure, only sprintf_s is secure. snprintf does not guarantee to add a final \0* [Not true](https://port70.net/~nsz/c/c11/n1570.html#7.21.6.5): "... output characters beyond the n-1st are discarded rather than being written to the array, and a null character is written at the end of the characters actually written into the array." – Andrew Henle Nov 17 '19 at 19:32