Console I/O

This section provides information on how to perform input and output operations with the Windows console.

Introduction to Console I/O

The Windows console provides a powerful interface for text-based applications. The Console I/O API allows you to read user input from the keyboard, write text and graphical elements to the console screen, manage the cursor, and control text formatting.

Console Handles

Console I/O operations are performed using handles. The system provides standard handles for input and output:

You can retrieve these handles using the GetStdHandle function.

HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

Reading Input

Reading input from the console typically involves using functions like ReadConsole or ReadConsoleInput. ReadConsole is suitable for reading text input, while ReadConsoleInput provides more detailed information about various input events (key presses, mouse events, etc.).

ReadConsole

Reads characters from the standard input stream and stores them in a buffer.

BOOL ReadConsole(
  HANDLE  hConsoleInput,
  LPVOID  lpBuffer,
  DWORD   nNumberOfCharsToRead,
  LPDWORD lpNumberOfCharsRead,
  LPVOID  pReserved
);

Parameters:

ReadConsoleInput

Reads one or more input records from a console input buffer.

BOOL ReadConsoleInput(
  HANDLE            hConsoleInput,
  PINPUT_RECORD   lpBuffer,
  DWORD             nLength,
  PDWORD            lpNumberOfEventsRead
);

Writing Output

Text can be written to the console using WriteConsole or WriteConsoleOutputCharacter.

WriteConsole

Writes a string of characters to the console screen.

BOOL WriteConsole(
  HANDLE  hConsoleOutput,
  const VOID *lpBuffer,
  DWORD   nNumberOfCharsToWrite,
  LPDWORD lpNumberOfCharsWritten,
  LPVOID  lpReserved
);

Parameters:

WriteConsoleOutputCharacter

Writes character and attribute information to a specified rectangular block of character cells in a console screen buffer.

BOOL WriteConsoleOutputCharacter(
  HANDLE      hConsoleOutput,
  const TCHAR *lpCharacter,
  DWORD       nLength,
  COORD       dwWriteCoord,
  LPDWORD     lpNumberOfCharsWritten
);

Screen Buffer Management

The console has a screen buffer that holds the characters and attributes displayed on the screen. You can manipulate this buffer to control the appearance and content of the console window.

SetConsoleScreenBufferSize

Sets the size of the console screen buffer in character cells.

GetConsoleScreenBufferInfo

Retrieves information about the specified console screen buffer, including its size, cursor position, and window dimensions.

BOOL GetConsoleScreenBufferInfo(
  HANDLE                      hConsoleOutput,
  PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo
);

Cursor Position Control

You can query and set the console cursor's position using the following functions:

SetConsoleCursorPosition

Sets the position of the cursor in a specified console screen buffer.

BOOL SetConsoleCursorPosition(
  HANDLE hConsoleOutput,
  COORD  dwCursorPosition
);

The COORD structure specifies the X and Y coordinates (column and row) of the cursor.

GetConsoleCursorInfo

Retrieves information about the size and shape of the cursor.

Console Color Attributes

The appearance of text in the console can be controlled using foreground and background color attributes. These are typically set using SetConsoleTextAttribute.

SetConsoleTextAttribute

Sets the character attributes (including color) for subsequent text output operations.

BOOL SetConsoleTextAttribute(
  HANDLE hConsoleOutput,
  WORD   wAttributes
);

The wAttributes parameter is a bitmask specifying the foreground and background colors. Common color constants include:

Example: Set text to bright red on a black background.

SetConsoleTextAttribute(hStdout, FOREGROUND_RED | FOREGROUND_INTENSITY);
Note: Console color attributes are bitwise OR'ed together. For example, to get yellow text, you would OR FOREGROUND_RED and FOREGROUND_GREEN.

Error Handling

Most console I/O functions return a non-zero value to indicate success and zero to indicate failure. You can get more specific error information by calling GetLastError.

DWORD error = GetLastError();
if (error != ERROR_SUCCESS) {
    // Handle the error
}