web-dev-qa-db-fra.com

sprintf_s n'a pas été déclaré dans cette étendue

J'ai un programme C qui utilise sprintf_s. Cela fonctionne bien sous Windows, mais lorsque je compile mon code sous Linux, cela donne cette erreur:

sprintf_s was not declared in this scope.

Pourquoi cela se produit-il et comment puis-je résoudre le problème?

18
SPB

Ce n'est pas standard, vous ne trouverez pas une telle fonction sur Linux.

La fonction standard snprintf devrait avoir une sémantique similaire.

28
peoro

sprintf_s ne fait pas partie de la bibliothèque standard C, elle n'est donc pas portable, vous ne pouvez donc pas l'utiliser sous Linux. MAIS vous avez snprintf, qui est très similaire et devrait vous aider à accomplir ce que vous voulez.

7
gnclmorais

sprintf_s ne fait pas partie de la bibliothèque standard C et vous ne pourrez pas l'utiliser sous Linux.

Cependant, snprintf est standard et doit effectuer la même tâche.

sprintf_s n'est qu'une partie de l'Annexe K, un Annexe facultative à la norme C11:

Annexe K

...

K.2 Portée

  1. Cette annexe spécifie une série d'extensionsfacultatifqui peuvent être utiles pour atténuer les vulnérabilités en matière de sécurité dans les programmes et comprendre de nouvelles fonctions, macros et types déclarés ou définis dans les en-têtes standard existants.

...

K.3.5.3.6 La fonction sprintf_s

Synopsis

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

(emphase ajoutée)

Il n’a jamais été intégré à POSIX (ni à Linux) (et n’est pas manqué du tout, il existe même des arguments sur son utilité au sein du comité).

Pour une meilleure portabilité, utilisez snprintf qui fait partie de la norme fondamentale et fournit toutes les fonctionnalités dont vous avez besoin.

4
Deduplicator

snprintf n'est pas sécurisé, seul sprintf_s est sécurisé. snprintf ne garantit pas l'ajout d'un\0 final, ce qui pourrait entraîner des débordements ultérieurs. Regardez https://github.com/rurban/safeclib pour une implémentation correcte.

1
rurban

Lors du portage de mon programme de Windows vers Linux, j’ai écrit après la mise en oeuvre dans mon propre 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;
}
0
Andrey