【问题标题】:retrieve console input as string array of arguments [duplicate]检索控制台输入作为参数的字符串数组[重复]
【发布时间】:2018-12-21 13:12:38
【问题描述】:

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

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

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

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

编辑: 也许需要澄清一下:我正在寻找开箱即用的字符串参数解析器,它尊重引号中的字符串文字,这样我收到的结果与使用与命令行参数相同的输入时相同。 是的,我可以自己拆分它,例如使用正则表达式,但我想知道是否没有可以使用的东西,因为我以这种方式接收命令行参数。

【问题讨论】:

  • “我真的需要自己解析吗?” - 是的,但是有很多有用的库。如果您只需要分隔字符串,那么您甚至可以使用正则表达式(但处理转义序列更加困难)。
  • 是的,如果没有现成的函数,我可能会使用正则表达式
  • 是的 - 删除了评论。 :o)
  • 没有什么可以“开箱即用”,除非你遵循一些规定的方法。大多数语言处理器都使用某种形式的堆栈和堆(因此我指出了拆分函数)。这一切都取决于您的需求有多复杂。
  • @Paul 我希望在字符串拆分中具有相同的行为,就像 windows/应用程序在接收命令行参数时所做的那样......不多也不少

标签: c# console-application


【解决方案1】:

如果你愿意,你可以编写一个解析命令行的代码。 但是有很多库可供您使用。

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

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

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

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

然后您可以将字符串数组解析为您的“选项”类,然后您可以从类变量中读取选项。

例子:

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 已经导入了该功能。 (拆分命令参数)

但你也可以自己制作(简单的函数,不会在“之间分割”):

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');
    }

【讨论】:

  • 这仍然适用于命令行参数,但有没有办法以交互方式使用它?据我所知,魔法发生在CommandLine.Parser.Default.ParseArguments&lt;Options&gt;(args),它已经需要一个正确的字符串数组——而这正是我所缺少的
  • 为您的解决方案阅读此内容:stackoverflow.com/questions/298830/…
  • 哦,我的搜索缺少正确的关键字,这正是我要搜索的。我投票结束了这个问题。
  • 你不给我积分:/。谢谢我可以帮助你。
猜你喜欢
  • 2018-12-11
  • 1970-01-01
  • 1970-01-01
  • 2020-02-17
  • 2011-05-23
  • 1970-01-01
  • 1970-01-01
  • 2014-08-01
  • 2019-01-12
相关资源
最近更新 更多