0

I have this simple code with switch. The thing is that after any case completed or after default the code is terminated. What I want to get that after completion it would ask the question "Would you like to repeat" and if answer is Y it would run the Main again and it is N it would terminate then and so on. I tried with do...while and no luck any other suggestions?

I am sure it should look something like this:

Console.WriteLine("Would you like to repeat? Y/N");

input = Console.ReadKey().KeyChar;

if (input == 'Y') {...}

The code:

class Switch
{
    static void Main()
    {
        Console.Write("Enter your selection (1, 2, or 3): ");
        string s = Console.ReadLine();
        int n = Int32.Parse(s);

        switch (n)
        {
            case 1:
                Console.WriteLine("Current value is {0}", 1);
                break;
            case 2:
                Console.WriteLine("Current value is {0}", 2);
                break;
            case 3:
                Console.WriteLine("Current value is {0}", 3);
                break;
            default:
                Console.WriteLine("Sorry, invalid selection.");
                break;
        }

        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}

.

Robertas
  • 21
  • 1
  • 4

4 Answers4

1

Let's simplify the problem: extract a method:

   private static void MyRoutine() {
     Console.Write("Enter your selection (1, 2, or 3): "); 

     String input = Console.ReadLine();
     int n = 0;

     // User Input validation: we want integer value (int.TryParse) in the desired rang
     if (!int.TryParse(input, out n)) {
       Console.WriteLine("Sorry, invalid selection. Integer value expected");  

       return;
     }
     else if (n < 1 || n > 3) {
       Console.WriteLine("Sorry, invalid selection. Range of 1..3 expected.");

       return;         
     } 

     // n is valid
     switch (n) {
       case 1:
         Console.WriteLine("Current value is {0}", 1);
         break;
       case 2:
         Console.WriteLine("Current value is {0}", 2);
         break;
       case 3:
         Console.WriteLine("Current value is {0}", 3);
         break;
     }
   }

Now we are ready to keep on running the routine (repeat is usually a loop; here we have do..while):

   static void Main() {
     do {
       MyRoutine();

       Console.WriteLine("Would you like to repeat? Y/N");
     }
     while (char.ToUpper(Console.ReadKey().KeyChar) == 'y');

     Console.WriteLine("Press any key to exit.");
     Console.ReadKey();
   }  
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • This one is not working for me neither. After choosing the option for repeat it terminates. "Enter your selection (1, 2, or 3): 3 Current value is 3 Would you like to repeat? Y/N Press any key to exit." – Robertas Nov 01 '18 at 15:24
  • @Robertas: you probably press lower case `y`, instead of `Y`; let's be nice and accept both possibilities with `char.ToUpper` - see my edit, please – Dmitry Bychenko Nov 02 '18 at 06:50
  • It even did not gave me an option to do that. I managed how it suppose to be. I updated my code. – Robertas Nov 02 '18 at 17:26
0

You could do something like:

class Switch
    {
    static void Main()
    {
    bool repeat = false;
    do {
        repeat = false;
        Console.Write("Enter your selection (1, 2, or 3): ");
        string s = Console.ReadLine();
        int n = Int32.Parse(s);

        switch (n)
        {
            case 1:
                Console.WriteLine("Current value is {0}", 1);
                break;
            case 2:
                Console.WriteLine("Current value is {0}", 2);
                break;
            case 3:
                Console.WriteLine("Current value is {0}", 3);
                break;
            default:
                Console.WriteLine("Sorry, invalid selection.");
                break;
        }
        Console.WriteLine("Would you like to repeat? Y/N");
        input = Console.ReadKey().KeyChar;
        repeat = (input == 'Y');

    }while(repeat);
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
    }

adding a do while loop with a check at the end if the user wants to repeat.

HDP11
  • 59
  • 8
  • This one is not working. Terminates program after choosing an option. doesn't matter which one you choose. – Robertas Nov 01 '18 at 14:55
  • You probably need to change `repeat = (input == 'Y')` to `repeat = (input == 'Y' || 'y')` – Icemanind Nov 01 '18 at 17:02
  • I did like you told. And this is what I get. It is just shows the question. And terminates program immediately. Without choose option. ( Enter your selection (1, 2, or 3): 1 Current value is 1 Would you like to repeat? Y/N Press any key to exit.) – Robertas Nov 01 '18 at 19:45
  • try changing `input = Console.ReadKey().KeyChar; repeat = (input == 'Y');` to `input = Console.ReadLine(); repeat = (input.ToUpper() == "Y")` You now need to press enter after typeing Y – HDP11 Nov 01 '18 at 21:26
0

Thanks everybody. I managed to marge both answers and succeed. This is how this code looks now and it is actually working they way I want.

using System;

class Switch
{
static void Main()
{
bool repeat;
char input ;
do {
    Console.Write("Enter your selection (1, 2, or 3): ");
    string s = Console.ReadLine();
    int n = Int32.Parse(s);

    switch (n)
    {
        case 1:
            Console.WriteLine("Current value is {0}", 1);
            break;
        case 2:
            Console.WriteLine("Current value is {0}", 2);
            break;
        case 3:
            Console.WriteLine("Current value is {0}", 3);
            break;
        default:
            Console.WriteLine("Sorry, invalid selection.");
            break;
    }

Console.WriteLine("Would you like to repeat? Y/N");
input = Convert.ToChar(Console.ReadLine());

    }
  while (input == 'y');

 Console.WriteLine("Press any key to exit.");
 Console.ReadKey();

}  


}
Robertas
  • 21
  • 1
  • 4
-1

Heres a good trick for a loop. For starters if you dont want the app to kill itself and keep it open its time to enter 2018 - Make us of the HostBuilder!

You can have the app startup and stayup and be async, win win win so as a quick example here is a Main entry point for my recent events engine:

public static async Task Main(string[] args)
    {
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

        var startup = new Startup();

        var hostBuilder = new HostBuilder()
            .ConfigureHostConfiguration(startup.ConfigureHostConfiguration)
            .ConfigureAppConfiguration(startup.ConfigureAppConfiguration)
            .ConfigureLogging(startup.ConfigureLogging)
            .ConfigureServices(startup.ConfigureServices)
            .Build();

        await hostBuilder.RunAsync();
    }

Add a nuget package ref to Microsoft.Extensions.Hosting.

You can skip all the startup... lines if you have now DI to sort out. Also youd need to add this line to you project file:

<LangVersion>latest</LangVersion>

Once the app is running any implementation of IHostedService is run automatically. I put my console code in here so here is my example of this:

using MassTransit;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Trabalhos.EventsEngine.Messages;

namespace Trabalhos.EventsEngine.ClientExample
{
    public class SenderHostedService : IHostedService
    {
        private readonly IBusControl eventsEngine;
        private readonly ILogger<SenderHostedService> logger;

        public SenderHostedService(IBusControl eventsEngine, ILogger<SenderHostedService> logger)
        {
            this.eventsEngine = eventsEngine;
            this.logger = logger;
        }

        public async Task StartAsync(CancellationToken cancellationToken)
        {
            var products = new List<(string name, decimal price)>();

            Console.WriteLine("Welcome to the Shop");
            Console.WriteLine("Press Q key to exit");
            Console.WriteLine("Press [0..9] key to order some products");
            Console.WriteLine(string.Join(Environment.NewLine, Products.Select((x, i) => $"[{i}]: {x.name} @ {x.price:C}")));
            for (;;)
            {
                var consoleKeyInfo = Console.ReadKey(true);
                if (consoleKeyInfo.Key == ConsoleKey.Q)
                {
                    break;
                }

                if (char.IsNumber(consoleKeyInfo.KeyChar))
                {
                    var product = Products[(int)char.GetNumericValue(consoleKeyInfo.KeyChar)];
                    products.Add(product);
                    Console.WriteLine($"Added {product.name}");
                }

                if (consoleKeyInfo.Key == ConsoleKey.Enter)
                {
                    await eventsEngine.Publish<IDummyRequest>(new
                    {
                        requestedData = products.Select(x => new { Name = x.name, Price = x.price }).ToList()
                    });

                    Console.WriteLine("Submitted Order");

                    products.Clear();
                }
            }
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            return Task.CompletedTask;
        }

        private static readonly IReadOnlyList<(string name, decimal price)> Products = new List<(string, decimal)>
        {
            ("Bread", 1.20m),
            ("Milk", 0.50m),
            ("Rice", 1m),
            ("Buttons", 0.9m),
            ("Pasta", 0.9m),
            ("Cereals", 1.6m),
            ("Chocolate", 2m),
            ("Noodles", 1m),
            ("Pie", 1m),
            ("Sandwich", 1m),
        };
    }
}

This will statup, run and stay running. The cool thing here is also the for(;;) loop, this is a neat trick to make it run on a loop so you can re-do things over and over, the hosting thing just means you don't need to worry about keeping the console alive.

I even have an escape key like you want:

if (consoleKeyInfo.Key == ConsoleKey.Q)
            {
                break;
            }

For an indepth example of using the Hosted setup, use this link https://jmezach.github.io/2017/10/29/having-fun-with-the-.net-core-generic-host/

Walks through it all so should help.

Aaron Gibson
  • 1,280
  • 1
  • 21
  • 36