2

When the input's type is not an integer, the program should fail. However, there are two problems:

  1. After a letter is typed and I get the "not valid" response, then if the next input is a number, it won't accept it and says "not valid".
  2. How can I make it so when a wrong number is inputted, it stays on the same row and just clears the previous input from the screen (and allows for a retry from the same position)?

    static void Main(string[] args)
    {
        int firstNum;
        int Operation = 1;
    
        switch (Operation)
        {
            case 1:
                Console.SetCursorPosition(0, 0);
                Console.Write("Write a number: ");
                firstNum = ReadInteger("");
                Console.ReadKey();
                break;
        }
    }
    
    private static int ReadInteger(string title)
    {
        while (true)
        {
            if (!string.IsNullOrWhiteSpace(title))
                Console.WriteLine(title);
    
            string input = Console.ReadLine();
    
            if (int.TryParse(input, out int result))
                return result;
    
            Console.WriteLine("Sorry, not a valid integer value; please, try again.");
            Console.ReadKey();
        }
    }
    
Sean Pianka
  • 2,157
  • 2
  • 27
  • 43
Ryan W
  • 39
  • 6
  • Possible duplicate of [How do I only allow number input into my C# Console Application?](https://stackoverflow.com/questions/13106493/how-do-i-only-allow-number-input-into-my-c-sharp-console-application) – tmwoods Nov 14 '18 at 20:52
  • 1
    @tmwoods This code only allows number input. That's not the issue, sorry if I didn't make it clear. The issue is after the first input, the number input seems to break and the cursor goes to a different place and rewrite something its not supposed to. – Ryan W Nov 14 '18 at 21:06

2 Answers2

2

Ad 1)

Because you have Console.ReadKey at the end of ReadInteger which will be executed as well. So if you hit Console.ReadLine at the line string input = Console.ReadLine(); and enter something that is not a number, int.TryParse will return false. This leads to the error message and the execution of Console.ReadKey. So you should first of all get rid of that Console.ReadKey there.


Ad 2)

You are setting the cursor position before the call of ReadInteger but not within ReadInteger. So if someone enters a text, the end of the input is typically done by pressing enter. You then write a line (with Console.WriteLine). So if you want to have the cursor at the same position, you will have to reset it's position within the loop which is within the ReadInteger method.

Markus Safar
  • 6,324
  • 5
  • 28
  • 44
-1

How about something like this:

 public static int ReadInt(string prompt)
 {
     Console.Clear();
     var length = prompt.Length + 2;     //2 is for a colon and a space
     var position = length;
     Console.Write($"{prompt}: ");
     string buffer = String.Empty;
     int returnNum = 0;
     while (true)
     {
         Console.SetCursorPosition(position, 0);
         var charRead = Console.ReadKey();
         if(charRead.KeyChar == '\r')
         {
             return returnNum;
         }
         if (!int.TryParse(buffer + charRead.KeyChar, out returnNum))
         {
             Console.SetCursorPosition(position, 0);
             Console.WriteLine(" "); //overwrite
             Console.SetCursorPosition(0, 1);
             Console.Write("Error: enter only digits");
             continue;
         }
         else
         {
             buffer += charRead.KeyChar;
             ++position;
             //overwrite any error
             Console.SetCursorPosition(0, 1);
             Console.Write("                         ");
         }
     }
 }

It's not perfect. It doesn't handle typing in too many digits. It doesn't handle backspace. It clears the console to establish position (it doesn't look like you can read the console position, and I'm too lazy to keep track of things).

If you do handle backspace, make sure you don't let users backup too much. It's been years (um, no, decades) since I've done low level console management, but I can remember doing this in CP/M in the early 80s - if you backed up to far, the OS died (which would be a very result in Windows :-) ).

Flydog57
  • 6,851
  • 2
  • 17
  • 18
  • OK, why the downvote? This seems to do what the OP asked. I don't mind being downvoted, but I'd like to learn something in the process. – Flydog57 Nov 14 '18 at 21:21
  • 1
    OP here, I'm still a beginner. Thanks for the help! I'll come back and try your method when I'm better it's rather confusing to me at the moment. – Ryan W Nov 14 '18 at 21:33
  • @RyanW: It works character by character. It maintains a buffer of the current number (as a string). If the user enters a digit, the `TryParse` will succeed and the new character is added to the buffer. If a non-digit is entered, it does some `SetCursorPos` games to overwrite the bad character (and write an error message on the next line - that message is overwritten on good input). If a new-line comes in, the current buffer/number is returned. Put a breakpoint on the `ReadKey` call, make sure that VS and your console don't overlap and debugging should show you how it works – Flydog57 Nov 14 '18 at 21:47