web-dev-qa-db-fra.com

fopen / fopen_s et écriture dans des fichiers

J'utilise fopen en C pour écrire la sortie dans un fichier texte. La déclaration de fonction est (où ARRAY_SIZE a été défini précédemment):

void create_out_file(char file_name[],long double *z1){  
  FILE *out;  
  int i;  

  if((out = fopen(file_name, "w+")) == NULL){  
    fprintf(stderr, "***> Open error on output file %s", file_name);  
    exit(-1);  
  }  

  for(i = 0; i < ARRAY_SIZE; i++)  
    fprintf(out, "%.16Le\n", z1[i]);  
  fclose(out);  
}  

Mes questions:

  1. Lors de la compilation avec MVS2008, j'obtiens l'avertissement: avertissement C4996: 'fopen': Cette fonction ou variable peut être dangereuse. Envisagez plutôt d'utiliser fopen_s. Je n'ai pas vu beaucoup d'informations sur fopen_s pour pouvoir changer mon code. Aucune suggestion?

  2. Peut-on demander à fprintf d'écrire des nombres avec la précision numérique souhaitée dans un fichier? Si j'utilise long double alors je suppose que mes réponses sont bonnes jusqu'à 15 chiffres après la virgule. Ai-je raison?

22
yCalleecharan

fopen_s est une variante de fopen qui contient la validation des paramètres et remet un code d'erreur au lieu d'un pointeur en cas de problème pendant le processus ouvert. Il est plus sécurisé que la variante de base car il représente plus de conditions Edge. Le compilateur vous avertit de l'utiliser car fopen représente un vecteur d'exploitation potentiel dans votre application.

Vous pouvez spécifier des chiffres de précision pour la famille de fonctions printf en utilisant le spécificateur %.xg, où x est le chiffre de précision souhaité dans la sortie. UNE long double varie en précision d'une plate-forme à l'autre, mais vous pouvez généralement parier qu'il s'agit d'au moins 16 chiffres de précision décimale.

Edit: Bien que je ne sois pas entièrement d'accord avec les autres qui suggèrent que fopen_s est une perte de temps complète , elle représente un risque d'exploitation assez faible et n'est pas largement prise en charge. Cependant, certaines des autres fonctions mises en garde sous C4996 sont des vulnérabilités beaucoup plus graves et utilisant _CRT_SECURE_NO_WARNINGS équivaut à désactiver l'alarme pour "vous avez laissé la porte de votre chambre déverrouillée" et "vous avez laissé une bombe nucléaire dans la cuisine".

Tant que vous n'êtes pas limité à l'utilisation du "C pur" pour votre projet (par exemple pour un travail scolaire ou un microcontrôleur intégré), vous feriez bien d'exploiter le fait que presque tous les compilateurs C modernes sont également des compilateurs C++ et utilisent le C++ iostream variantes de toutes ces fonctions d'E/S afin d'obtenir à la fois une meilleure sécurité et compatibilité en même temps.

20
Dan Story

J'ai rencontré un problème similaire en travaillant avec Visual Studio 2012, mais où mon problème s'est développé, je construisais un programme que je veux utiliser les cloches et les sifflets de Visual Studio pour tester et finalement pouvoir compiler et exécuter la même application sur mon Serveur Linux (je fais un bot)

c'est donc ce que j'ai trouvé après quelques recherches sur Google et j'ai pensé le publier au cas où cela pourrait aider quelqu'un d'autre.

FILE *fp_config;
const char *configfile ;
configfile = "bot.conf";
#ifdef WIN32
    errno_t err;
    if( (err  = fopen_s( &fp_config, configfile, "r" )) !=0 ) {
#else
    if ((fp_config = fopen(configfile, "r")) == NULL) {
#endif
        fprintf(stderr, "Cannot open config file %s!\n", configfile);
    }

cela apaisera Visual Studio et ne se plaindra pas et cela permettra également au même code de compiler sur gcc ou tout autre compilateur c/c ++ conforme aux normes

10
BrierMay
  1. fopen_s et toutes les autres fonctions _s sont des variantes "sécurisées" spécifiques à MS des fonctions standard. Si votre code n'a pas besoin d'être multiplateforme, vous pouvez simplement basculer et rendre le compilateur heureux. Sinon, ajoutez simplement le _CRT_SECURE_NO_WARNINGS directive préprocesseur dans les paramètres de votre projet et cela ne vous avertira plus.

  2. Oui, un double long est facilement bon pour 15 chiffres de précision; en fait, même les doubles réguliers sont assez bons pour ça (mais pas plus).

6
tzaman

D'autres affiches ont souligné que fopen n'est pas vraiment très dangereux. Si vous ne voulez pas cet avertissement, mais que vous voulez les autres qui avertissent des vulnérabilités réelles, ne faites pas #define _CRT_SECURE_NO_WARNINGS.

Au lieu de cela, la prochaine fois que vous obtenez l'avertissement fopen, cliquez sur la ligne qui dit "voir la déclaration de 'fopen'". Cela vous amènera à la ligne dans stdio.h qui injecte l'avertissement. Supprimez le texte _CRT_INSECURE_DEPRECATE(fopen_s) de cette ligne, et vous n'obtiendrez plus l'avertissement de sécurité lorsque vous utiliserez fopen, mais il restera pour strcpy, strdup et ceux éventuellement dangereux.

4
AShelly

Le passage de fopen à fopen_s a désactivé la possibilité d'ouvrir le fichier dans le bloc-notes (lecture seule) lorsque le fichier est ouvert et en cours d'écriture. Je reviens à fopen et je peux lire pendant que mon programme écrit le fichier.

4
eduard

Définissez simplement _CRT_SECURE_NO_WARNINGS avant d'inclure un fichier pour se débarrasser de ces avertissements et arrêter de croire à ce que MS dit à propos de fopen

1
Artyom