Review of Console I/O with win32 functions

The SetConsoleMode() function can be used to set the input and output modes of the console’s input and output buffers. The function takes two arguments; the first argument is the handle to the console, which can be acquired via the GetStdHandle() function.

#include <Windows.h>
#include <stdlib.h>
#include <stdio.h>


int _tmain(int argc, _TCHAR* argv[])
{
	HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
	HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);

	//check to see we got the input handle
	if(hInput == INVALID_HANDLE_VALUE){
		printf("Error getting input handle.\n");
		exit(EXIT_FAILURE);
	} else {
		printf("Input handle acquired.\n");
	}

	//check to see we got the output handle
	if(hOutput == INVALID_HANDLE_VALUE){
		printf("Error getting output handle.\n");
		exit(EXIT_FAILURE);
	} else {
		printf("Output handle acquired.\n");
	}

	return 0;
}

The second argument to the SetConsoleMode() function is a DWORD value that specifies how the characters are processed. There are five commonly used flags that are in fact enabled by default; ENABLE_LINE_INPUT, which specifies that the ReadConsole() function returns when it encounters a carriage return characters; ENABLE_ECHO_INPUT, which echoes characters to the screen as they are read; ENABLE_PROCESSED_INPUT, which processes backspace, carriage return, and line feed characters; ENABLE_PROCESSED_OUTPUT, which processes backspace, carriage return, and line feed characters; and ENABLE_WRAP_AT_EOL_OUTPUT, which enables line wrap for both normal and echoed output.

#include <Windows.h>
#include <stdio.h>

int _tmain(int argc, _TCHAR* argv[])
{
	printf("ENABLE_LINE_INPUT %u\n", ENABLE_LINE_INPUT);
	printf("ENABLE_ECHO_INPUT %u\n", ENABLE_ECHO_INPUT);
	printf("ENABLE_PROCESSED_INPUT %u\n", ENABLE_PROCESSED_INPUT);
	printf("ENABLE_PROCESSED_OUTPUT %u\n", ENABLE_PROCESSED_OUTPUT);
	printf("ENABLE_WRAP_AT_EOL_OUTPUT %u\n", ENABLE_WRAP_AT_EOL_OUTPUT);

	return 0;
}

The SetConsoleMode() function returns True if the function succeeds and False, otherwise.

It is possible to perform console I/O using ReadFile() and WriteFile(), but it is somewhat easier just to use the console I/O functions ReadConsole() and WriteConsole(). The ReadConsole() and WriteConsole() functions process TCHAR values, rather than bytes, and operates according to the console mode.

The ReadConsole() function has five parameters. While the fifth parameter can be set to NULL, the rest must be filled out. The first parameter is a handle to the console input buffer that has GENERIC_READ access. The second parameter is a pointer to a buffer that stores the data read from the console input buffer. The third argument is the number of characters to be read. The fourth argument is a pointer to a DWORD value that stores the number of characters actually read. The ReadConsole() function returns True if the read action succeeds.

#include <Windows.h>
#include <stdlib.h>
#include <stdio.h>

int _tmain(int argc, _TCHAR* argv[])
{
	const int Buffer_Length = 1024;
	TCHAR szBuffer[Buffer_Length];
	DWORD dwLength, dwRead;
	HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);
	
	if(hIn==INVALID_HANDLE_VALUE){
		printf("Invalid handle value.\n");
		exit(EXIT_FAILURE);
	}

	//get length of buffer
	dwLength = _tcslen(szBuffer);

	printf("Please enter the text: ");

	if(ReadConsole(hIn, szBuffer, dwLength, &dwRead, NULL)){
		printf("Read from console.\n");
		printf("%d characters read (includes carriage return / line feed).\n", dwRead);
	} else {
		printf("Failed to read from console.\n");
		exit(EXIT_FAILURE);
	}

        CloseHandle(hIn);

	return 0;
}

Please note that a process can only have one console at a time.

The WriteConsole() function is essentially the same as the ReadConsole() function. The first parameter passed to WriteConsole() is a handle to the console screen buffer. The second parameter is the buffer storing the TCHAR values we wish to write to the console. The third parameter indicates the number of characters we want to write. The fourth parameter is a pointer to a DWORD value that stores the number of characters actually written. We will again pass NULL for the fifth parameter.

#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>

int _tmain(int argc, _TCHAR* argv[])
{
	DWORD dwCount, dwMsgLen;
	HANDLE hIn, hOut;
	BOOL bSuccess;
	TCHAR szBuffer[2056], szWriteBuffer[2112];

	hIn = GetStdHandle(STD_INPUT_HANDLE);
	hOut = GetStdHandle(STD_OUTPUT_HANDLE);

	if(hIn == INVALID_HANDLE_VALUE || hOut == INVALID_HANDLE_VALUE){
		printf("Error getting the handles to the console.\n");
		exit(EXIT_FAILURE);
	}

	//read the text
	printf("Please enter some text: ");

	bSuccess = ReadConsole(hIn, szBuffer, _tcslen(szBuffer), &dwCount, NULL);

	if(!bSuccess){
		printf("Error reading from the console.\n");
		exit(EXIT_FAILURE);
	}

	
	dwMsgLen = dwCount - 2;
	

	szBuffer[dwMsgLen] = '';

	//TCHAR mapping to sprintf()
	swprintf_s(szWriteBuffer, _T("You wrote: '%s' [%d TCHAR written.]\n"), szBuffer, dwMsgLen);

	WriteConsole(hOut, szWriteBuffer, _tcslen(szWriteBuffer), &dwCount, NULL);

	//close the handles!
	CloseHandle(hIn);
	CloseHandle(hOut);

	return 0;
}

If you have any interest in learning standard C, take a look at my book http://www.amazon.com/Big-Als-C-Standard-ebook/dp/B00A4JGE0M/

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s