I want to pass a string array to main but keep spaces - c#

I want to pass a string to main, but I am having trouble with spaces.
I pass the string "C:\Documents and Settings\desktop\..." to the Main(string[] args) and I had:
args[0] = "C:\Documents"
args[1] = "and"
args[2] = "Settings\desktop\..."
But what I want is:
args[0] = "C:\Documents and Settings\desktop\..."
Any way to keep spaces but concatenate to one element of the string? The code should also work with any number of spaces in a given file path, not just 2 in this case.

This is typically handled by passing the arguments in quotes.
For example, if you call this as:
yourApp.exe "C:\Documents and Settings\desktop..."
You'll get the string in the first arg (args[0]).
For example, using this program:
using System;
internal class Program
{
private static void Main(string[] args)
{
foreach (var arg in args) Console.WriteLine(arg);
Console.ReadKey();
}
}
If you run this with the command line argument as:
"C:\Documents and Settings\desktop..."
(With the quotation marks in place), this will print:
C:\Documents and Settings\desktop...
If that isn't an option, and you only have a single argument, you could always join the results:
using System;
internal class Program
{
private static void Main(string[] args)
{
string argument = String.Join(" ", args);
Console.WriteLine(argument);
Console.ReadKey();
}
}
This will work without wrapping the path in quotes, but it assumes the entire path is a single path, only has one space in between "words", and has no other arguments in place. Personally, I would recommend wrapping the call in quotation marks, as it's a standard convention.

Can't you just quote the string when you call your program from the command line?
EXAMPLE: myprog "This is one argument"
namespace test
{
class Program
{
/*
* EXAMPLE: test arg1 "arg2 with spaces" arg3
* args[0]=arg1...
* args[1]=arg2 with spaces...
* args[2]=arg3...
*/
static void Main(string[] args)
{
for (int i = 0; i < args.Length; i++)
System.Console.WriteLine("args[{0}]={1}...", i, args[i]);
}
}
}

Related

Regex C# is it possible to use a variable in substitution?

I got bunch of strings in text, which looks like something like this:
h1. this is the Header
h3. this one the header too
h111. and this
And I got function, which suppose to process this text depends on what lets say iteration it been called
public void ProcessHeadersInText(string inputText, int atLevel = 1)
so the output should look like one below in case of been called
ProcessHeadersInText(inputText, 2)
Output should be:
<h3>this is the Header<h3>
<h5>this one the header too<h5>
<h9 and this <h9>
(last one looks like this because of if value after h letter is more than 9 it suppose to be 9 in the output)
So, I started to think about using regex.
Here's the example https://regex101.com/r/spb3Af/1/
(As you can see I came up with regex like this (^(h([\d]+)\.+?)(.+?)$) and tried to use substitution on it <h$3>$4</h$3>)
Its almost what I'm looking for but I need to add some logic into work with heading level.
Is it possible to add any work with variables in substitution?
Or I need to find other way? (extract all heading first, replace em considering function variables and value of the header, and only after use regex I wrote?)
The regex you may use is
^h(\d+)\.+\s*(.+)
If you need to make sure the match does not span across line, you may replace \s with [^\S\r\n]. See the regex demo.
When replacing inside C#, parse Group 1 value to int and increment the value inside a match evaluator inside Regex.Replace method.
Here is the example code that will help you:
using System;
using System.Linq;
using System.Text.RegularExpressions;
using System.IO;
public class Test
{
// Demo: https://regex101.com/r/M9iGUO/2
public static readonly Regex reg = new Regex(#"^h(\d+)\.+\s*(.+)", RegexOptions.Compiled | RegexOptions.Multiline);
public static void Main()
{
var inputText = "h1. Topic 1\r\nblah blah blah, because of bla bla bla\r\nh2. PartA\r\nblah blah blah\r\nh3. Part a\r\nblah blah blah\r\nh2. Part B\r\nblah blah blah\r\nh1. Topic 2\r\nand its cuz blah blah\r\nFIN";
var res = ProcessHeadersInText(inputText, 2);
Console.WriteLine(res);
}
public static string ProcessHeadersInText(string inputText, int atLevel = 1)
{
return reg.Replace(inputText, m =>
string.Format("<h{0}>{1}</h{0}>", (int.Parse(m.Groups[1].Value) > 9 ?
9 : int.Parse(m.Groups[1].Value) + atLevel), m.Groups[2].Value.Trim()));
}
}
See the C# online demo
Note I am using .Trim() on m.Groups[2].Value as . matches \r. You may use TrimEnd('\r') to get rid of this char.
You can use a Regex like the one used below to fix your issues.
Regex.Replace(s, #"^(h\d+)\.(.*)$", #"<$1>$2<$1>", RegexOptions.Multiline)
Let me explain you what I am doing
// This will capture the header number which is followed
// by a '.' but ignore the . in the capture
(h\d+)\.
// This will capture the remaining of the string till the end
// of the line (see the multi-line regex option being used)
(.*)$
The parenthesis will capture it into variables that can be used as "$1" for the first capture and "$2" for the second capture
Try this:
private static string ProcessHeadersInText(string inputText, int atLevel = 1)
{
// Group 1 = value after 'h'
// Group 2 = Content of header without leading whitespace
string pattern = #"^h(\d+)\.\s*(.*?)\r?$";
return Regex.Replace(inputText, pattern, match => EvaluateHeaderMatch(match, atLevel), RegexOptions.Multiline);
}
private static string EvaluateHeaderMatch(Match m, int atLevel)
{
int hVal = int.Parse(m.Groups[1].Value) + atLevel;
if (hVal > 9) { hVal = 9; }
return $"<h{hVal}>{m.Groups[2].Value}</h{hVal}>";
}
Then just call
ProcessHeadersInText(input, 2);
This uses the Regex.Replace(string, string, MatchEvaluator, RegexOptions) overload with a custom evaluator function.
You could of course streamline this solution into a single function with an inline lambda expression:
public static string ProcessHeadersInText(string inputText, int atLevel = 1)
{
string pattern = #"^h(\d+)\.\s*(.*?)\r?$";
return Regex.Replace(inputText, pattern,
match =>
{
int hVal = int.Parse(match.Groups[1].Value) + atLevel;
if (hVal > 9) { hVal = 9; }
return $"<h{hVal}>{match.Groups[2].Value}</h{hVal}>";
},
RegexOptions.Multiline);
}
A lot of good solution in this thread, but I don't think you really need a Regex solution for your problem. For fun and challenge, here a non regex solution:
Try it online!
using System;
using System.Linq;
public class Program
{
public static void Main()
{
string extractTitle(string x) => x.Substring(x.IndexOf(". ") + 2);
string extractNumber(string x) => x.Remove(x.IndexOf(". ")).Substring(1);
string build(string n, string t) => $"<h{n}>{t}</h{n}>";
var inputs = new [] {
"h1. this is the Header",
"h3. this one the header too",
"h111. and this" };
foreach (var line in inputs.Select(x => build(extractNumber(x), extractTitle(x))))
{
Console.WriteLine(line);
}
}
}
I use C#7 nested function and C#6 interpolated string. If you want, I can use more legacy C#. The code should be easy to read, I can add comments if needed.
C#5 version
using System;
using System.Linq;
public class Program
{
static string extractTitle(string x)
{
return x.Substring(x.IndexOf(". ") + 2);
}
static string extractNumber(string x)
{
return x.Remove(x.IndexOf(". ")).Substring(1);
}
static string build(string n, string t)
{
return string.Format("<h{0}>{1}</h{0}>", n, t);
}
public static void Main()
{
var inputs = new []{
"h1. this is the Header",
"h3. this one the header too",
"h111. and this"
};
foreach (var line in inputs.Select(x => build(extractNumber(x), extractTitle(x))))
{
Console.WriteLine(line);
}
}
}

Passing Quotation Mark Character (") as C# Console Application Argument

I have a project to demonstrate a program similar to the "echo" command in the MS-DOS Command Line. Here is the code in C#:
using System;
namespace arguments
{
class Program
{
static void Main(string[] args)
{
try
{
switch (args[0])
{
case "/?":
string location = System.Reflection.Assembly.GetEntryAssembly().Location;
string name = System.IO.Path.GetFileName(location);
Console.WriteLine("Displays messages\nSyntax: {0} [message]", name);
Environment.Exit(0);
break;
}
if (args.Length >= 0)
{
string x = "";
foreach (var item in args)
{
x += item.ToString() + " ";
}
Console.WriteLine(Convert.ToString(x)); // this should eliminate vulnerabilities.
}
}
catch
{
string location = System.Reflection.Assembly.GetEntryAssembly().Location;
string name = System.IO.Path.GetFileName(location);
Console.WriteLine("Displays messages\nSyntax: {0} [message]", name);
}
}
}
}
This does a pretty efficient job at doing what it's supposed to do. Then I got into trying to exploit it in any way I could.
In command prompt, I ran arguments.exe ", this is supposed to print out ". But that's not really what happened. I then tried the same with the echo command by running echo ", and it, like it's supposed to, printed out ". This is mind boggling because I wouldn't have even thought this would be a problem. I couldn't get it to pose a great threat, just confused me for a minute.
My question is, is there any way to pass the quotation mark (") as argument to this console application?
Here is a picture to demonstrate it a little bit better: http://prntscr.com/cm9yal
void Main(string[] args)
args array here contains the arguments which have been passed to your application. Because arguments may have spaces they can be surrounded by quotes.
For this reason you won't get the string you have placed as argument. You will also loose any number of spaces between quoted parameters.
If you need the raw command line string, use:
string cmdline = System.Environment.CommandLine;
To be able to get the single quote, you'll need to bypass the default parsing performed by the CLR when populating the args array. You can do this by examining Environment.CommandLine, which in the case you describe above will return something along the lines of:
ConsoleApplication1.exe \"
Note, the argument I passed was simply " (not the escaped variant shown).

What is the Most Efficient way to Place Strings to Array from .txt

I have a text file with about 30 words (of varying length). I'm trying to bring all of those words into the program and store them into an array of 'x' elements (x being the number of words).
Any help? I'm literally on day 2 of learning.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Hangman {
class Program {
static void Main(string[] args) {
//StreamReader myWordList = new StreamReader("WordList.txt");//string stringArray[] = StreamReader(WordList.txt);//.WordList.txt;
String myWordArrays[] = File.ReadAllLines(#
"C:\Users\YouTube Upload\Documents\Visual Studio 2013\Projects\Hangman");
Console.WriteLine(myWordArrays[2]);
Console.ReadLine();
}
}
}
This is the complete code (above) - I'm getting these errors:
Error 1 Bad array declarator: To declare a managed array the rank specifier precedes the variable's identifier. To declare a fixed size buffer field, use the fixed keyword before the field type. c:\users\youtube upload\documents\visual studio 2013\Projects\Hangman\Hangman\Program.cs 16 32 Hangman
And
Error 2 Invalid expression term '=' c:\users\youtube upload\documents\visual studio 2013\Projects\Hangman\Hangman\Program.cs 16 35 Hangman
I don't really understand that, because I'm calling it like I should be (or so I would think? o.0)
And this:
Error 3 ; expected c:\users\youtube upload\documents\visual studio 2013\Projects\Hangman\Hangman\Program.cs 16 35 Hangman
also this one
Error 4 ; expected c:\users\youtube upload\documents\visual studio 2013\Projects\Hangman\Hangman\Program.cs 16 37 Hangman
Forgive my horrible formatting here - I'm new to this site and am just getting used to it all. :(
Get values from file like this :
string[] myWordArrays = File.ReadAllLines(#"C:\Users\YouTube Upload\Documents\Visual Studio 2013\Projects\Hangman\yourfilename");
Your whole program :
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Hangman {
class Program {
static void Main(string[] args) {
string[] myWordArrays = File.ReadAllLines(#"C:\Users\YouTube Upload\Documents\Visual Studio 2013\Projects\Hangman\yourfilename");
Console.WriteLine(myWordArrays[2]);
Console.ReadKey();
}
}
}
P.S. What mistakes have you made in this line of code
String myWordArrays[] = File.ReadAllLines(#
"C:\Users\YouTube Upload\Documents\Visual Studio 2013\Projects\Hangman\");
Incorrect variable declaration. Correct one is
string[] myWordArrays = ...
'#' sign should be placed right before string that contain escape characters and should be on a same line. What if line is too long? Then you can move both this sign and the string to a next line.
string[] myWordArrays = File.ReadAllLines(
#"C:\Users\YouTube Upload\Documents\Visual Studio 2013\Projects\Hangman");
File.ReadAllLines method accepts only full path and not a relative one. To point to a file that is located in the same folder where executive file is stored (bin folder) you can use Directory.GetCurrentDirectory() method. So you can change it to :
string filename = 1.txt;
File.ReadAllLines(Directory.GetCurrentDirectory() + "\" + filename);
Depending on the character(s) used to split the strings, you could use one of the following:
var streamReader = new StreamReader("file");
var words = streamReader.ReadToEnd();
var wordArray = words.Split(new[] { Environment.NewLine }, StringSplitOptions.None); // For words split by lines where you know the format of the line ending
var wordArray = words.Split(new [] {"\n", "\r\n"}, StringSplitOptions.None); // For words split by lines where the format could be unix or windows
var wordArray = words.Split(','); // For words split by comma
So, for more explination StreamReader.ReadToEnd() returns a string. This class has many methods as defined in:
https://msdn.microsoft.com/en-us/library/system.string(v=vs.110).aspx
These methods include a "split" method, which takes either an array of characters (or multiple comma separated characters) (char denoted by single quote (')) or an array of strings with string split options.
In the latter, we define a new array of strings with new [] { "string1", "string2", "..."} here the type of the array is implicit, but we could specify new string[] {...} if we wanted, or pass in an array of strings we had already defined. The second option is an enum with two values; None and RemoveEmptyEntries, which are defined here:
https://msdn.microsoft.com/en-us/library/system.stringsplitoptions(v=vs.110).aspx
There are additional overloads for the string.split method (which are in the top link).
I would like to thank all of you for the tremendous help. I had the formatting incorrect, but I guess I understood how it worked after all!! lol. At least it wasn't a misplaced/missing semicolon, yeah? :)
namespace Hangman
{
class Program
{
static void Main(string[] args)
{
//StreamReader myWordList = new StreamReader("WordList.txt");//string stringArray[] = StreamReader(WordList.txt);//.WordList.txt;
String[] myWordArrays = File.ReadAllLines("WordList.txt");
Console.WriteLine(myWordArrays[2]);
Console.ReadLine();
}
}
}
Thank you all so very much. This fixed it, and it did successfully display the 3rd element (string), which is advice, which happens to be on the third line [2] - perfect. Thank you!!!
Try this, it may help you.
private void PutTextIntoArray()
{
var array = ReadTextFile("C:\\WordList.txt").GetTotalWords();
}
private static string ReadTextFile(string file)
{
try
{
return File.ReadAllText(file);
}
catch (IOException ex)
{
return ex.Message;
}
catch (Exception ex)
{
return ex.Message;
}
}
public static class Extensions
{
public static string ReplaceMultipleSpacesWith(this string text, string newString)
{
return Regex.Replace(text, #"\s+", newString);
}
public static string[] GetTotalWords(this string text)
{
text = text.Trim().ReplaceMultipleSpacesWith(" ");
var words = text.Split(' ');
return words;
}
}

How can you put single spaces into a string of characters in C#

I am still a beginner in C# and I know there is a method that can be used to do this but I can't seem to find it online.
I have a function that permutates a word
static void Main(string[] args)
{
string[] list = "a b c d".Split();
foreach (string[] permutation in Permutations<string>.AllFor(list))
{
System.Console.WriteLine(string.Join(" ", permutation));
}
}
However it only works with words that are broken up. (eg. "a b c d" ) Since that is not really a practical way to ask a user for input, I want to find a way to take a word from the user (an unbroken word like "hello" ) and break it up for the function to understand. Eg. form the input word of the use "happy" to a spaced word for the program to understand = "h a p p y"
I tried this code:
//splits the word into an array
string[] arr = name.Split();
//splits the array with spaces to enter into the program
name = string.Join(" ",arr);
arr = name.Split();
But it just ends up coming out unbroken anyway. Can someone tell me the easiest way to do this?
Just to mention I am still a beginner in C# and programming in total I might not understand some of the higher level concepts. I have been through some answers on this website and I have seen some answers that I don't understand at all.
You can loop over the string to convert it to an array, and then use Join.
using System.Text.RegularExpressions;
using System;
public class Program{
public static void Main(string[] args) {
string v = "hello";
// Convert into the a string array, the old-fashioned way.
string[] name = new string[v.Length];
for (int i = 0; i < v.Length; i++)
name[i] = v[i] + "";
string feedToPermutationFunction = string.Join(" ",name));
// Feed the above string into your permutation code.
}
}
You just need to separate each character and then concatenate them with a space:
This is the simplest way:
var userInput = Console.ReadLine();
var output = string.Join<char>(" ", userInput);
Console.WriteLine(output);
char[] array=input.ToArray();
string val="";
for(int i=0;i<array.Length;i++)
{
val+=array[i]+" ";
}
this will give you a string with spaces like you wanted Val
create an array with the string length
string[] strarray=new string[val.Length];
for(int i=0;i<strarray.Length;i++)
{
strarray[i]=val.Substring(i,len); //**i** is for string index,,,**len** string length in each index
}

reversing text from input file using linq

I would like to reverse each word from input.txt using c# and linq and display the output text, so far i have a code that inputs the word and reverses it.
using System;
using System.Text;
using System.Linq;
namespace program
{
class Program
{
public static void Main(string[] args)
{
Console.WriteLine("String:");
string name = Console.ReadLine();
string output = new string(name.ToCharArray().Reverse().ToArray());
Console.WriteLine(output);
}
}
}
string input = "I love programming";
string output = String.Join(" ",
input.Split().Select(w => new String(w.Reverse().ToArray())));
// I evol gnimmargorp
Reading file is simple:
string input = File.ReadAllText("input.txt");
You can also move word reversing into separate method. That will allow you to change algorithm of string reversing without touching other logic:
private static string GetReversedString(string s)
{
return new String(s.Reverse().ToArray());
}
And getting reversed output will look like:
string output = String.Join(" ", input.Split().Select(GetReversedString));
If lines should be preserved:
string output =
String.Join(Environment.NewLine,
File.ReadLines().Select(l =>
String.Join(" ", l.Split().Select(GetReversedString))));
The reversal code could be refactored in an extension method for String; Next, a text file should be opened, the lines splitted to single words and the words mapped reversely to the console.

Categories