4

Im pretty new to programming and I have a challenge but i need your help. My task is to write a program which is reading something from the console and then if its number it will print 1, if its string it will look like this (string + *). Heres my code but there is something wrong and I cant figure it out.Its a must to use Switch - Case.

static void Main(string[] args)
{
    string x = Console.ReadLine();
    switch (x)
    {
        case "int" :
            int i = int.Parse(x);
            i = i + 1;
            Console.WriteLine(i);
            break;
        case "double":
            double d = double.Parse(x);
            d = d + 1;
            Console.WriteLine(d);
            break;
        case "string":
            string s = (x);
            Console.WriteLine(s + "*");
            break;
        default:
            break;
    }        
}  
Michael Mairegger
  • 6,833
  • 28
  • 41
Westmafia
  • 43
  • 4

2 Answers2

2

switch case does not work like that. It takes the argument's data type that you pass:

string x = Console.ReadLine();
switch(x) //x is the argument for switch

As it is. In your case x is always a string. Switch checks the value of the argument and find the designed case for that value, it does not check the type of the argument and find the designed case for that value.

But if your aim is to check if the string is convertible to int, double, DateTime, some other data types, or can only be read as string, you should do it with TryParse for individual data type:

int myInt;
double myDouble;
bool r1 = int.TryParse(x, out myInt); //r1 is true if x can be parsed to int
bool r2 = double.TryParse(x, out myDouble); //r2 is true if x can be parsed to double

Edit:

Since it is a must to use switch case, then you can put the result in an integer:

int a = (r1 ? 1 << 1 : 0) + (r2 ? 1 : 0); //0 if string, 1 if int, 2 if double, 3 if int or double

using concept of bit-flag, and make the switch case like this:

switch (a){
    case 0: //string case
      Console.WriteLine(x + "*");
      break;
    case 1: //int case
      Console.WriteLine((Convert.ToInt32(x) + 1).ToString());
      break;
    case 2: //double case
      Console.WriteLine((Convert.ToDouble(x) + 1).ToString());
      break;
    case 3: //int or double case
      Console.WriteLine((Convert.ToInt32(x) + 1).ToString());
      break;
}

Original:

Then you can do something like this:

if (r1){ //parsable to int
  //do something, like raise the number by 1
  myInt += 1;
  x = myInt.ToString();      
} else if (r2){ //parsable to double
  //do something, like raise the number by 1
  myDouble += 1;
  x = myDouble.ToString();
} else { //cannot be parsed to any
  //do something like add `*`
  x = x + "*";
}
Console.WriteLine(x);
Ian
  • 30,182
  • 19
  • 69
  • 107
  • _with switch - case_ – fubo Apr 01 '16 at 07:44
  • Thanks i am just wondering Why it works with double and string but when the console reads integer it doesnt raise it with 1 ?It should do it as i see the code becouse its the same like the double ....Now i will try the other Original with "if else" it seems pretty easier....I dont know why they request me to do it with switch case – Westmafia Apr 01 '16 at 09:15
  • Oh it works,sorry i made a mistake...I cant answer myself why if i avoid case 3,it doestn works ? – Westmafia Apr 01 '16 at 09:21
  • I would like you to exlplain me how the code works,becouse its hard for me to understand it becouse you know its not only to copy it i want to understand it :) – Westmafia Apr 01 '16 at 09:23
  • @Westmafia what's your question again? you use the `if` case right? – Ian Apr 01 '16 at 09:24
  • No,I am talking about the switch case . I can understand why the code doesnt work without case3 : int or double.Becouse once we have a string,once we have double and once we have int...Why i need a forth case which is case 3 for int and double ?And can you explain me what does that mean "1 << 1" I dont see anywhere the definition of the case 3.How the switch pick's the third case ? – Westmafia Apr 01 '16 at 09:38
  • @Westmafia ah, I see.. (1) if your `string` is `1.0` for example, then it can be converted to `double` but cannot be converted to `int` (because of the decimal separator `.`) but (2) if your string is `1`, then it can be converted to both `double` and `int`. In that case, you need to represent whether the string can be converted to (1) none, (2) int only, (3) double only, (4) both. And the easiest way to do that is by using binary flag: (all in binary: 00 = none, 01= int only, 10 = double only, 11 = int and double) and my code `(r1 ? 1 << 1 : 0) + (r2 ? 1 : 0);` do just that. ;) – Ian Apr 01 '16 at 09:45
  • @Westmafia you know about binary representation of a number, do you? if not, perhaps [this explanation](http://stackoverflow.com/questions/35762313/bit-shifting-x-a-number/36301456#36301456) and also [this](http://stackoverflow.com/questions/35615868/what-hapens-with-bitwise-shift-for-all-8-bits/35615896#35615896) can help you a little. They are for `C` language, but the general rules applied to `C#` as well. – Ian Apr 01 '16 at 09:47
1

Hope this will work, for now it works with int,double,string we can extend

 public static class Extenstions
{
    public static bool IsValid<T>(this string source) where T : struct
    {
        MethodInfo tryParse = (MethodInfo)typeof(T).GetMember("TryParse").FirstOrDefault();
        if (tryParse == null) return false;
        return (bool)tryParse.Invoke(null, new object[] { source, null });
    }
    public static Type GetParsableType(this string source)
    {
        return source.IsValid<int>()&&!source.Contains(".") ? typeof(int) : source.IsValid<double>() ? typeof(double) : typeof(string);

    }
}
class Program
{

    static void Main(string[] args)
    {
        while (true)
        {
            string x = Console.ReadLine();
            switch (x.GetParsableType().Name.ToLower())
            {
                case "int32":
                case "int":
                    int i = int.Parse(x);
                    i = i + 1;
                    Console.WriteLine(i); break;
                case "double":
                    double d = double.Parse(x);
                    d = d + 1;
                    Console.WriteLine(d); break;
                case "string":
                    string s = (x);
                    Console.WriteLine(s + "*"); break;
                default: ; break;
            }
        }
    }
}