Split String Containing Command-Line Parameters into String[] in C#

Split string containing command-line parameters into string[] in C#

In addition to the good and pure managed solution by Earwicker, it may be worth mentioning, for sake of completeness, that Windows also provides the CommandLineToArgvW function for breaking up a string into an array of strings:

LPWSTR *CommandLineToArgvW(
LPCWSTR lpCmdLine, int *pNumArgs);

Parses a Unicode command line string
and returns an array of pointers to
the command line arguments, along with
a count of such arguments, in a way
that is similar to the standard C
run-time argv and argc values.

An example of calling this API from C# and unpacking the resulting string array in managed code can be found at, “Converting Command Line String to Args[] using CommandLineToArgvW() API.” Below is a slightly simpler version of the same code:

[DllImport("shell32.dll", SetLastError = true)]
static extern IntPtr CommandLineToArgvW(
[MarshalAs(UnmanagedType.LPWStr)] string lpCmdLine, out int pNumArgs);

public static string[] CommandLineToArgs(string commandLine)
{
int argc;
var argv = CommandLineToArgvW(commandLine, out argc);
if (argv == IntPtr.Zero)
throw new System.ComponentModel.Win32Exception();
try
{
var args = new string[argc];
for (var i = 0; i < args.Length; i++)
{
var p = Marshal.ReadIntPtr(argv, i * IntPtr.Size);
args[i] = Marshal.PtrToStringUni(p);
}

return args;
}
finally
{
Marshal.FreeHGlobal(argv);
}
}

Split a string containing command-line parameters into a String[] in Java

Here is a pretty easy alternative for splitting a text line from a file into an argument vector so that you can feed it into your options parser:

This is the solution:

public static void main(String[] args) {
String myArgs[] = Commandline.translateCommandline("-a hello -b world -c \"Hello world\"");
for (String arg:myArgs)
System.out.println(arg);
}

The magic class Commandline is part of ant. So you either have to put ant on the classpath or just take the Commandline class as the used method is static.

How split this specific string into array

If you are writing code to parse command-line arguments, you could use the NuGet package System.CommandLine.

After adding that package, you can write code like this:

using System;
using System.CommandLine;

namespace Demo
{
static class Program
{
static void Main()
{
string commandLine = "MyDatabase C:\\MyDatabase\\Backup \"C:\\Program Files\\MySQL\\MySQL Server 8.0\\bin\"";

var cmd = new RootCommand();
var result = cmd.Parse(commandLine);

Console.WriteLine($"{result.Tokens.Count} arguments found:");

foreach (var argument in result.Tokens)
{
Console.WriteLine(argument);
}
}
}
}

The output from that program is:

3 arguments found:
Argument: MyDatabase
Argument: C:\MyDatabase\Backup
Argument: C:\Program Files\MySQL\MySQL Server 8.0\bin

This is somewhat of a "sledgehammer to crack a nut", but if you really are parsing command line arguments, System.CommandLine provides a great deal of functionality beyond just the basic parsing.

How can I parse line arguments?

In .net you have static void Main(string[] args). So, if you pass something like -push $a 75 $c 5, your args will have 5 items. Lets say you have multiple

-push $a 75 $c 5 -push $b 100 $d 10

You would need to do re-split by -push - cmd = string.Join(" ", args) - you are back to original command line. Now, lets split again

You need some model of course

public class ArgsPoco
{
public int A {get;set;}
public int B {get;set;}
public int C {get;set;}
}

Then you take your command and fill POCO

string[] pushSections = cmd.Split(new[]{"-push"});
foreach (string sect in pushSections )
{
string[] args = sect.Split('$', StringSplitOptions.RemoveEmptyEntries);
foreach (string arg in args)
{
var poco = new ArgsPoco();
SetProperty(arg, poco);
}
_somePocoList.Add(poco);
}

private void SetProperty(string arg, ArgsPoco poco)
{
string item = arg.Trim();
int val = Convert.ToInt32(item.Substring(1).Trim());
if (item.StartsWith("a"))
poco.A = val;
else if (item.StartsWith("b"))
poco.B = val;
else if (item.StartsWith("c"))
poco.C = val;
}

Then, you just decorate your POCO with some JSon serialization attributes from Newtonsoft.Json like

[Json . . . . 
public class ArgsPoco
{
[Json . . . .
public int A {get;set;}
. . . .

I m not clear here what specific output you need. But bottom line, you serialize your model the way you want, using existent tools or build custom/

Splitting string on command line argument

This code should work BUT it is making the assumption that all the files are txt files with .txt as their extension AND that you only have one argument (All of your files are combined into one string, so args would only read one argument).

public static void Main(string[] args)
{
string input = args[0];
List<string> files = input.Split('.').ToList<string>();
for (int i = 0; i < files.Count - 1; i++)
{
files[i] = files[i].Replace("txt","");
files[i] += ".txt";
}
for (int i = 0; i < files.Count - 1; i++)
{
Console.WriteLine(files[i]);
}
return;
}

C# - Split executable path and arguments into two strings

You could try a CSV parser like the only onboard in .NET, the VisualBasic.TextFieldParser:

List<string[]> allLineFields = new List<string[]>();
var textStream = new System.IO.StringReader(text);
using (var parser = new Microsoft.VisualBasic.FileIO.TextFieldParser(textStream))
{
parser.Delimiters = new string[] { " " };
parser.HasFieldsEnclosedInQuotes = true; // <--- !!!
string[] fields;
while ((fields = parser.ReadFields()) != null)
{
allLineFields.Add(fields);
}
}

With a single string the list contains one String[], the first is the path, the rest are args.

Update: this works with all but your last string because the path is C:\Program Files\Sample.exe. You have to wrap it in quotes, otherwise the space in Program Files splits them into two parts, but that is a known issue with windows paths and scripts.



Related Topics



Leave a reply



Submit