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

Visual C++ Discussion :

problème accès aux fichiers include ou au fichiers à lire à l'exécution


Sujet :

Visual C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Retraité
    Inscrit en
    Mars 2004
    Messages
    150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Mars 2004
    Messages : 150
    Par défaut problème accès aux fichiers include ou au fichiers à lire à l'exécution
    Bonjour à tous,

    J'ai posté le message suivant dans le mauvais forum, de plus dans un sujet dit "résolu". Je pense qu'il a de ce fait peu de chance d'être lu par quelqu'un.
    Je le poste donc à nouveau, j'espère au bon endroit.

    Ce qui suit concerne des programmes "console".

    Depuis quelque temps (à vrai dire je ne sais pas bien depuis quand, car j'ai parfois de longues périodes sans rien coder), donc peut-être quelques semaines ou deux ou trois mois, j'ai des problèmes avec mes #include lorsque les fichiers en question ne sont pas dans le même dossier que mon fichier .cpp. Le système me répond systématiquement que le fichier en question n'existe pas.

    Même problème avec les library.

    Même problème avec les fichiers qui doivent être ouverts à l'exécution (avec fopen_s) qui ne sont pas dans le même dossier que celui qui contient le .exe.

    Je précise que ces nombreux programmes qui ne marchent plus, ont marché de nombreuses années : subitement un programme qui marchait correctement, ne marche plus et on me dit à chaque fois "impossible d'ouvrir le fichier xxx, ce fichier n'existe pas".

    À chaque fois, je contourne le problème avec un copier-coller à la main dans mon code .cpp ou en copiant le fichier à inclure dans le même dossier que celui de mon .cpp, s'il s'agit d'un include, ou en copiant le fichier que je voulais ouvrir à l'exécution dans le même dossier que celui où se trouve mon .exe.

    Mais, c'est pénible...

    Je suppose que quelque chose a changé dans la syntaxe d'appel de fichiers, soit des fichier à inclure dans le code, soit des fichiers à lire à l'exécution, mais quoi ? Qu'est-ce qui a changé ?

    S'il y a une nouvelle syntaxe, je m'y conformerai, mais justement, j'ignore quelles sont les nouvelles règles !

    Merci d'avance pour toute aide.

  2. #2
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 438
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 438
    Par défaut
    Vous faites beaucoup d'erreurs et d'imprécisions dans votre demande d'aide.
    J'ai l'impression que vous êtes un novice en C++ (et en C) malgré vos plus de 21 ans de présence sur ce site.

    Le fait que vous ayez posté dans un forum "Visual C++" n'indique donc pas forcément que vous utilisez "Visual Studio" comme IDE, n'est-ce pas ?

    La gestion des fichiers d'inclusion dans un IDE et les chemins de fichier à l'exécution d'un programme n'ont pas grand-chose en commun, donc les mettre "à égalité" dans une demande d'aide semble montrer une complète méconnaissance de leurs fonctionnements respectifs.

    Je suppose que quelque chose a changé dans la syntaxe d'appel de fichiers, soit des fichier à inclure dans le code, soit des fichiers à lire à l'exécution, mais quoi ? Qu'est-ce qui a changé ?
    Ça sent plus un truc qui est "tombé en marche" depuis des années et que vos jours de chance se sont taris.

    S'il y a une nouvelle syntaxe, je m'y conformerai, mais justement, j'ignore quelles sont les nouvelles règles !
    Pas de nouvelle syntaxe ou règles, mais j'ai l'impression que vous ne connaissiez pas les "anciens" => "tombé en marche".

    Ce qui suit concerne des programmes "console".
    Rien de ce que vous présentez dans votre message n'a de spécificité "console".
    Vos jours de chance ne sont vraisemblablement pas encore tous taris en même temps.

    j'ai des problèmes avec mes #include lorsque les fichiers en question ne sont pas dans le même dossier que mon fichier .cpp
    Bizarrement, vous ne mentionnez pas la différence entre '#include "xxx.h"' et '#include <xxx.h>'. La seconde forme étant à privilégier en cas d'utilisation de fichier d'en-tête "externe" au module (librairies, autres couches ou modules du projet).
    je suppute qu'un fichier "pas dans le même dossier" n'est pas dans le même module, donc, avez-vous bien utilisé la second forme dans ce cas-là ?
    L'utilisation de la première forme peut fonctionner un temps si votre IDE (Integrated Development Environment) est "bien" configuré (par chance ou par laxisme).

    Le système me répond systématiquement que le fichier en question n'existe pas.
    Qu'entendez-vous pas "système" ???
    Contrairement à l'accès aux fichiers à l'exécution d'un programme, le système d'exploitation n'a rien à voir (directement) avec la génération d'un exécutable ; qu'il soit console, fenêtré, driver, service, etc...
    C'est votre chaine de génération (préprocesseur + compilateur + éditeur de lien + optimiseur + etc... ) utilisé/configuré dans votre IDE qui est paramétrée pour savoir où aller chercher dans l'arborescence de fichier ces fichiers d'en-tête "externes".

    Comme vous n'avez jamais mentionné ni votre IDE ni votre chaine de génération, je suppose qu'ils étaient, par chance, "bien" configurés avant.
    Un simple anti-virus, un changement de variable d'environnement, une mise à jour des outils etc..., peut casser cet alignement de planètes qu'est votre "chance".

    Donc vérifiez que (ou apprenez à vous servir efficacement de) votre IDE et/ou chaine de génération soi(en)t correctement paramétré(s) pour vos projets.

    Même problème avec les library.
    cf. problème des fichiers d'en-tête "externes" ci-avant, ainsi que la problématique de la configuration de l'IDE que vous utilisez.

    Même problème avec les fichiers qui doivent être ouverts à l'exécution (avec fopen_s) qui ne sont pas dans le même dossier que celui qui contient le .exe.
    Cela n'a rien à voir avec les fichiers d'en-tête, et vous ne mentionnez pas le plus important : le répertoire de travail.
    Les chemins relatifs le sont par rapport au répertoire de travail, pas par rapport répertoire contenant l'exécutable.
    Il se peut que des OS mal configurés/sécurisés font croire que ce n'est pas important mais avec un patch de l'OS, vous vous retrouvez le bec dans l'eau.

    Je précise que ces nombreux programmes qui ne marchent plus, ont marché de nombreuses années :
    Probablement par chance, mais n'oublions pas qu'un anti-virus peut mettre en quarantaine tout et n'importe quoi, et cela, du jour au lendemain.
    Les mis à jour de sécurité peut aussi boucher un trou de sécurité que vous utilisez indirectement par inadvertance.

    subitement un programme qui marchait correctement, ne marche plus et on me dit à chaque fois "impossible d'ouvrir le fichier xxx, ce fichier n'existe pas".
    Si votre mode de lancement a changé le répertoire de travail ou qu'il ne fixe pas systématiquement (donc l'hérite d'un machin qui, lui, a évolué : variables d'environnement, liens, launcher, anti-virus, etc..), c'est "normale" que le "comportement" de votre programme change aussi.

    ou en copiant le fichier que je voulais ouvrir à l'exécution dans le même dossier que celui où se trouve mon .exe.
    C'est que votre système d'exploitation est toujours une passoire sécuritaire, et que votre programme est potentiellement un trou de sécurité.

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Mars 2004
    Messages : 150
    Par défaut
    Bonjour bacelar,

    Merci pour votre réponse rapide et particulièrement détaillée.

    Je pense que je vous dois quelques éclaircissements.

    Je suis aujourd'hui retraité. Et je suis effectivement un novice en C.

    J'utilise l'IDE Visual studio, pour visual C++. Mais je ne n'utilise que mes (maigres) connaissances en C.

    Notamment : 1-Pour ouvrir et lire un fichier "fich" situé dans le dossier D:\a\b\c
    j'ai jusqu'à présent utilisé la ligne

    fopen_s(&f,"D:\\a\\b\\c\\fich", "rb");

    2-Pour insérer des lignes de code situées dans le fichier "fichcode.h" du dossier D:\e\f\g pré-existantes à un programme en cours, j'ai jusqu'à présent utilisé l'instruction

    #include "D:\\e\\f\\g\\fichcode.h"

    Dans l'un et l'autre cas, ceci ne fonctionne plus chez moi. Même si
    La gestion des fichiers d'inclusion dans un IDE et les chemins de fichier à l'exécution d'un programme n'ont pas grand-chose en commun
    j'y ai vu quand même une similitude et j'ai pensé qu'à l'occasion d'une mise à jour certaines règles pour gérer l'accès aux fichiers avaient évolué.

    Votre conclusion
    les mettre "à égalité" dans une demande d'aide semble montrer une complète méconnaissance de leurs fonctionnements respectifs.
    est certes tout à fait correcte.

    C'est la raison pour laquelle je demande de l'aide...

    Bizarrement, vous ne mentionnez pas la différence entre '#include "xxx.h"' et '#include <xxx.h>'
    J'utilise la forme #include <xxx.h> également par ignorance. J'ai vu des exemples de cette forme dans l'aide de l'IDE. Et j'utilise parfois cette forme en supposant que le compilateur ira chercher dans un dossier par défaut :
    par exemple, pour utiliser la fonction _getch(), j'utilise #include <conio.h>
    et le compilateur va chercher <conio.h> quelque part. Je n'ai pas de problème à ce sujet.
    Mais pour ce qui concerne les include de mes fichiers, j'ai pensé qu'il me fallait bien préciser où le compilateur doit aller chercher ce fichier. Il semble que cela ait marché jusqu'à maintenant.

    Donc vérifiez que (ou apprenez à vous servir efficacement de) votre IDE et/ou chaine de génération soi(en)t correctement paramétré(s) pour vos projets.
    Excellente idée ; existe-t-il un tutoriel pour ça ? Que dois-je changer dans mes paramètres ?

    En cliquant sur Projet puis propriétés, il y a répertoires Include et aussi Répertoires Include externes et j'y trouve

    $(VC_IncludePath);$(WindowsSDK_IncludePath);
    Suis-je censé ajouter ici le répertoire où se trouve mon fichier include ?

    Par ailleurs, vous dites que cela n'a rien à voir, mais alors comment puis-je remplacer la ligne

    fopen_s(&f,"D:\\a\\b\\c\\fich", "rb");
    pour que ça marche...

    Merci en tous cas de votre aide.

  4. #4
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 438
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 438
    Par défaut
    Je suis aujourd'hui retraité. Et je suis effectivement un novice en C.

    J'utilise l'IDE Visual studio, pour visual C++. Mais je ne n'utilise que mes (maigres) connaissances en C.
    Attention, "Visual C++" aka MSVC n'est pas une chaine de génération C, mais C++.
    MSVC ne respecte pas les normes C mais les normes C++.
    Ce n'est donc pas un instrument à utiliser "sortie de l'étagère" pour faire du C "standardisé".

    Pour utiliser une chaine de compilation respectant les normes C et non C++ dans Visual Studio, cela représente, il me semble, un travail non négligeable et inaccessible à un débutant.

    Notamment : 1-Pour ouvrir et lire un fichier "fich" situé dans le dossier D:\a\b\c
    j'ai jusqu'à présent utilisé la ligne

    fopen_s(&f,"D:\\a\\b\\c\\fich", "rb");
    "fopen", c'est de l'accès au système de fichier au runtime, pas aux fichiers d'en-tête.
    Il s'agit d'un chemin absolu, car il commence par une lettre suivi de ":".
    Il n'est donc pas relatif au répertoire de travail du processus ( processus <> de l'exécutable).
    "fopen_s", c'est loin d'être un long fleuve tranquille (cassage de compatibilité ascendante, normalisation C, partage "lisible" ou pas, etc...):
    https://learn.microsoft.com/fr-fr/cp...?view=msvc-170
    Je ne vois pas de rapport avec le fait de mettre les fichiers dans le même répertoire que le fichier "image" du processus, mais des rustines de rétrocompatibilité ne sont pas à exclure.

    Moi, je n'utilise jamais ces primitives si bas niveau de l'API C de Win32 mais les API C++ "filesystem" standard, pour ne pas avoir à jongler avec des rustines.

    Question bête, le lecteur "D:" de vos chemin, c'est un "vrai" disque ou un mapping "réseau" ?
    Cela peut expliquer que ces chemins jadis "valides" ne le sont plus avec cette antiquité de "fopen_s" si la nature du lecteur "D:" ait changé.
    Par ailleurs, vous dites que cela n'a rien à voir, mais alors comment puis-je remplacer la ligne

    fopen_s(&f,"D:\\a\\b\\c\\fich", "rb");
    pour que ça marche...
    Commencez par comprendre pourquoi cela ne fonctionne pas.
    "D:" existe ?
    "D:" c'est un "vrai" disque ?
    "a" existe ?
    etc...
    Avec la documentation de "fopen_s", on voit que les cas qui déconnent avec cette antiquité, c'est pas ce qui manque.

    2-Pour insérer des lignes de code situées dans le fichier "fichcode.h" du dossier D:\e\f\g pré-existantes à un programme en cours, j'ai jusqu'à présent utilisé l'instruction

    #include "D:\\e\\f\\g\\fichcode.h"
    La différence entre '#include "xxx.h"' et '#include <xxx.h>', c'est que la première formule indique qu'il faut commencer la recherche du fichier "xxx.h" comme un chemin relatif au répertoire contenant le fichier en cours de compilation (le fichier .cpp ou .c) => donc "xxx.h" c'est rechercher dans "./xxx.h" avec "." le répertoire contenant le fichier .c ou .cpp en cours de compilation.
    Si le fichier "./xxx.h" n'est pas trouvé dans le même répertoire que le fichier .c ou .cpp, le préprocesseur commence à regarder dans les répertoires indiqués dans la "liste des répertoires d'include" jusqu'à le trouver (donc l'ordre dans cette liste est importante), puis dans la "liste des répertoires d'include externes".
    Avec '#include <xxx.h>', on indique au compilateur qu'il ne faut pas chercher à partir du répertoire contenant le fichier .c ou .cpp en cours de compilation mais directement dans la "liste des répertoires d'include".
    Il est donc assez absurde de mettre un chemin absolu dans un #include.
    La démarche, c'est d'utiliser des '#include "../module/sousmodule/xxx.h"' pour des fichiers d'en-tête "interne" au projet ; et des '#include <module/sousmodule/xxx.h>' pour des fichiers d'en-tête externes, en ajoutant les racines des modules externes dans la "liste des répertoires d'include externe". Pour un "gros" projet, vous pouvez aussi fixer un répertoire interne au projet comme "racine" des fichiers d'en-tête du projet et ajouter ce répertoire dans la liste des répertoires d'include "internes".

    J'utilise la forme #include <xxx.h> également par ignorance. J'ai vu des exemples de cette forme dans l'aide de l'IDE. Et j'utilise parfois cette forme en supposant que le compilateur ira chercher dans un dossier par défaut :
    par exemple, pour utiliser la fonction _getch(), j'utilise #include <conio.h>
    et le compilateur va chercher <conio.h> quelque part. Je n'ai pas de problème à ce sujet.
    Cela montre que la "liste des répertoires d'include externe" de vos projets sont assez bien configurées "de base".

    En cliquant sur Projet puis propriétés, il y a répertoires Include et aussi Répertoires Include externes et j'y trouve

    $(VC_IncludePath);$(WindowsSDK_IncludePath);
    Suis-je censé ajouter ici le répertoire où se trouve mon fichier include ?
    Non, pas ceux de votre projet, uniquement les répertoires des bibliothèques externes que vous utilisez dans votre projet, si elles n'y sont pas encore.

    Pour les fichiers d'include de votre projet, utilisez la forme '#include "/toto/xxx.h"' avec un chemin relatif au répertoire contenant le fichier en cours de compilation. Comme déjà indiqué, pour un "gros" projet, vous pouvez aussi fixer un répertoire interne au projet comme "racine" des fichiers d'en-tête du projet et ajouter ce répertoire dans la liste des répertoires d'include "internes".

    j'y ai vu quand même une similitude et j'ai pensé qu'à l'occasion d'une mise à jour certaines règles pour gérer l'accès aux fichiers avaient évolué.
    C'est parce que vous utilisez mal les mécanismes #include et que si une mise à jour "casse" un lecteur ou un chemin "en dur", c'est tous ces bugs latents qui vous arrivent à la figure.

    Mais pour ce qui concerne les include de mes fichiers, j'ai pensé qu'il me fallait bien préciser où le compilateur doit aller chercher ce fichier. Il semble que cela ait marché jusqu'à maintenant.
    Pas avec un chemin absolu en dur, ça fonctionnait par chance. Imaginez si vous vouliez déplacer le code source ailleurs sur votre disque ?

    Excellente idée ; existe-t-il un tutoriel pour ça ? Que dois-je changer dans mes paramètres ?
    Vous avez trouvez les propriétés du projet, vous reste à comprendre comment ça marche.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 391
    Par défaut
    Selon la version de Visual Studio, le "répertoire courant" par défaut lors de l'exécution du programme n'est pas le même, mais normalement on peut le régler explicitement dans les options du projet.
    Mais tu peux déjà commencer par déterminer empiriquement quel est ce répertoire, en utilisant _getwcd() ou GetCurrentDirectory() dans l'exécution du programme...
    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.

  6. #6
    Membre confirmé
    Homme Profil pro
    Retraité
    Inscrit en
    Mars 2004
    Messages
    150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Mars 2004
    Messages : 150
    Par défaut
    Vous avez trouvez les propriétés du projet, vous reste à comprendre comment ça marche.
    Oui, mais je ne comprends pas grand-chose aux propriétés.

    J'ai essayé d'ajouter le répertoire où se trouve une librairie appelée par mon code, l'éditeur de lien ne se plaint plus de l'absence de ma librairie, mais désormais il se plaint de l'absence d'un autre librairie ("Kernel qqchose"); j'avais pourtant ajouté ma librairie à la fin, après les librairies déjà indiquées. Donc ça ne va pas non plus.

    Existe-t-il un tuto qui explique ce que je dois changer dans les propriétés, et comment les changer ?

    Finalement la ligne
    fopen_s(&f,"D:\\a\\b\\c\\fich", "rb")
    est-elle vraiment un sacrilège ? Que dois-je faire pour que ce soit bien compris (et accepté) par l'ID ?

    cet alignement de planètes
    se reproduira-t-il ?

    P.S. Le D: fait effectivement référence à un disque dur. Mais ce genre de référence à un fichier d'un support quelconque C:, D:, E: (clé USB,CD) m'est tout à fait coutumier. Tout cela marchait bien (par chance ?), et cela ne marche plus.

Discussions similaires

  1. Temps d'acces aux fichiers liés...
    Par PAUL87 dans le forum Access
    Réponses: 2
    Dernier message: 08/12/2005, 15h08
  2. [Applet] Accès aux fichiers
    Par alabakan dans le forum Applets
    Réponses: 2
    Dernier message: 21/10/2005, 09h33
  3. [Upload] Date de dernier accès aux fichiers...
    Par John@EuroDevz dans le forum Langage
    Réponses: 10
    Dernier message: 08/04/2005, 10h57
  4. [Tomcat]Droit d'accès aux fichiers créés par une servlet
    Par loulouleboss dans le forum Tomcat et TomEE
    Réponses: 7
    Dernier message: 15/07/2004, 14h32
  5. [Réseau] Autorisations d'accès aux fichiers
    Par Pedro dans le forum API, COM et SDKs
    Réponses: 7
    Dernier message: 19/05/2004, 13h43

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