IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Discussion :

Problème pour réécrire sur un fichier existant


Sujet :

Windows

  1. #1
    Membre régulier
    Homme Profil pro
    Retraité
    Inscrit en
    Mars 2004
    Messages
    137
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 75
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Mars 2004
    Messages : 137
    Points : 116
    Points
    116
    Par défaut Problème pour réécrire sur un fichier existant
    Bonjour à tous !

    Je suis en train de découvrir Windows 11 (après Windows 7, ça change !) ainsi que le nouveau Visual C++, dont je n'utilise que C, en fait.

    J'ai un programme qui modifie le contenu d'un fichier. Il marchait bien avant, avec l'ancien (très ancien) Visual C++ que j'utilisais sous Windows 7, mais ça, c'était avant. J'ai constaté que le nouveau Visual C++ était beaucoup plus strict que l'ancien et j'ai donc dû modifier mes programmes. Le programme dont il est question est censé modifier le contenu de certains bytes d'un fichier déjà existant. Pour faciliter la compréhension, j'ai créé un minuscule programme pour montrer le problème.

    Je pars de ce programme :

    #include <iostream>
    FILE* a;

    int main()
    {
    fopen_s(&a, "aa.txt", "wb");
    char t = 1;
    for (int h = 0; h < 10; h++) fwrite(&t, 1, 1, a);
    fclose(a);
    }

    Après exécution, j'obtiens un fichier de longueur 10 bytes :
    adresses 0 1 2 3 4 5 6 7 8 9 a b c d e f

    0000(0000) 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0

    Ensuite, je crée un autre programme, tout aussi microscopique :

    #include <iostream>
    FILE* a;

    int main()
    {
    fopen_s(&a, "aa.txt", "a+b");
    fseek(a, 0, SEEK_SET);
    char t = 2;
    for (int h = 0; h < 10; h++) fwrite(&t, 1, 1, a);
    fclose(a);
    }

    Ce programme a pour but de remplacer les 1 par des 2. Mais le contenu du fichier est devenu :

    adresses 0 1 2 3 4 5 6 7 8 9 a b c d e f

    0000(0000) 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2
    0016(0010) 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0

    Et le fichier a pour longueur 20

    Ma question est : Qu'ai-je mal fait ?

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Le mode d'ouverture "a" (append) empêche d'écrire ailleurs qu'à la fin du fichier (même si tu fais un fseek avant).
    Si tu veux supporter lecture et écriture n'importe où, il faut ouvrir en "r+" (ou dans le cas actuel, "r+b").

    Citation Envoyé par La norme, Ch 7.19.5.3 §5 (C99) et 7.21.5.3 §6 (C11)
    Opening a file with append mode ('a' as the first character in the mode argument)
    causes all subsequent writes to the file to be forced to the then current end-of-file,
    regardless of intervening calls to the fseek function.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre régulier
    Homme Profil pro
    Retraité
    Inscrit en
    Mars 2004
    Messages
    137
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 75
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Mars 2004
    Messages : 137
    Points : 116
    Points
    116
    Par défaut Merci
    Merci de ta réponse.

    Comme je l'ai dit plus haut, le minuscule extrait que j'ai fourni n'était qu'une petite partie du programme qui me posait problème. Et comme un idiot, j'ai fait une erreur en recopiant la commande open_s.

    Donc, merci, tu avais raison, il faut écrire r+b et pas a+b. Le problème en fait, c'est que c'était bien écrit "r+b" dans le programme qui me gênait. Le mini programme ci-dessus marche très bien avec ta correction.

    C'est en fait l'antivirus Norton qui a bloqué mon programme, et je ne sais toujours pas pourquoi. Ce qui est étrange, c'est que j'ai testé mon programme sur d'autres fichiers, et là, ça marche. Mais pour une raison inconnue, ça ne marche pas sur un autre fichier !

    Merci en tous cas pour ta réponse pertinente.

Discussions similaires

  1. Problème pour enregistrer sur un fichier.ini
    Par dura654 dans le forum Delphi
    Réponses: 2
    Dernier message: 21/06/2018, 15h20
  2. Réponses: 2
    Dernier message: 29/01/2018, 09h43
  3. problème pour regarder si un fichier existe en bash
    Par alaninho dans le forum Linux
    Réponses: 2
    Dernier message: 15/05/2012, 20h03
  4. [E-03] problème pour travailler sur 2 fichiers en même temps
    Par Emily2711 dans le forum Macros et VBA Excel
    Réponses: 11
    Dernier message: 24/02/2009, 12h06
  5. Problème de droits sur un fichier
    Par BenoitDenis dans le forum Langage
    Réponses: 8
    Dernier message: 14/02/2006, 16h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo