检索控制台输入作为参数的字符串数组

时间:2018-07-13 07:56:56

标签: c# console-application

我正在尝试从现有应用程序创建一个交互式shell,该应用程序可解释如下命令行参数:

application.exe command subcommand someNumber=1 boolArgument s="string argument with spaces"

输入Main时,我收到一个包含所有提供的参数的字符串数组,这已经将s="string argument with spaces"视为一个块。我想以相同的方式处理交互式控制台输入,但是找不到等效的功能...

我真的必须自己解析吗?我的直接方法是读取整行并在空格处分割,但随后我必须处理引号中的字符串参数的情况……

编辑: 也许需要澄清一下:我正在寻找一种开箱即用的字符串参数解析器,该解析器尊重引号中的字符串文字,以便获得与使用相同输入作为命令行参数时相同的结果。 是的,我可以自行拆分,例如使用RegEx,但是我想知道是否有什么可以使用的,因为我是通过这种方式接收命令行参数的。

1 个答案:

答案 0 :(得分:1)

如果需要,可以编写用于解析命令行的代码。 但是,您可以使用许多库。

有一个非常好的命令行库:'https://github.com/commandlineparser/commandline'

它非常易于使用,希望对您有所帮助。

您必须创建一个带有所有选项的“选项”类。 要声明选项,请使用'option'属性:

[Option(char shortoption, string longoption, Required = bool,  MetaValue = string, Min = int, Seperator = char, SetName = string)]
public <type> <name> { get; set; }

然后,您可以将字符串数组解析为'options'类,并且可以从类变量中读取选项。

示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using CommandLine;
namespace ConsoleApp1
{
    //Declare some options
    public class Options
    {
        //Format:
        //[Option(char shortoption, string longoption, Required = bool,  MetaValue = string, Min = int, Seperator = char, SetName = string)]
        //public <type> <name> { get; set; }

        [Option('r', "read", Required = true, HelpText = "Filename", Separator = ' ')]
        public IEnumerable<string> InputFiles { get; set; }

        [Option('e', "echo", Required = true, HelpText = "Echo message")]
        public string echo { get; set; }

    }
    class Program
    {
        static void Main(string[] args)
        {
            bool s = true;
            CommandLine.Parser.Default.ParseArguments<Options>(args).WithNotParsed<Options>((errs) => 
            {
                foreach (Error e in errs)
                {
                    Console.WriteLine("ERROR " + e.Tag.ToString());
                    s = e.StopsProcessing ? false : s;
                }
                if(!s)
                {
                    return;
                }
            }).WithParsed<Options>(opts => {
                Console.WriteLine(opts.echo);
                foreach(string filename in opts.InputFiles)
                {
                    Console.WriteLine(File.ReadAllText(filename));
                }
            });

        }
    }
}

控制台:

ConsoleApp1\bin\Debug>ConsoleApp1.exe -r helps.txt sayhello.txt -e "Thanks for reading"
Thanks for reading
I hope this helps
Hello world

ConsoleApp1\bin\Debug>ConsoleApp1.exe -r -fds fds fds-f dsf -
ConsoleApp1 1.0.0.0
Copyright ©  2018
ERROR(S):
Option 'f' is unknown.
Required option 'e, echo' is missing.

  -r, --read    Required. Filename

  -e, --echo    Required. Echo message

  --help        Display this help screen.

  --version     Display version information.

ERROR UnknownOptionError
ERROR MissingRequiredOptionError

ConsoleApp1\bin\Debug>ConsoleApp1.exe -e f
ConsoleApp1 1.0.0.0
Copyright ©  2018
ERROR(S):
Required option 'r, read' is missing.

  -r, --read    Required. Filename

  -e, --echo    Required. Echo message

  --help        Display this help screen.

  --version     Display version information.

ERROR MissingRequiredOptionError

ConsoleApp1\bin\Debug>ConsoleApp1.exe -r helps.txt sayhello.txt -e ":)"
:)
I hope this helps
Hello world

ConsoleApp1\bin\Debug>

如何安装?

转到视图->其他窗口->程序包管理器控制台

输入命令:

Install-Package CommandLineParser -Version 2.2.1 -ProjectName <yourprojectname>

Github:

https://github.com/commandlineparser/commandline

我希望这会有所帮助。

阅读:Split string containing command-line parameters into string[] in C#。 Windows已经导入了该功能。 (分割命令args)

但是您也可以创建自己的(简单的函数,该函数不会在“之间分割”):

static string[] ParseArguments(string commandLine)
    {
        char[] parmChars = commandLine.ToCharArray();
        bool inQuote = false;
        for (int index = 0; index < parmChars.Length; index++)
        {
            if (parmChars[index] == '"')
                inQuote = !inQuote;
            if (!inQuote && parmChars[index] == ' ')
                parmChars[index] = '\n';
        }
        return (new string(parmChars)).Split('\n');
    }