J'ai un problème avec la programmation en C, en particulier avec fopen dans Visual Studio. J'ai lu sur la fonction fopen_s
et ajouté la ligne suivante à mon projet, mais cela ne fonctionne toujours pas.
_CRT_SECURE_NO_WARNINGS
J'ai donc essayé d'utiliser fopen_s
de cette façon:
FILE *fp;
errno_t err;
if ((err = fopen_s(&fp, "C:/File.txt", "rt")) != 0)
printf("File was not opened\n");
else
fprintf(fp, "Date: %s, Time: %s, Score: %i \n", __DATE__, __TIME__, score);
fclose(fp);
Il s'écrase toujours. Qu'est-ce qui ne va pas?
Vous utilisez fclose
avec une valeur fp
invalide, même si l'ouverture a échoué. Ajoutez au moins {}
autour de la branche else
.
De nombreux développeurs pensent que c'est généralement une bonne idée d'utiliser des accolades partout, même avec une seule déclaration à l'intérieur. Il est si facile de commettre une telle erreur si vous ne le faites pas, même pour des développeurs expérimentés. Alors mettez-les autour de la branche puis aussi.
Les fonctions _s
sont des inventions Microsoft non transférables qui, pour la plupart, dupliquent des fonctionnalités qui existaient déjà sous un nom plus portable. De plus, le passage aveugle de la variante non -_s
d'une fonction à la variante _s
résout généralement non rien. (Par exemple, tronquer silencieusement une chaîne est moins désastreux qu'empiler la pile, mais il reste que le comportement incorrect peut être exploitable.)
Votre problème - qui n'est pas affecté par la différence entre fopen
et fopen_s
- est presque certainement que vous ne prenez pas la peine de vérifier les erreurs correctement. Voici comment vérifier les erreurs correctement:
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main(int argc, char **argv)
{
FILE *fp;
if (argc != 2) {
fprintf(stderr, "usage: %s filename\n", argv[0]);
return 2;
}
fp = fopen(argv[1], "rb");
if (!fp) {
fprintf(stderr, "opening %s: %s\n", argv[1], strerror(errno)); // HERE
return 1;
}
// use 'fp' here...
return 0;
}
Notez que la ligne marquée // HERE
imprime les deux la chaîne exacte transmise à fopen
et le résultat de strerror(errno)
. Il est absolument essentiel d’imprimer les arguments et strerror(errno)
lorsqu’un appel système échoue. (Remarque: si vous utilisez une des fonctions _s
qui renvoie un code d'erreur plutôt que de définir errno
, vous devez alors passer la valeur de retour à strerror
.)
Modifiez votre programme pour faire cela et vous pourrez comprendre pourquoi cela ne fonctionne pas.
Sous Windows, les barres obliques sont différentes de celles sous Linux, vous pouvez donc envisager d’utiliser C:\File.txt au lieu de C: /File.txt.
// donne un coup de feu, ça marche.
#include <stdio.h>
#include <tchar.h>
#include<iostream>
using namespace std;
int main()
{
int score = 10;
FILE *fp;
errno_t err;
if ((err = fopen_s(&fp, "C:\\Users\\achea\\Desktop\\File.txt", "w+")) != 0)
{
printf("File was not opened\n");
}
else
{
fprintf(fp, "Date: %s, Time: %s, Score: %i \n", __DATE__, __TIME__,
score);
}
fclose(fp);
return 0;
}