Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent the console to write a character in the last line?

I have a problem with a console project of C#. I want to use the whole console screen to write text in it. Meaning, for example, to "draw" a border along the border of the console. The problem is the unnecessary last character in the last line. How can I prevent it?

For a better understanding, I've added a picture of the unwanted character.Screenshot of the console

I draw it by filling a two dimensional array of chars and dumping it with the following method. yMax is the height and xMax the width of the console window.

private void DumpCharacters()
    {
        for (int y = 0; y < yMax - 1; y++)
        {
            string line = string.Empty;
            for (int x = 0; x < xMax; x++)
            {
                line += characters[x, y];
            }
            Console.SetCursorPosition(0, y);
            Console.Write(line);
        }
    }

I already tried to increase the height of the border, but then, the mentioned character overwrites the border at that position.

EDIT: Sorry for my unclear explanation. Of course I meant, like Attila Bujáki said, the jump to the last line. Is it possible to prevent this?

like image 749
Marco Frost Avatar asked Jan 08 '14 15:01

Marco Frost


People also ask

What is the use of console ReadLine() function?

One of the most common uses of the ReadLine method is to pause program execution before clearing the console and displaying new information to it, or to prompt the user to press the Enter key before terminating the application.

How do I make my console Writeline stay?

To keep the console window open in Visual Studio without using the Console. ReadLine() method, you should run the application without debug mode by pressing Ctrl+F5 or by clicking on the menu Debug > Start without Debugging option.

What is console ReadKey in vb net?

ReadKey() Obtains the next character or function key pressed by the user. The pressed key is displayed in the console window. public: static ConsoleKeyInfo ReadKey();


3 Answers

If you want to fill the whole console window with your characters a possible way to go is to move back your cursor to the 0,0 position.

Example:

Console.CursorVisible = false;
for(int i = 0; i < Console.WindowHeight * Console.WindowWidth; i ++)
{
     Console.Write((i / Console.WindowWidth) % 10);  // print your stuff
}
Console.SetCursorPosition(0, 0);

Console.ReadKey();

So you could do it like this in your method:

private void DumpCharacters()
    {
        for (int y = 0; y < yMax; y++)
        {
            string line = string.Empty;
            for (int x = 0; x < xMax; x++)
            {
                line += characters[x, y];
            }
            Console.SetCursorPosition(0, y);
            Console.Write(line);
        }
        Console.SetCursorPosition(0, 0);
    }

Notice that you don't have to substract one from yMax. It is because now you can use the last line of the Console screen too.

Console with an character border

Here is the full code to generate the desired outcome:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleChar
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Title = "Stackoverflow - Super example";
            Console.CursorVisible = false;

            int yMax = Console.WindowHeight;
            int xMax = Console.WindowWidth;
            char[,] characters= new char[Console.WindowWidth, Console.WindowHeight];

            for (int i = 0; i < Console.WindowWidth; i++ )
            {
                for (int j = 0; j < Console.WindowHeight; j++)
                {
                    char currentChar = ' ';

                    if((i == 0) || (i == Console.WindowWidth - 1))
                    {
                        currentChar = '║';
                    }
                    else
                    {
                        if((j == 0) || (j == Console.WindowHeight - 1))
                        {
                            currentChar = '═';
                        }
                    }                    

                    characters[i, j] = currentChar;
                }
            }

            characters[0, 0] = '╔';
            characters[Console.WindowWidth-1, 0] = '╗';
            characters[0, Console.WindowHeight - 1] = '╚';
            characters[Console.WindowWidth - 1, Console.WindowHeight - 1] = '╝';

                for (int y = 0; y < yMax ; y++)
                {
                    string line = string.Empty;
                    for (int x = 0; x < xMax; x++)
                    {
                        line += characters[x, y];
                    }
                    Console.SetCursorPosition(0, y);
                    Console.Write(line);
                }
            Console.SetCursorPosition(0, 0);
        }
    }
}
like image 87
Attila Avatar answered Oct 30 '22 18:10

Attila


Use CursorVisible property of Console

Console.CursorVisible = false;
like image 24
gleng Avatar answered Oct 30 '22 18:10

gleng


The accepted answer doesn't work if the Console buffer size is the same as the window size. As Phillip Scott Givens mentioned above, you have to use Console.MoveBufferArea writing to somewhere other than the bottom-right corner. This is the only way to solve the problem using the System.Console API even with Console.CursorVisible = false. Example code:

var w = Console.WindowWidth;
var h = Console.WindowHeight;
Console.SetBufferSize(w, h);

// Draw all but bottom-right 2 characters of box here ...

// HACK: Console.Write will automatically advance the cursor position at the end of each
// line which will push the buffer upwards resulting in the loss of the first line
var sourceReplacement = '═';
Console.SetCursorPosition(w - 2, h - 1); // bottom-right minus 1
Console.Write('╝');
// Move from bottom-right minus 1 to bottom-right overwriting the source
// with the replacement character
Console.MoveBufferArea(w - 2, h - 1, 1, 1, w - 1, h - 1,
    sourceReplacement, Console.ForegroundColor, Console.BackgroundColor);

If you're not fine with that, you can use the native console API (but it is Windows-only):

// http://pinvoke.net/default.aspx/kernel32/FillConsoleOutputCharacter.html
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool FillConsoleOutputCharacter(
    IntPtr hConsoleOutput,
    char cCharacter,
    uint nLength,
    COORD dwWriteCoord,
    out uint lpNumberOfCharsWritten
    );
like image 23
Graeme Wicksted Avatar answered Oct 30 '22 20:10

Graeme Wicksted