Switch Statement with Strings C# - c#

I need to write something that will get the start-up arguments and then do something for those start-up args, and I was thinking that switch would be good but it only accepts for ints and it has to be for a string
This isn't the actual code but I want to know how to make something like this work
namespace Simtho
{
class Program
{
static void Main(string[] args)
{
switch (Environment.GetCommandLineArgs())
{
case "-i":
Console.WriteLine("Command Executed Successfully");
Console.Read;
break;
}
}
}
}

Environment.GetCommandLineArgs() returns an array of strings. Arrays cannot be switched on. Try iterating over the members of the array, like this:
namespace Simtho
{
class Program
{
static void Main(string[] args)
{
foreach (string arg in Environment.GetCommandLineArgs())
{
switch (arg)
{
case "-i":
Console.WriteLine("Command Executed Successfully");
Console.Read();
break;
}
}
}
}
}

What about something like this?
string[] args = Environment.GetCommandLineArgs();
if (args.Contains("-i"))
{
// Do something
}

Environment.GetCommandLineArgs() returns array of strings?
And maybe i'm wrong but internally switch on strings converted to if-else sequence...

Environment.GetCommandLineArgs() returns a string[]
You can't switch on a string array. You probably want to test if the array contains certain values though.

Related

Making a console with a print comand

I am trying to make a program that will print whatever is after "print:" in a console application (I don't know how else to explain it)
If you don't understand I think my code will help you
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LiteConsole
{
class Program
{
static void Main(string[] args)
{
while (true)
{
string input = Console.In.ReadLine();
char[] chars = input.ToCharArray();
if (input.Contains("print"))
{
int Place = 0;
int colenPlace = 0;
foreach (char a in chars)
{
Place++;
if (chars[Place].Equals(":"))
{
colenPlace = Place;
break;
}
}
Console.Write(input.Substring(colenPlace));
}
}
}
}
}
When I run the program and type "print:Hello World" it doesn't print "Hello World" like it should, it just goes to the next line.
At a quick glance I can see two bugs in your application:
First, if a ':' character is never found, the code will generate an IndexOutOfBoundsException. This is because you increment the index before you use it, so you're never comparing the first character of the input and will generate an exception after the last character. Move Place++; to the end of the loop to solve this:
foreach (char a in chars)
{
if (chars[Place].Equals(":"))
{
colenPlace = Place;
break;
}
Place++;
}
Second, this will never be true:
chars[Place].Equals(":")
The value is a char, but you're comparing it to a string. Compare it to a char instead:
chars[Place].Equals(':')
Or even just use a direct comparison (which should result in a compile-time error if you try to use a string by mistake):
chars(Place) == ':'
Could probably simplify it to:
static void Main(string[] args)
{
while (true)
{
var input = Console.ReadLine();
if input.StartsWith("print:")
Console.WriteLine(input.Replace("print:", ""));
}
}

How to add to a class a string with two integers and show the sum

Greeting fellow programmers!
I am currently studying software development (I started not a month ago) and I have a problem that needs a solution. Underneath you can find the code and as you can see, the method WriteNumber needs help. I need to write the code in a way that when I run the program, on the console screen the following two lines will be shown:
Hello World!
81
The Main method code cannot be changed and also I cannot add more methods to the class Calculator so the code needs to be done only within the WriteNumbers method. I have tried a lot of things but I am still grasping how everything works so any help is welcome! Thank you in advance for your time.
Namespace CalculatorTest
{
class Calculator
{
public static string WriteText (string input)
{
return "" + input;
}
public static string WriteNumber()
{
}
}
class Program
{
static void Main(string[] args)
{
string s = Calculator.WriteText("Hello World!");
Console.WriteLine(s);
string n = Calculator.WriteNumber(53 + 28);
Console.WriteLine(n);
Console.Read();
}
}
Not to do your homework for you to just be copied/pasted, hopefully I can give you some hints...
Notice how the method is being invoked:
Calculator.WriteNumber(53 + 28)
The 53 + 28 part happens first, then the result of that operation is passed to the method. That result, naturally, is 81. What's important about that is its type, which is an integer.
So, reasonably, the method signature needs to accept an int as a parameter. This would be done very similarly to how the other method accepts a string as a parameter:
public static string WriteText(string input)
What, then, does that method need to do with that input? Well, it's only a single value, so there aren't any calculations to be performed on it. It would appear that the method simply needs to return the value as a string. (It's your homework so you tell me, is that correct?)
This can be done with exactly two things:
Calling .ToString() on the value
Using the return keyword to return the result of that operation
(Note: The .ToString() operation does something very intuitive on value types, such as int or double or bool. As you progress into using reference types, you're going to find that it does something very different. Any time you have a custom class on which you want to call .ToString(), you'll need to override the .ToString() method on that class first.)
Please read David's answer, it's important that you make the effort to understand why this works the way it does. That being said:
public static string WriteNumber(int number)
{
return number.ToString();
}
Thank you all for your valuable input but special thanks to David because he showed where I made my error. I forgot that the two numbers in the main function will be summed up FIRST and THEN forwarded to the method in the class Calculator. After that got cleared up, it was easy to understand what to do (basically adjust the type of the input parameter to int).
namespace CalculatorTest
{
class Calculator
{
public static string WriteText (string input)
{
return "" + input;
}
public static string WriteNumber(int sumOfNumbers)
{
return "" + sumOfNumbers;
}
}
class Program
{
static void Main(string[] args)
{
string s = Calculator.WriteText("Hello World!");
Console.WriteLine(s);
string n = Calculator.WriteNumber(53 + 28);
Console.WriteLine(n);
Console.Read();
}
}
}

how to recall variable in foreach Loop C#

I'm new to C#. I wrote a foreach loop,but how can I recall the variables outside the loop. Thanks for your help.
Here is my code:
static void Main(string[] args)
{
IDictionary<string,float> IDico=new Dictionary<string,float>();
IDico.Add("D1",1);
IDico.Add("D2",2);
IDico.Add("D3",3);
string tempo="D2";
foreach(var element in IDico.Keys)
{
if(tempo.Contains(element in IDico.Keys)
{
var outPut=IDico[element]
}
}
var call=outPut // How can I call outPut outside the for loop?Because the outPut doesn't exist for this row.
}
This is your code
static void Main(string[] args)
{
IDictionary<string,float> IDico=new Dictionary<string,float>();
IDico.Add("D1",1);
IDico.Add("D2",2);
IDico.Add("D3",3);
string tempo="D2";
float outPut = 0.0;
foreach(var element in IDico.Keys)
{
if(tempo.Contains(element))
{
outPut=IDico[element]
}
}
//Do stuff with outPut
}
however i think you may be trying to find tempo in the dictionary so really you should just do this:
static void Main(string[] args)
{
IDictionary<string,float> IDico=new Dictionary<string,float>();
IDico.Add("D1",1);
IDico.Add("D2",2);
IDico.Add("D3",3);
string tempo="D2";
float outPut = 0.0;
if(IDico.Contains(tempo))
{
outPut=IDico[tempo];
}
//Do stuff with outPut
}
static void Main(string[] args)
{
IDictionary<string,float> IDico=new Dictionary<string,float>();
IDico.Add("D1",1);
IDico.Add("D2",2);
IDico.Add("D3",3);
string tempo="D2";
string outPut = string.Empty;
foreach(var element in IDico.Keys)
{
if(tempo.Contains(element))
{
outPut = IDico[element]
}
}
var call = outPut;
}
If outPut can contain more than one element from your dictionary consider using and array or list. If you want to stop iterating after you find a match use a break; in the if statement so that after the match is found the loop will stop.
Also, you're going to want to declare outPut outside of loop so it doesn't re declare itself on each iteration of the loop.
I also fixed the contains statement for you as well as you were using improper syntax.

C# Application with Numerous Errors

I am having fun with a couple of errors I am getting in a C# application I am writing.
The error I keep getting is:
encrypt and decrypt calls must have a return type
Console.WriteLine being used as a method
static void encrypt(string[] args) expected class, delegate, interface or struct
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string pw ="", hash =""; //Declare an intialise variables
if (args.Length < 4) // Test to see if correct number of arguments have been passed
{
Console.WriteLine("Please use command line arguments in this format: encrypt -e (or -d) password-to-encrypt-with input-file output-file");
Environment.Exit(0);
}
if (args[1].Length < 10 || args[1].Length > 40) // Test to see if the password is between 10 and 40 characters
{
Console.WriteLine("Please use a password between 10 and 40 characters");
Environment.Exit(0);
}
switch (args[0]) //Uses first argument value to drive switch statement (-e or -d)
{
case "-e":
encrypt(string[] args);
break;
case "-d":
decrypt(string[] args);
break;
default:
Console.WriteLine("When using the program please use -e to encrypt and -d to decrypt");
break;
}
} //End of MAIN
static void encrypt(string[] args) //Function to encrypt
{
string inputtext =""; //Initialise Varible (Ensure it is empty)
inputtext=System.IO.File.ReadAllText(args[2]); //Read file in an assign to input text
return;
}
static void decrypt(string[] args) //Function to decrypt
{
string inputtext =""; //Initialise Varible (Ensure it is empty)
inputtext=System.IO.File.ReadAllText(args[2]); //Read file in an assign to input text
return;
}
}
}
Any help would be much appreciated!
Alistair
When calling a method, you must not specify the types of the arguments. So:
case "-e":
encrypt(args);
break;
Along with what Hans has said, you mentioned an error about return types in your methods.
Your encrypt and decrypt methods have return statements, but they are void methods meaning they don't have any return types.
Either give it a type you want to return (presumably the string you are manipulating) or just remove the return statement altogether. You do not need to explicitly put return at the end of a method to get it to exit out of the method. It will do that anyway.
Two small pro-tips, I would declare your fields on different lines, not all bunched together (with the way you have declared pw and hash) and also add a using directive for System.IO, so you don't have to call System.IO.File.ReadAllText, you can just call File.ReadAllText.

How do i exit a List<string>.ForEach loop when using an anonymous delegate?

In a normal loop you can break out of a loop using break. Can the same be done using an anonymous delegate?
Example
inputString and result are both declared outside the delegate.
blackList.ForEach(new Action<string>(
delegate(string item)
{
if(inputString.Contains(item)==true)
{
result = true;
// I want to break here
}
}
));
Edit:
Thanks for the replies, I'm actually reading your book at the minute John :) Just for the record i hit this issue and switched back to a normal foreach loop but I posted this question to see if i missed something.
As others have posted, you can't exit the loop in ForEach.
Are you able to use LINQ? If so, you could easily combine TakeWhile and a custom ForEach extension method (which just about every project seems to have these days).
In your example, however, List<T>.FindIndex would be the best alternative - but if you're not actually doing that, please post an example of what you really want to do.
There is no loop that one has access to, from which to break. And each call to the (anonymous) delegate is a new function call so local variables will not help. But since C# gives you a closure, you can set a flag and then do nothing in further calls:
bool stop = false;
myList.ForEach((a) => {
if (stop) {
return;
} else if (a.SomeCondition()) {
stop = true;
}
});
(This needs to be tested to check if correct reference semantics for closure is generated.)
A more advanced approach would be to create your own extension method that allowed the delegate to return false to stop the loop:
static class MyExtensions {
static void ForEachStoppable<T>(this IEnumerable<T> input, Func<T, bool> action) {
foreach (T t in input) {
if (!action(t)) {
break;
}
}
}
}
Do you have LINQ available to you? Your logic seems similar to Any:
bool any = blackList.Any(s=>inputString.Contains(s));
which is the same as:
bool any = blackList.Any(inputString.Contains);
If you don't have LINQ, then this is still the same as:
bool any = blackList.Find(inputString.Contains) != null;
If you want to run additional logic, there are things you can do (with LINQ) with TakeWhile etc
I don't think there's an elegant way to do it when using the ForEach method. A hacky solution is to throw an exception.
What's preventing you from doing an old fashioned foreach?
foreach (string item in blackList)
{
if (!inputString.Contains(item)) continue;
result = true;
break;
}
If you want a loop, use a loop.
Action allows for no return value, so there's no way the ForEach function could possibly know that you want to break, short of throwing an exception. Using an exception here is overkill.
The only way to "exit" the loop is to throw an exception. There is no "break" style way of exiting the .ForEach method like you would a normal foreach loop.
The ForEach method is not mean to do this. If you want to know if a collection contains an item you should use the Contains method. And if you want to perform a check on all items in a collection you should try the Any extention method.
bool #break = false;
blackList.ForEach(item =>
{
if(!#break && inputString.Contains(item))
{ #break = true;
result = true;
}
if (#break) return;
/* ... */
});
Note that the above will still iterate through each item but return immediately. Of course, this way is probably not as good as a normal foreach.
class Program
{
static void Main(string[] args)
{
List<string> blackList = new List<string>(new[] { "jaime", "jhon", "febres", "velez" });
string inputString = "febres";
bool result = false;
blackList.ForEach((item) =>
{
Console.WriteLine("Executing");
if (inputString.Contains(item))
{
result = true;
Console.WriteLine("Founded!");
}
},
() => result);
Console.WriteLine(result);
Console.ReadLine();
}
}
public static class MyExtensions
{
public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action, Func<bool> breakOn)
{
foreach (var item in enumerable)
{
action(item);
if (breakOn())
{
break;
}
}
}
}
Would this work for you:
bool result = null != blackList.Find( item => inputString.Contains(item)) );
blackList.ForEach(new Action<string>(
delegate(string item)
{
if(inputString.Contains(item)==true)
{
result = true;
// I want to break here
return;
}
}
));
if you realy want to exist a loop foreach in a list you could use the exception like this code:
public class ExitMyForEachListException : Exception
{
public ExitMyForEachListException(string message)
: base(message)
{
}
}
class Program
{
static void Main(string[] args)
{
List<string> str = new List<string>() { "Name1", "name2", "name3", "name4", "name5", "name6", "name7" };
try
{
str.ForEach(z =>
{
if (z.EndsWith("6"))
throw new ExitMyForEachListException("I get Out because I found name number 6!");
System.Console.WriteLine(z);
});
}
catch (ExitMyForEachListException ex)
{
System.Console.WriteLine(ex.Message);
}
System.Console.Read();
}
}
hope this help to get other point of view.

Categories