AUniquee
AUniquee

Reputation: 65

How to get input in the middle of a printed line in .NET 3 console applcation

My question is rather simple, but I can't seem to find a simple answer, no answer at all for that point.

What I want to do is to print a question and then have an answer field, and then write more text after that without waiting for input:

This is a program that solves second degree equations using this formula ax*x + bx + c = d
write your numbers! {WHERE I WANT TO WRITE AND GET INPUT}x*x + bx+ c = d

I wrote {WHERE I WANT TO WRITE AND GET INPUT} where I would want to write when the application is running, the after that get the input, so the application can start doing the math!

Upvotes: 3

Views: 177

Answers (1)

Dai
Dai

Reputation: 155443

NOTE: In the context of console programs, the term "cursor" refers to the caret, or insertion point, of console text - it does not refer to your mouse-pointer.


You can use Console.SetCursorPosition to control where text is written to the console, but it comes with numerous caveats:

Namely, you will need to get the current cursor position with Console.CursorTop and Console.CursorLeft (or Console.GetCursorPosition on .NET 5). This is so that you can know where the cursor is when you print a field - because the console buffer (which can be sized differently to the window) can be resized by the user at any point - this is also why many console programs output garbled text when resized if they aren't controlling the cursor position properly.

Here's an example implementation of your problem: placeholders in a mathematical expression. Note that only single-characters can be inserted at each placeholder (represented by an underscore character). If you want to make the placeholder dynamically expandable as more digits are entered then that's an exercise for the reader (hint: re-print the line by using \r).

        static void Main( string[] args )
        {
            const String line1 = "This is a program that solves second degree equations using this formula ax*x + bx + c = d";
            const String line2 = "write your numbers! _x*x + _x+ _c = d";

            // HACK:
            if( Console.BufferWidth < line2.Length )
            {
                Console.WriteLine( "Please resize your console window to {0} columns and restart this program.", line2.Length );
                return;
            }

            Console.WriteLine( line1 );
            Console.WriteLine( line2 );

            // Get the character indexes of the placeholders:
            Int32 pos1 = line2.IndexOf( '_' );
            Int32 pos2 = line2.IndexOf( '_', pos1 + 1 );
            Int32 pos3 = line2.IndexOf( '_', pos2 + 1 );
            Int32 pos4 = line2.IndexOf( 'd', pos3 + 1 );

#if NET5_0
            (Int32 x, Int32 y) = Console.GetCursorPosition();
#else
            Int32 x = Console.CursorLeft;
            Int32 y = Console.CursorTop;
#endif

            // Curiously, `y` is 2 for the second line (implying base 1), but SetCursorPosition uses base 0, so adjust it:
            y = y - 1;

            // Assuming the placeholders are on the same line without any wrapping:
            Console.SetCursorPosition( left: pos1, top: y );

            Int32? a = ReadDigit();
            if( a == null ) return;

            Console.SetCursorPosition( left: pos2, top: y );

            Int32? b = ReadDigit();
            if( b == null ) return;

            Console.SetCursorPosition( left: pos3, top: y );

            Int32? c = ReadDigit();
            if( c == null ) return;

            // Compute 'd':
            Double d = 1234;// SolveQuadradicFormula( a, b, c );

            // Move cursor where the 'd' is:
            Console.SetCursorPosition( left: pos4, top: y );

            // Then write the value of d:
            Console.Write( d );
            Console.WriteLine();
        }

        private static Int32? ReadDigit()
        {
            do
            {
                ConsoleKeyInfo key = Console.ReadKey();
                if( Char.IsDigit( key.KeyChar ) )
                {
                    return key.KeyChar - '0';
                }
                else if( key.Key == ConsoleKey.Escape )
                {
                    return null;
                }
            }
            while( true );
        }

Screenshot proof:

Waiting for user-input:

enter image description here

After pressing 1 on my keyboard:

enter image description here

Then, after pressing 2 on my keyboard:

enter image description here

Then, after pressing 3 on my keyboard (which also shows the value for d, which is just 1234: a fake placeholder value for now):

enter image description here

Upvotes: 2

Related Questions