Auteur de questions
Chaîne de caractères en argument

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
Toutes les réponses
-
Environment.GetCommandLineArgs ramène bien un tableau de chaînes avec les arguments...
-
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 :
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.string cmdl = Environment.CommandLine;
int pos = Environment.GetCommandLineArgs()[0].Length + 2; if (cmdl.Substring(0, 1) == "\"") { pos++; } string lesargu = cmdl.Substring(pos);
- Modifié Gloops dimanche 10 mars 2019 10:32
-
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 /////////////////////////////////
-
Ç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