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

C Discussion :

Interprétation de l’étoile en argument


Sujet :

C

  1. #1
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2011
    Messages
    83
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 83
    Par défaut Interprétation de l’étoile en argument
    Bonjour,

    j'ai constaté que lorsque que l'on exécute un programme via la fenêtre DOS et que l'on rentre un chemin comme celui ci en argument: "C:\Windows\*", l'argument que le programme reçoit est non pas "C:\Windows\*" mais la liste de tout les fichiers et dossiers contenu dans "C:\Windows"

    Voici un code qui permet de le constater :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int main(int argc, char** argv)
    {   
        int i;
        for (i = 0; i < argc; i++)
        {
            printf("Parametre %d : %s\n",i,argv[i] );
        }
    }
    je souhaiterais recevoir exactement ce que saisie l'utilisateur en argument et non pas une interprétation.
    Est ce possible ?

  2. #2
    Membre Expert Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    791
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 791
    Par défaut
    Ben non.

    Faire pgm.exe c:\windows\* sous DOS donne bien ce que tu escomptes pour argv[1]: "c:\windows\*" (sans les guillemets)

  3. #3
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2011
    Messages
    83
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 83
    Par défaut
    je t'assure que tu te trompes edgarjacobs. si tu ne me crois pas compile ce code et exécute le :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #include <stdlib.h>
    #include <stdio.h>
     
     
    int main(int argc, char** argv)
    {   
        int i;
     
        printf("\n TEST ");
        for (i = 0; i < argc; i++)
        {
            printf("Parametre %d : %s\n",i,argv[i] );
        }
    }
    Avec pgm.exe c:\windows\* je reçoit 103 arguments me précisant tout le contenu de mon dossier Windows alors que je voudrais recevoir tel quelle ce que saisit l'utilisateur (sans interprétation)

    Pour information en argv[1] je reçois "c:\windows\addins"

  4. #4
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Arnau6, edgarjacobs : utilisez-vous les mêmes versions de Windows ?

    J'ai compilé le programme sous Linux Mint, je lui passes l'argument ./* et j'obtiens :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    pierre@pierre-mint:~/Documents/TestsC$ ./a.out ./*
     
     TEST Parametre 0 : ./a.out
    Parametre 1 : ./a.out
    Parametre 2 : ./commande.c
    Parametre 3 : ./commande.h
    Parametre 4 : ./commande.o
    Parametre 5 : ./fork_commandes_shell.c
    Parametre 6 : ./Includes
    Parametre 7 : ./main.c
    Parametre 8 : ./main.o
    Parametre 9 : ./test.c
    Parametre 10 : ./test.log
    Ce résultat me semble totalement logique car le shell interprète l'étoile qui veut dire "tout et n'importe quoi". Dans mon cas, ça donne tous les fichiers (et dossiers) du répertoire courant (.); dans le vôtre, ceux de votre dossier Windows.

    Pour confirmer cette interprétation par le shell, utilisons des guillemets simples qui servent à forcer le shell à ne pas interpréter ce qui se trouve encadré :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    pierre@pierre-mint:~/Documents/TestsC$ ./a.out './*'
     
     TEST Parametre 0 : ./a.out
    Parametre 1 : ./*
    Même effet avec des guillemets doubles.

    Même si le shell de Windows n'est pas le bash de Linux Mint, un fonctionnement semblable me parait être très logique et cohérent !

  5. #5
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2011
    Messages
    83
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 83
    Par défaut
    Merci pour cette réponse mais les simple ' ne permettent pas de saisir des chaines de caractères comme avec des "
    Ceci se constate lors qu'il y a des espaces dans le chemin. par exemple avec 'C:\Program Files (x86)'
    mon argv[1] est : 'C:\Program
    mon argv[2] est : Files
    et mon argv[3] est : (x86)'

    Est il possible d’empêcher toute interprétation des arguments pour recevoir exactement ce qui est saisi ?

  6. #6
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Je t'avoue que j'ai un peu la flemme de booter sur Windows pour tester.

    En tout cas avec Linux (Bash) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    pierre@pierre-mint:~/Documents/TestsC$ ./a.out "Mon Dossier/*"
     
     TEST Parametre 0 : ./a.out
    Parametre 1 : Mon Dossier/*
    Idem avec des guillemets simples. As-tu essayer avec des guillemets doubles ?

    Tu peux aussi essayer de "banaliser" (?) l'espace :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    pierre@pierre-mint:~/Documents/TestsC$ ./a.out Mon\ Dossier/*
     
     TEST Parametre 0 : ./a.out
    Parametre 1 : Mon Dossier/*

  7. #7
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2011
    Messages
    83
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 83
    Par défaut
    Oui j'ai essayé avec des guillemets double

    Je ne comprends pas ce que tu veux dire avec :
    Tu peux aussi essayer de "banaliser" (?) l'espace
    Peux tu développer s'il te plait.

  8. #8
    Membre Expert
    Inscrit en
    Avril 2010
    Messages
    1 495
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 1 495
    Par défaut
    Salut,

    Je confirme pour Bktero...

    Arnau6, quelle est ta version de Windows ???

    Parce que sous le Shell Windows, la logique, c'est que toute expression entre guillemets (doubles) est une chaine de caractères, à coup de renfort du caractère d'échappement dans certains contextes, sans ça l'astérisque est interprété et étendu si Windows trouve une correspondance dans les fichiers... donc, on met les guillemets doubles si on ne veut pas d'interprétation, et au contraire, pas de guillemets si on veut que ça soit interprété, si le chemin contient plus d'un espace, alors on utilise les noms courts... tout ça, c'est inhérent au Shell, et pas vraiment en rapport direct avec l'EXE, donc c'est à l'utilisateur de faire en sorte de passer les bons paramètres, mais bien sûr il convient de lui fournir une aide explicite et des exemples...sinon il faut repenser le programme en utilisant des arguments nommés par exemple...

  9. #9
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Arnau6 Voir le message
    Oui j'ai essayé avec des guillemets double.
    Et ce n'est pas suffisant ? Le post de minnesota semble dire que non.

    Citation Envoyé par Arnau6 Voir le message
    Je ne comprends pas ce que tu veux dire avec : "Tu peux aussi essayer de "banaliser" (?) l'espace "
    Peux tu développer s'il te plait.
    As-tu lu l'extrait de code que j'ai donné ? As-tu remarqué que je ne mets pas de guillemets mais un \ ? En effet, dans le contexte du shell, l'espace est considérée comme un séparateur entre les arguments et non comme un caractère normal d'une chaine. Il faut donc le "banaliser" (le vrai terme doit en effet être "échapper", merci minnesota ^^) pour modifier le comportement du shell si les guillemets ne suffisent pas. Et encore comme l'a dit minnesota, tu devras peut-être combiner les 2. Il faut peut-être aussi banaliser l'étoile.

    Encore avec bash :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    pierre@pierre-mint:~/Documents/TestsC$ ./a.out "Mon\ Dossier/""\*"
     
     TEST Parametre 0 : ./a.out
    Parametre 1 : Mon\ Dossier/\*
    pierre@pierre-mint:~/Documents/TestsC$ ./a.out "Mon\ Dossier/"\*
     
     TEST Parametre 0 : ./a.out
    Parametre 1 : Mon\ Dossier/*

  10. #10
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2011
    Messages
    83
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2011
    Messages : 83
    Par défaut
    J'ai essayé les autres syntaxes mais le résultat est le même. Ma version de Windows est : Windows 7 édition familiale premium.
    Je vais repenser la syntaxe de mon programme afin de faire en sorte que l'on ai pas besoin d'utiliser le symbole *

  11. #11
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Re ! J'ai enfin démarré sous Windows (Seven, je crois Pro) pour tester. Je n'ai pas réussi.... L'interpréteur de cmd.exe est vraiment miteux. Demande dans un forum dédié à Windows ou alors change la technique de passage des arguments. Désolé ^^

  12. #12
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    De mémoire -- je n'ai plus programmé pour Windows depuis 1994, tout ce que je sais date d'alors ou bien c'est des choses que j'ai lues sur les forums --, l'interprétation de * sous Windows n'est pas faite par l'interpréteur de commande (du moins tant qu'on n'utilise pas un shell unix), mais par le runtime C; il faudrait voir s'il n'y a pas moyen de la désactiver.

  13. #13
    Membre Expert
    Inscrit en
    Avril 2010
    Messages
    1 495
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 1 495
    Par défaut
    Exact, je viens de regarder et en effet l'interpréteur de commande étend l'astérisque aux correspondances, lorsqu'elles existent, uniquement pour les commandes internes, mais pas les "commandes" externes... pour celles-là, c'est la CRT qui s'en occupe...(en config par défaut en tout cas) (aussi, bien que le mode opératoire est différent, on est, à mon sens, physiquement pas très loin du shell... je sais pas comment tu interpréterais ça Jean-Marc... ??? ).

    Donc je disais, dans un projet c++, sur Windows, l'expansion est activée par défaut, dans un projet c, ça semble être l'inverse, à confirmer...

    Pour désactiver l'expansion sur gcc/mingw c'est très simple, il suffit de définir et initialiser la variable globale int _CRT_glob = 0; (crt_glob=0 pour "no globbing", vraisemblablement "no global file-name", enfin je pense) ou faire une liaison avec "crt_noglob.o", pour visual et autres EDI qui en utilise ou partages les Lib, je vous laisse lire ce que dit msdn : http://msdn.microsoft.com/en-us/libr...=vs.71%29.aspx
    http://msdn.microsoft.com/en-US/libr...=vs.80%29.aspx

    et les deux extraits plus bas...

    à noter qu'il est possible de récupérer la ligne de commande avec des fonctions Win32 comme GetCommandLine et CommandLineToArgv sans avoir à détourner la fonction _setargv... mais j'ai pas approfondi plus que ça...


    C Language Reference
    Expanding Wildcard Arguments
    Microsoft Specific —>
    When running a C program, you can use either of the two wildcards — the question mark (?) and the asterisk (*) — to specify filename and path arguments on the command line.
    Command-line arguments are handled by a routine called _setargv (or _wsetargv in the wide-character environment), which by default does not expand wildcards into separate strings in the argv string array. You can replace the normal _setargv routine with a more powerful version of _setargv that does handle wildcards by linking with the Setargv.obj file. If your program uses a wmain function, link with Wsetargv.obj.
    To link with Setargv.obj or Wsetargv.obj, use the /link option. For example:
    cl typeit.c /link setargv.obj
    The wildcards are expanded in the same manner as operating system commands. (See your operating system user's guide if you are unfamiliar with wildcards.) Enclosing an argument in double quotation marks (" ") suppresses the wildcard expansion. Within quoted arguments, you can represent quotation marks literally by preceding the double-quotation-mark character with a backslash (\). If no matches are found for the wildcard argument, the argument is passed literally.
    END Microsoft Specific
    C++ Language Reference
    Wildcard Expansion
    Microsoft Specific
    You can use wildcards — the question mark (?) and asterisk (*) — to specify filename and path arguments on the command line.
    Command-line arguments are handled by a routine called _setargv. By default, _setargv expands wildcards into separate strings in the argv string array. If no matches are found for the wildcard argument, the argument is passed literally.
    END Microsoft Specific

  14. #14
    Membre très actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2010
    Messages
    434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2010
    Messages : 434
    Par défaut
    bonjour,

    Pourquoi tu ne lis pas l'entrée standard?

  15. #15
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    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 397
    Par défaut
    Microsoft Visual Studio 2010 SP1 sous Windows 7 Pro, Win32 Console Application, Empty Project, copy-paste du code dans un .c (avec ajout du stdio.h):
    Code CMD.EXE : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    D:\MesDocs\Visual Studio 2010\Projects\TestsSous2010\Debug>SimpleCommandLineTest C:\Windows\*
    Parametre 0 : SimpleCommandLineTest
    Parametre 1 : C:\Windows\*
     
    D:\MesDocs\Visual Studio 2010\Projects\TestsSous2010\Debug>
    Même code sous Visual C++ 6.0 SP6 sous le même OS: Même résultat.

    Comme je n'ai jamais modifié ces paramètres, cela confirme que la CRT n'étend pas les astérisques par défaut (le premier extrait de la doc disent que l'extension n'a lieu que si l'on ajoute explicitement setargv.obj au projet).

    Edit: Et si je fait l'ajout en question (juste rajouter setargv.obj dans l'onglet "link" des Project Settings) :
    Code CMD.EXE : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    D:\MesDocs\Visual Studio 6\Projects\Tests1\ConsoleApp2\Debug>consoleApp2 C:\Windows\*
    Parametre 0 : consoleApp2
    Parametre 1 : C:\Windows\addins
    Parametre 2 : C:\Windows\AppCompat
    <snip>
    Parametre 108 : C:\Windows\wplog.txt
    Parametre 109 : C:\Windows\write.exe
    Parametre 110 : C:\Windows\xpsp1hfm.log
     
    D:\MesDocs\Visual Studio 6\Projects\Tests1\ConsoleApp2\Debug>

    Désolé, je n'ai pas de MinGW sur ce poste.
    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.

Discussions similaires

  1. Arguments pour et contre Access ?
    Par bottura dans le forum Sondages et Débats
    Réponses: 240
    Dernier message: 23/03/2018, 23h25
  2. Réponses: 1
    Dernier message: 12/09/2011, 12h17
  3. Récuperer Arguments sur la ligne de commande ?
    Par Muetdhiver dans le forum x86 16-bits
    Réponses: 9
    Dernier message: 20/01/2003, 21h01
  4. fonction renvoyant un tableau en argument
    Par Jones dans le forum Langage
    Réponses: 6
    Dernier message: 30/09/2002, 18h20
  5. Procédure avec un nombre variable d'arguments
    Par charly dans le forum Langage
    Réponses: 15
    Dernier message: 21/06/2002, 11h08

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