none
Chaîne de caractères en argument RRS feed

  • Discussion générale

  • Bonjour tout le monde,

    Je cherche à récupérer la chaîne de caractères passée en argument à une application console.

    Ce n'est pas si évident que ça, à supposer qu'elle ne soit pas entourée de guillemets.

    D'entrée de jeu, on élimine la solution du tableau args[], puisque ça ne fonctionnerait que si les arguments successifs n'étaient séparés que par un seul caractère.

    En mode debug sous Visual Studio, je peux essayer

    System.Reflection.Assembly a = System.Reflection.Assembly.GetEntryAssembly();
    Console.WriteLine(a.CodeBase);

    qui me donne ceci :

    file:///D:/Projets Visual Studio/Console/ReverseString/ReverseString/bin/Debug/ReverseString.exe

    que je vais pouvoir comparer à la ligne de commande :

    string cmdl = Environment.CommandLine;
    Console.WriteLine(cmdl);

    soit :

    "D:\Projets Visual Studio\Console\ReverseString\ReverseString\bin\Debug\ReverseString.exe" une chaîne de caractères   passée  en argument

    Je peux chercher le début de cette ligne, soit D:\Projets, dans le chemin indiqué précédemment, et je vois alors que je dois l'exploiter à partir de la huitième position. J'ajoute un guillemet à la fin si il y en a un au début.

    J'ajoute un pour l'espace, et ça me permet de trouver les arguments dans la ligne de commande, je me retrouve à "une chaîne de caractères" ...

    Bon, tout ça c'est bien, voyons maintenant dans la fenêtre de lignes de commandes de Windows.

    Avec les mêmes arguments, en ayant pour répertoire courant celui où se trouve le programme, nous avons comme ligne de commande :

    ReverseString  une chaîne de caractères   passée  en argument

    Nous n'avons plus ni chemin, ni extension.

    Sera donc considéré comme chemin "ReverseString".

    Si je le cherche dans le chemin complet indiqué au début, et que je continue de là jusqu'à la fin, j'obtiens :

    ReverseString\ReverseString\bin\Debug\ReverseString.exe

    Je ne vois pas trop quoi faire avec ça.

    Je n'ai pas précisé que dans les arguments à chercher il n'y a aucune partie du chemin, car ça peut être le cas.

    J'ai dû passer devant la bonne commande sans la voir ?




    • Modifié Gloops dimanche 10 mars 2019 01:34
    dimanche 10 mars 2019 01:16

Toutes les réponses

  • Environment.GetCommandLineArgs ramène bien un tableau de chaînes avec les arguments...


    dimanche 10 mars 2019 07:20
  • Environment.GetCommandLineArgs ramène bien un tableau de chaînes avec les arguments...


    Merci. Celle-là, je l'avais bien vue passer, mais il me semblait qu'elle était égale au tableau args.

    C'est presque vrai, mais il y a un décalage de l'index d'une position.

    Du coup il convient de s'intéresser au premier élément :

    Environment.GetCommandLineArgs()[0]

    Il contient l'expression dans la ligne de commande du chemin du programme.

    Ainsi est évacué ce problème de la diversité possible de cette expression.

    Voici donc comment je peux à présent procéder :

    string cmdl = Environment.CommandLine;

    int pos = Environment.GetCommandLineArgs()[0].Length + 2; if (cmdl.Substring(0, 1) == "\"") { pos++; } string lesargu = cmdl.Substring(pos);

    J'ai testé ça dans les deux contextes décrits et c'est bon. J'espère que je n'aurai pas de mauvaise surprise dans un autre contexte.





    • Modifié Gloops dimanche 10 mars 2019 10:32
    dimanche 10 mars 2019 10:12
  • MS avait aussi publié une classe plus complète basée sur Environment.GetCommandLineArgs :

    //-----------------------------------------------------------------------
    //  This file is part of the Microsoft .NET Framework SDK Code Samples.
    // 
    //  Copyright (C) Microsoft Corporation.  All rights reserved.
    // 
    //This source code is intended only as a supplement to Microsoft
    //Development Tools and/or on-line documentation.  See these other
    //materials for detailed information regarding Microsoft code samples.
    // 
    //THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
    //KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
    //IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
    //PARTICULAR PURPOSE.
    //-----------------------------------------------------------------------
    
    /*=====================================================================
      File:      ArgParse.cs
    
      Summary:   Reusable class for parsing command-line arguments.
    
    =====================================================================*/
    
    // Add the classes in the following namespaces to our namespace
    using System;
    using System.Globalization;
    
    
    ///////////////////////////////////////////////////////////////////////////////
    namespace Microsoft.Samples
    {
    	public abstract class ArgumentParser
    	{
    		private String[] switchChars;             // For example: "/", "-"
    
    		private String[] switchSymbols;           // Switch character(s)
    
    		private Boolean caseSensitiveSwitches;   // Are switches case-sensitive?
    
    		// Domain of results when processing a command-line argument switch
    		protected enum SwitchStatus { NoError, Error, ShowUsage };
    
    		// Constructor that defaults to case-insensitive switches and 
    		// defaults to "/" and "-" as the only valid switch characters
    		protected ArgumentParser(String[] switchSymbols) 
            : this(switchSymbols, false, new string[] { "/", "-" })
    		{
    		}
    
    		// Constructor that defaults to "/" and "-" as the only valid switch characters
    		protected ArgumentParser(String[] switchSymbols, Boolean caseSensitiveSwitches) 
            : this(switchSymbols, caseSensitiveSwitches, new string[] { "/", "-" })
    		{
    		}
    
    		// Constructor with no defaults
    		protected ArgumentParser(String[] switchSymbols, Boolean caseSensitiveSwitches, String[] switchChars)
    		{
    			this.switchSymbols = switchSymbols;
    			this.caseSensitiveSwitches = caseSensitiveSwitches;
    			this.switchChars = switchChars;
    		}
    
    		// Every derived class must implement an OnUsage method
    		public abstract void OnUsage(String errorInfo);
    
    		// Every derived class must implement an OnSwitch method or a switch is considerred an error
    		protected virtual SwitchStatus OnSwitch(String switchSymbol, String switchValue)
    		{
    			return (SwitchStatus.Error);
    		}
    
    		// Every derived class must implement an OnNonSwitch method or a non-switch is considerred an error
    		protected virtual SwitchStatus OnNonSwitch(String value)
    		{
    			return (SwitchStatus.Error);
    		}
    
    		// The derived class is notified after all command-line switches have been parsed.
    		// The derived class can perform any sanity checking required at this time.
    		protected virtual SwitchStatus OnDoneParse()
    		{
    			// By default, we'll assume that all parsing was successful
    			return (SwitchStatus.Error);
    		}
    
    		// This Parse method always parses the application's command-line arguments
    		public Boolean Parse()
    		{
    			// Visual Basic will use this method since its entry-point function 
    			// doesn't get the command-line arguments passed to it.
    			return (Parse(Environment.GetCommandLineArgs()));
    		}
    
    		// This Parse method parses an arbitrary set of arguments
    		public Boolean Parse(String[] args)
    		{
    			SwitchStatus ss = SwitchStatus.NoError;	    // Assume parsing is sucessful.
    			int argNum;
    
    			for (argNum = 0; (ss == SwitchStatus.NoError) && (argNum < args.Length); argNum++)
    			{
    				// Determine if this argument starts with a valid switch character
    				Boolean fIsSwitch = false;
    
    				for (int n = 0; !fIsSwitch && (n < switchChars.Length); n++)
    				{
    					fIsSwitch = (0 == String.CompareOrdinal(args[argNum], 0, switchChars[n], 0, 1));
    				}
    
    				if (fIsSwitch)
    				{
    					// Does the switch begin with a legal switch symbol?
    					Boolean fLegalSwitchSymbol = false;
    					int n;
    
    					for (n = 0; !fLegalSwitchSymbol && (n < switchSymbols.Length); n++)
    					{
    						if (caseSensitiveSwitches)
    						{
    							fLegalSwitchSymbol = (0 == String.CompareOrdinal(args[argNum], 1, switchSymbols[n], 0, switchSymbols[n].Length));
    						}
    						else
    						{
    							fLegalSwitchSymbol = (0 == String.CompareOrdinal(args[argNum].ToUpper(CultureInfo.InvariantCulture), 1, switchSymbols[n].ToUpper(CultureInfo.InvariantCulture), 0, switchSymbols[n].Length));
    						}
    
    						if (fLegalSwitchSymbol) break;
    					}
    
    					if (!fLegalSwitchSymbol)
    					{
    						// User specified an unrecognized switch, exit
    						ss = SwitchStatus.Error;
    						break;
    					}
    					else
    					{
    						// This is a legal switch, notified the derived class of this switch and its value
    						ss = OnSwitch(caseSensitiveSwitches ? switchSymbols[n] : switchSymbols[n].ToLower(CultureInfo.InvariantCulture), args[argNum].Substring(1 + switchSymbols[n].Length));
    					}
    				}
    				else
    				{
    					// This is not a switch, notified the derived class of this "non-switch value"
    					ss = OnNonSwitch(args[argNum]);
    				}
    			}
    
    			// Finished parsing arguments
    			if (ss == SwitchStatus.NoError)
    			{
    				// No error occurred while parsing, let derived class perform a 
    				// sanity check and return an appropraite status
    				ss = OnDoneParse();
    			}
    
    			if (ss == SwitchStatus.ShowUsage)
    			{
    				// Status indicates that usage should be shown, show it
    				OnUsage(null);
    			}
    
    			if (ss == SwitchStatus.Error)
    			{
    				// Status indicates that an error occurred, show it and the proper usage
    				OnUsage((argNum == args.Length) ? null : args[argNum]);
    			}
    
    			// Return whether all parsing was sucessful.
    			return (ss == SwitchStatus.NoError);
    		}
    	}
    }
    
    ///////////////////////////////// End of File /////////////////////////////////
    

    dimanche 10 mars 2019 10:25
  • Ça, c'est intéressant aussi, mais il me semble que ça répond à un problème différent, où on veut traiter séparément les arguments, entendus comme étant séparés par une suite d'espaces (avec un cas particulier si on emploie des guillemets).

    Comme je disais au début de ma question, si il y a trois espaces, ou cinq, entre deux arguments, je veux les retrouver dans la chaîne traitée. Raison pour laquelle le tableau args ne répond pas au problème.



    (pardon pour la touche tabulation qui se trouve à côté du a ...)
    • Modifié Gloops dimanche 10 mars 2019 10:37
    dimanche 10 mars 2019 10:32