web-dev-qa-db-fra.com

Utiliser fopen_s en C

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?

9
nikodamn

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.

9
hyde

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.

4
zwol

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. 

1
binit92

// 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;
}
0
Achamyeleh Dagnaw