3

Before you flag this, I've tried several solutions found here (I swear it is not duplicate) and end up with errors causing VS to crash.

EDIT: Some people said my loop doesn't work. The issue is not there, it has to do with the keypress enter image description here

Here is my original code :

        while (true)
            {
                Console.WriteLine("Voer een getal in : ");
                string invoer = Console.ReadLine();
                Console.Write("Voer de macht in waarmee u wilt vermenigvuldigen :");
                string macht = Console.ReadLine();

                int getal = Convert.ToInt32(invoer);
                int getalmacht = Convert.ToInt32(macht);

                int uitkomst = (int)Math.Pow(getal, getalmacht);
                Console.WriteLine("De macht van " + getal + " is " + uitkomst + " .");
                Console.ReadLine();


            }

It worked fine but it did not look for keypresses.

Here is one that checks for keypress and does not throw a error :

namespace Democonsole
{
class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Press ESC to stop.");

        do
        {
            while (!Console.KeyAvailable)
            {

                Console.WriteLine("Voer een getal in : ");
                string invoer = Console.ReadLine();
                Console.Write("Voer de macht in waarmee u wilt vermenigvuldigen :");
                string macht = Console.ReadLine();

                int getal = Convert.ToInt32(invoer);
                int getalmacht = Convert.ToInt32(macht);

                int uitkomst = (int)Math.Pow(getal, getalmacht);
                Console.WriteLine("De macht van " + getal + " is " + uitkomst + " .");
                Console.ReadLine();


            }
        } while (Console.ReadKey(true).Key != ConsoleKey.Escape);




    }
}

}

It does however upon running crash and give the error as seen in the printscreen.

Any other way to do this?

EDIT : Added more examples of solutions I tried due to request.

    static void Main(string[] args)
{
    var myWorker = new MyWorker();
    myWorker.DoStuff();
    Console.WriteLine("Press any key to stop...");
    Console.ReadKey();
}

break

     while (true)
                    {
                        Console.WriteLine("Voer een getal in : ");
                        string invoer = Console.ReadLine();
                        Console.Write("Voer de macht in waarmee u wilt vermenigvuldigen :");
                        string macht = Console.ReadLine();

                        int getal = Convert.ToInt32(invoer);
                        int getalmacht = Convert.ToInt32(macht);

                        int uitkomst = (int)Math.Pow(getal, getalmacht);
                        Console.WriteLine("De macht van " + getal + " is " + uitkomst + " .");
                        Console.ReadLine();
                        Console.Keypress()



`
Maartenw
  • 595
  • 1
  • 5
  • 19
  • 3
    Please show your code and error as a text in your question. People does not follow 3rd party sites to see your code and error message. – Soner Gönül Dec 03 '15 at 08:25
  • show what you have tried – Nikson K John Dec 03 '15 at 08:27
  • @SonerGönül Edited. Although last time I posted a question people told me to NOT put the code inside the post. – Maartenw Dec 03 '15 at 08:29
  • @MaartenWachters - who told you that? It's a bad habit to *not* post the **relevant** code! Maybe you posted *too much* code (which is just as bad as not posting any at all). A guideline on how much code is the right amount is described here: [sscce](http://sscce.org/) – Corak Dec 03 '15 at 08:36
  • @CPR43 Huh? How exactly is the second implementation correct? Have you actually looked at what it does??? – Corey Dec 03 '15 at 08:39
  • @Corey What exactly is wrong? Asking so I can fix it :) – Maartenw Dec 03 '15 at 08:47
  • I ran your code without problems, everytime i input an integer it asks for another integer and shows the x to the power of y. Loop runs fine. – AnjumSKhan Dec 03 '15 at 08:53
  • @AnjumSKhan Yeah. I'm not sure what is wrong because it runs fine without the keypresses. I implemented it exactly like other posts here on SO – Maartenw Dec 03 '15 at 09:01

2 Answers2

3

The error message tells you pretty much all you need to know about the error, which is that you are trying to convert a string to an integer and the string cannot be converted to an integer. Probably because it's empty.

That's only part of the problem though, which I will address later.

First, your loop structure is wrong. The inner loop runs as long as there is no keypress waiting to be read. But right at the end of the loop's body you are expressly clearing the content of the console buffer, so it will never exit the inner loop.

Consider this minimal example:

while (!Console.KeyAvailable)
{
    Console.ReadLine();
}

Assuming that there are no keys waiting to be read when it encounters the while statement (which will skip the whole thing) the inner statement will accumulate characters from keystrokes until you press enter then return the characters as a string. A few microseconds later it will check to see if you have pressed another key after the enter, which is quite literally impossible. As a result this is a strange way of writing an infinite loop.

Next problem is that you ask for input from the user and assume that the input is going to be valid. It's not, which is what is causing those exceptions you got earlier. Always assume that the user is going to enter something that your program is not expecting and figure out how to deal with it going wrong.

For instance:

string invoer = Console.ReadLine();
int getal;
if (!int.TryParse(invoer, out getal))
{
    Console.WriteLine("Invalid value '{0}'", invoer);
    continue;
}

If the value doesn't convert to a number then this will complain about it and go back to the start of the loop. You might also want to try exiting the loop if the value is empty:

string invoer = Console.ReadLine();
if (string.IsNullOrEmpty(invoer))
    break;
int getal;
if (!int.TryParse(invoer, out getal))
{
    Console.WriteLine("Invalid value '{0}'", invoer);
    continue;
}

That at least gives you a way out of the loop, which you don't have at the moment.

Corey
  • 15,524
  • 2
  • 35
  • 68
  • @MaartenWachters Your loop either doesn't do what you think it does or it does something stupid. If you're fine with that, I can't help you. – Corey Dec 03 '15 at 09:34
  • I'm not sure what you mean then. As you can see here http://imgur.com/JLkUm8s it clearly works. – Maartenw Dec 03 '15 at 09:44
  • @MaartenWachters And how do you exit the loop Maarten? – Corey Dec 03 '15 at 09:52
  • With the console key avaible (that doesn't work, why I came here ). I tried your solution and it also did not work, might be my fault. – Maartenw Dec 03 '15 at 09:55
0

I have a completely alternative solution using the following solution. The title sais, that You want esc checked. So here it is. Highly copied from this solution:

ConsoleHoKeyManager.cs>

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;

namespace ConsoleHotKey
{
    public static class HotKeyManager
    {
        public static event EventHandler<HotKeyEventArgs> HotKeyPressed;

        public static int RegisterHotKey(Keys key, KeyModifiers modifiers)
        {
            _windowReadyEvent.WaitOne();
            int id = System.Threading.Interlocked.Increment(ref _id);
            _wnd.Invoke(new RegisterHotKeyDelegate(RegisterHotKeyInternal), _hwnd, id, (uint)modifiers, (uint)key);
            return id;
        }

        public static void UnregisterHotKey(int id)
        {
            _wnd.Invoke(new UnRegisterHotKeyDelegate(UnRegisterHotKeyInternal), _hwnd, id);
        }

        delegate void RegisterHotKeyDelegate(IntPtr hwnd, int id, uint modifiers, uint key);
        delegate void UnRegisterHotKeyDelegate(IntPtr hwnd, int id);

        private static void RegisterHotKeyInternal(IntPtr hwnd, int id, uint modifiers, uint key)
        {
            RegisterHotKey(hwnd, id, modifiers, key);
        }

        private static void UnRegisterHotKeyInternal(IntPtr hwnd, int id)
        {
            UnregisterHotKey(_hwnd, id);
        }

        private static void OnHotKeyPressed(HotKeyEventArgs e)
        {
            if (HotKeyManager.HotKeyPressed != null)
            {
                HotKeyManager.HotKeyPressed(null, e);
            }
        }

        private static volatile MessageWindow _wnd;
        private static volatile IntPtr _hwnd;
        private static ManualResetEvent _windowReadyEvent = new ManualResetEvent(false);
        static HotKeyManager()
        {
            Thread messageLoop = new Thread(delegate()
            {
                Application.Run(new MessageWindow());
            });
            messageLoop.Name = "MessageLoopThread";
            messageLoop.IsBackground = true;
            messageLoop.Start();
        }

        private class MessageWindow : Form
        {
            public MessageWindow()
            {
                _wnd = this;
                _hwnd = this.Handle;
                _windowReadyEvent.Set();
            }

            protected override void WndProc(ref Message m)
            {
                if (m.Msg == WM_HOTKEY)
                {
                    HotKeyEventArgs e = new HotKeyEventArgs(m.LParam);
                    HotKeyManager.OnHotKeyPressed(e);
                }

                base.WndProc(ref m);
            }

            protected override void SetVisibleCore(bool value)
            {
                // Ensure the window never becomes visible
                base.SetVisibleCore(false);
            }

            private const int WM_HOTKEY = 0x312;
        }

        [DllImport("user32", SetLastError = true)]
        private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);

        [DllImport("user32", SetLastError = true)]
        private static extern bool UnregisterHotKey(IntPtr hWnd, int id);

        private static int _id = 0;
    }


    public class HotKeyEventArgs : EventArgs
    {
        public readonly Keys Key;
        public readonly KeyModifiers Modifiers;

        public HotKeyEventArgs(Keys key, KeyModifiers modifiers)
        {
            this.Key = key;
            this.Modifiers = modifiers;
        }

        public HotKeyEventArgs(IntPtr hotKeyParam)
        {
            uint param = (uint)hotKeyParam.ToInt64();
            Key = (Keys)((param & 0xffff0000) >> 16);
            Modifiers = (KeyModifiers)(param & 0x0000ffff);
        }
    }

    [Flags]
    public enum KeyModifiers
    {
        Alt = 1,
        Control = 2,
        Shift = 4,
        Windows = 8,
        NoRepeat = 0x4000,
        None = 0
    }
}

Program.cs>

using ConsoleHotKey;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Democonsole
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Press ESC to stop.");
            HotKeyManager.RegisterHotKey(Keys.Escape, KeyModifiers.None);
            HotKeyManager.HotKeyPressed += new EventHandler<HotKeyEventArgs>(Console_CancelKeyPress);
            while (true)
            {
                Console.WriteLine("Voer een getal in : ");
                string invoer = Console.ReadLine();
                Console.Write("Voer de macht in waarmee u wilt vermenigvuldigen :");
                string macht = Console.ReadLine();

                int getal = Convert.ToInt32(invoer);
                int getalmacht = Convert.ToInt32(macht);

                int uitkomst = (int)Math.Pow(getal, getalmacht);
                Console.WriteLine("De macht van " + getal + " is " + uitkomst + " .");
                Console.ReadLine();
            }
        }

        static void Console_CancelKeyPress(object sender, HotKeyEventArgs e)
        {
            Environment.Exit(0);
        }
    }
}

You have to reference system.windows.forms too.

Community
  • 1
  • 1
ntohl
  • 2,067
  • 1
  • 28
  • 32