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

Lazarus Pascal Discussion :

Contrôler dans le code les chemins en fonction de l'OS [Lazarus]


Sujet :

Lazarus Pascal

  1. #1
    Rédacteur

    Avatar de naute
    Homme Profil pro
    Retraité
    Inscrit en
    Mars 2009
    Messages
    708
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Mars 2009
    Messages : 708
    Points : 2 924
    Points
    2 924
    Par défaut Contrôler dans le code les chemins en fonction de l'OS
    Bonjour .

    Actuellement, je change manuellement, dans mon code, les / en \ selon que je compile pour GNU-Linux ou Windows. C'est simple, bien sûr, mais pas satisfaisant, dans la mesure où, entre autre, il n'est pas rare que j'oublie de faire la modification avant la compilation.
    J'ai essayé un truc du genre:
    Code Pascal : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    {$ifdef Win32}
      separateur:='\'
    {else}
      separateur:='/';
    {$endif}
    mais ça ne fonctionne pas. Voilà comment ça se présente dans mon code (capture):

    Nom : ifdef.png
Affichages : 188
Taille : 6,1 Ko

    J'ai bien sûr déclaré la variable en amont.
    Code Pascal : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    var
      separateur: char;
    Je suppose que ça va en faire rire plus d'un mais faut être indulgent .

    Quelle est la procédure correcte à suivre (si elle existe, mais je pense que oui)? Merci d'avance pour vos réponses.

    Amicalement,

    naute.

  2. #2
    Membre éclairé

    Homme Profil pro
    Rédacteur technique (retraité)
    Inscrit en
    Octobre 2009
    Messages
    168
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 81
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Rédacteur technique (retraité)

    Informations forums :
    Inscription : Octobre 2009
    Messages : 168
    Points : 807
    Points
    807
    Par défaut
    Utilise la constante caractère DirectorySeparator de l'unité System qui correspond au caractère '/' ou '\' selon l'OS ciblé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mavar := 'un dossier' + DirectorySeparator + 'un fichier';

  3. #3
    Rédacteur

    Avatar de naute
    Homme Profil pro
    Retraité
    Inscrit en
    Mars 2009
    Messages
    708
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Mars 2009
    Messages : 708
    Points : 2 924
    Points
    2 924
    Par défaut
    Citation Envoyé par DomDA91 Voir le message
    Utilise la constante caractère DirectorySeparator de l'unité System qui correspond au caractère '/' ou '\' selon l'OS ciblé
    Merci beaucoup pour ta réponse rapide et pour ne pas avoir rigolé.

    Amicalement,

    naute.

  4. #4
    Expert confirmé
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Salut

    Juste au cas ou voici un petite fonction bien utile de ma bibliothèque, qui change le séparateur en fonction de l'OS :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    Uses SysUtils, LazUTF8;
     
    function FixPathDelimiter(S: string):String;
    var
      I: Integer;
    begin
      Result := S;
      for I := UTF8Length(Result) downto 1 do
      begin
        if (Result[I] = '/') or (Result[I] = '\') then
          Result[I] := PathDelim;
      End;
    end;
    A+
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  5. #5
    Rédacteur

    Avatar de naute
    Homme Profil pro
    Retraité
    Inscrit en
    Mars 2009
    Messages
    708
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Mars 2009
    Messages : 708
    Points : 2 924
    Points
    2 924
    Par défaut
    Bonjour BeanzMaster .

    Et merci! Je prend aussi . Les deux solutions ont chacune leurs avantages.

    Donc, si je comprend bien,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    PathDelim = DirectorySeparator
    C'est quand même bizarre d'avoir deux constantes représentant la même valeur. Une seule aurait suffit, non?

    Amicalement,
    naute.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    245
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 245
    Points : 534
    Points
    534
    Par défaut
    Bonjour,

    Citation Envoyé par BeanzMaster Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    Uses SysUtils, LazUTF8;
     
    function FixPathDelimiter(S: string):String;
    var
      I: Integer;
    begin
      Result := S;
      for I := UTF8Length(Result) downto 1 do
      begin
        if (Result[I] = '/') or (Result[I] = '\') then
          Result[I] := PathDelim;
      End;
    end;
    Cette fonction peut ne pas fonctionner correctement car UTF8Length retourne le nombre de caractères. Return[I] sélectionne le Iième "octet" de Result et non le Iième "caractère". Par exemple "C:/André/" retournera "C:\André/" au lieu de "C:\André\".
    Il doit être possible d'utiliser la fonction StringReplace, mais je la trouve trop sophistiquée pour remplacer seulement un caractère.
    Je préfère:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    function FixPathDelimiter(S:string;ToWin:Boolean=False):String;
    var
     I:Integer;
     Old:Char;
    begin
      {$ifdef windows}
      Old:='/';
      if ToWin then
        Result:=UTF8ToWinCP(S)
      else
        Result:=S;
      {$else}
      Old:='\';
      Result:=S;
      {$endif}
      for I:=1 to Length(Result) do
      begin
        if Result[I]=Old then
          Result[I]:=DirectorySeparator;
      end;
    end;
    où j'ai ajouté le paramètre ToWin pour effectuer si nécessaire la conversion en Ansi sous Windows. Certains composants de connexion à des bases de données par exemple, ne fonctionnent pas avec une adresse en UTF8.

    André

  7. #7
    Membre éclairé

    Homme Profil pro
    Rédacteur technique (retraité)
    Inscrit en
    Octobre 2009
    Messages
    168
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 81
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Rédacteur technique (retraité)

    Informations forums :
    Inscription : Octobre 2009
    Messages : 168
    Points : 807
    Points
    807
    Par défaut
    Citation Envoyé par naute
    C'est quand même bizarre d'avoir deux constantes représentant la même valeur. Une seule aurait suffit, non?
    DirectorySeparator est défini de base dans l'unité System.

    PathDelim est un alias redéfini dans l'unité SysUtils, laquelle est principalement prévue pour la compatibilité Delphi.

    Idem pour System.DriveSeparator et SysUtils.DriveDelim, System.PathSeparator et SysUtils.PathSep.

  8. #8
    Membre éclairé

    Homme Profil pro
    Rédacteur technique (retraité)
    Inscrit en
    Octobre 2009
    Messages
    168
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 81
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Rédacteur technique (retraité)

    Informations forums :
    Inscription : Octobre 2009
    Messages : 168
    Points : 807
    Points
    807
    Par défaut
    Une procedure similaire à FixPathDelimiter proposée ci-dessus existe déjà dans l'unité système sous le nom de DoDirSeparators. Maheureusement elle est déclarée dans la section implémentation et n'est donc pas disponible publiquement. Elle est déclinée pour divers types chaîne (ShortString, AnsiString, WideString, pchar, etc.).

    Par exemple voici son code pour ShortString et AnsiString (extrait de System.inc) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
    Interface
       Const = AllowDirectorySeparators : set of char = ['\','/'];
    ...
     
    Implementation
    ...
    procedure DoDirSeparators(var p:shortstring);
    var
      i : longint;
    begin
      for i:=1 to length(p) do
        if p[i] in AllowDirectorySeparators then
          p[i]:=DirectorySeparator;
    end;
     
    {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
    procedure DoDirSeparators(var ps:RawByteString);
    var
      i : longint;
      p : pchar;
      unique : boolean;
    begin
      unique:=false;
      for i:=1 to length(ps) do
        if ps[i] in AllowDirectorySeparators then
          begin
            if not unique then
              begin
                uniquestring(ps);
                p:=pchar(ps);
                unique:=true;
              end;
            p[i-1]:=DirectorySeparator;
          end;
    end;
    {$endif FPC_HAS_FEATURE_ANSISTRINGS}
    ...

  9. #9
    Expert confirmé
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par alanglet Voir le message
    Bonjour,



    Cette fonction peut ne pas fonctionner correctement car UTF8Length retourne le nombre de caractères. Return[I] sélectionne le Iième "octet" de Result et non le Iième "caractère". Par exemple "C:/André/" retournera "C:\André/" au lieu de "C:\André\".

    ...

    André
    Salut bien vu André Grosse erreur de ma part ou j'ai changé Length par UTF8LengthLe code suivant lui fonctionne sans problème :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function FixPathDelimiter(S: string):String;
    var
      I: Integer;
    begin
      Result := S;
      for I := Length(Result) downto 1 do
      begin
        if (Result[I] = '/') or (Result[I] = '\') then
          Result[I] := PathDelim;
      End;
    end;
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  10. #10
    Rédacteur

    Avatar de naute
    Homme Profil pro
    Retraité
    Inscrit en
    Mars 2009
    Messages
    708
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Mars 2009
    Messages : 708
    Points : 2 924
    Points
    2 924
    Par défaut
    beaucoup pour toutes ces mises au point. Elles m'ont fait réfléchir sur le codage UTF8.

    Je pensais qu'en UTF8, tous les caractères étaient codés sur 4 octets, et, sans aller chercher plus loin, je ne comprenais pas comment on pouvait discriminer les caractères ASCII purs. Après une rapide recherche sur wikipedia, j'ai la réponse. C'est la valeur des 1, 2 ou 3 bits de poids fort du premier (ou seul) octet qui détermine sur combien d'octet(s) est stocké le caractère.

    Ce qui fait que maintenant, je comprend, entre autre, la différence entre Length et UTF8Length, dont les résultats seront identiques uniquement sur de l'ASCII pur.

    La première réponse de DomDA91 solutionnait parfaitement et simplement mon problème puisque je construisais moi-même la chaîne représentant le chemin. Je garde par contre sous le coude les routines que vous me proposez pour le cas où j'aurais besoin de convertir un chemin complet.

    Merci encore

    Amicalement,
    naute.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Débutant] Chemin relatif dans les css et fonctions javascript
    Par misterdarth dans le forum ASP.NET MVC
    Réponses: 1
    Dernier message: 30/12/2016, 15h09
  2. Garder dans la mémoire les calculs des fonctions
    Par ROUGE87 dans le forum Général Java
    Réponses: 27
    Dernier message: 29/06/2011, 17h46
  3. Réponses: 7
    Dernier message: 22/04/2010, 15h45
  4. les fonctions static dans le code
    Par Arthis dans le forum C#
    Réponses: 13
    Dernier message: 25/03/2009, 11h44
  5. Réponses: 10
    Dernier message: 03/09/2004, 17h26

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