Home Bask to C/C++ Index Tips & Tricks Index Links

General C/C++ coding techniques

A friend needed some C and C++ tutoring.  Her school, which I'll not name, decided that they could teach their students C and C++ as a single course!  Excuse me, but how in the world is someone going to handle C++ without the basic C foundation?

In my not so humble opinion, one should first teach students assembler language, followed by a higher level language (C, for example), and then teach them the object oriented techniques and constructs (C++, for example).

Another friend, who is an experienced programmer instructor was impressed enough with my tutoring, that he asked my permission to use my hangman example in his C/C++ classes.  I granted him permission.

Anyway, I've chosen to place the tutoring homework that I provided to my friend here, so that you may examine some C and C++ coding techniques.   The homework assignment was to write a simple hangman program in C/C++ that reads a random word from a text file for the user to guess.  For simplicity, it has no  separate header file.

The program will run in a DOS box under Windows 9x, NT, 2000 or XP (It's a 32 bit console application, so it needs to run under a Windows DOS box), or under UNIX and Linux.

The Windows download is a zip file containing the hangman source, executable, sample text file with words and a makefile if you want to compile it yourself.  The makefile was generated with Microsoft Visual C++ 5.0.

To compile the Windows console version yourself, you need a compiler and linkage editor as well as some flavor of make.  The following works for me:

pkunzip   hangman.zip
nmake  /f hangman.mak

The UNIX/Linux download is a "tar ball" containing the same.
To extract the "tar ball" change to your directory of choice and use:

gunzip -c hangman.tar.gz | tar -xvf -

(Note the trailing hyphen)

The UNIX/Linux "tar ball" contains a GLIBC 2.0 executable, so you might need to recompile hangman before you can use it.  To do this, switch to the directory where you extracted  the "tar ball" files and type:

make

The source code is identical for both the Windows and the UNIX/Linux versions.

Download Hangman
Windows Version
   
File date:   Thursday, 02-Dec-2004 11:56:10 EST
File size:   91,898 bytes
UNIX/Linux Version
   
File date:   Thursday, 02-Dec-2004 11:54:07 EST
File size:   25,153 bytes

Here is the "Hangman" source code.

/*----------------------------------------------------------------------------------------------*/
/* Homework - Hangman in C++.                                                                   */
/* --------------------------                                                                   */
/*                                                                                              */
/* This program will open a file of words, randomly select one of the words in the file and     */
/* provide the terminal operator an opportunity to guess the word.  It displays underscores     */
/* to indicate the number of characters in the word and fills each underscore with a letter     */
/* for each correct guess.                                                                      */
/*                                                                                              */
/* After 10 incorrect guesses, the operator is notified that he or she is hanged and the word   */
/* is displayed.  If the operator solves the word, a congratulation message is displayed.       */
/*----------------------------------------------------------------------------------------------*/

#include    <stdlib.h>                      // This is where standard c functions are defined.
#include    <stdio.h>                       // This is where fopen, fclose, etc., are defined.

#ifdef      DEPRECATED                      // Older (DEPRECATED) compiler support.
#include    <iostream.h>                    // This is where cout is defined.
#include    <fstream.h>                     // This is where ifstream is defined.
#else                                       // New (not DEPRECATED) compiler support.
#include    <iostream>                      // This is where cout is defined.
#include    <fstream>                       // This is where ifstream is defined.
#endif                                      // End of DEPRECATED/Not-DEPRECATED support.

#ifdef      UNIX                            // UNIX/LINUX only.
#include    <unistd.h>                      // This is where read is defined.
#include    <termios.h>                     // This is where the termios functions are defined.
#include    <ctype.h>                       // This is where the type conversions are defined.
#endif                                      // End of UNIX/LINUX only.

#ifndef     UNIX                            // Windows (95/98/NT/2000) only.
#include    <conio.h>                       // This is where getch is defined.
#endif                                      // End of Windows (95/98/NT/2000) only.

#include    <malloc.h>                      // This is where malloc and memset are defined.
#include    <time.h>                        // This is where the time functions are defined.
#include    <string.h>                      // This is where the string handling functions
                                            // are defined.

#define MAXWORDSIZE 256                     // Arbitrarily define the maximum word size.

#ifdef  UNIX                                // UNIX/LINUX only.
char    getch(void);                        // Declare the getch function for UNIX.
#endif                                      // End of UNIX/LINUX only.

#ifndef DEPRECATED                          // New (not DEPRECATED) compiler support.
using   namespace std;                      // This tells the compiler to use the standard
                                            // namespace - e.g., cout is 'std::cout'.
#endif                                      // End of New (not DEPRECATED) compiler support.

class   hangman                             // Beginning of Hangman class definition.
{
public:                                     // Public hangman functions and data.
            hangman(void);                  // Constructor creates the hangman object.
    bool    guessword(char *);              // Member function stores the word.
    bool    guess(char);                    // Member function check the letter.
    bool    isused(char);                   // Member function to check if letter is used.
    bool    hanged(void);                   // Member function to check if you're hanged.
    int     solved(void);                   // Member function to check if you've solved the word.
    int     remaining(void);                // Member function to return guesses remaining.
    char   *theword(void);                  // Member function to return a pointer to the word.
    void    display(void);                  // member function displays correct letters.
           ~hangman(void);                  // Destructor destroys a hangman object.

protected:                                  // Protected hangman functions and data.
                                            // There aren't any.

private:                                    // Private hangman functions and data...
                                            // Only the hangman object can directly access these.

    char   *word;                           // This is the word to solve.
    char   *letters;                        // This contains our correct guesses so far.
    int     guesses;                        // This is the number of guesses remaining.
    char   *used;                           // This contains the letters we've tried so far.
};

/*----------------------------------------------------------------------------------------------*/
/* This is the hangman class constructor.                                                       */
/* --------------------------------------                                                       */
/*                                                                                              */
/* It initializes the private hangman member variables.                                         */
/*                                                                                              */
/* Call with:   void    -   Nothing.                                                            */
/*                                                                                              */
/* Returns:             -   Nothing (Constructors aren't allowed to return anything.            */
/*----------------------------------------------------------------------------------------------*/
hangman::hangman(void)
{
    word    = 0;
    letters = 0;
    guesses = 0;
    used    = 0;
}

/*----------------------------------------------------------------------------------------------*/
/* This is the function to store the word to solve.                                             */
/* ------------------------------------------------                                             */
/*                                                                                              */
/* It allocates real system storage to store the word to solve, the current word, the letters   */
/* guessed so far and the maximum number of guesses allowed before you're hanged.               */
/*                                                                                              */
/* Call with:   char *  -   a pointer to a "C" type string array.                               */
/*                                                                                              */
/* Returns:     bool    -   True  (1) if successful.                                            */
/*                          False (0) if unsuccessful.                                          */
/*----------------------------------------------------------------------------------------------*/
bool    hangman::guessword(char *newword)   // Function stores the word to solve. 
{
    int    i;                               // General purpose integer for the word length.

    i    = strlen(newword);                 // Get the length of the word character array.

    if (!(word = new char[i + 1]))          // Ensure there's enough system memory to store the
        return false;                       // word to solve.  If not, return false.

    word[0] = '\0';                         // Terminate the "C" string.
    strcpy(word, newword);                  // Copy the string into the array
    
    if (!(letters = new char[i + 1]))       // Ensure there's enough system memory to store the
        return false;                       // correctly guessed letters. If not, return false.

    memset(letters, '_', i);                // Initialize the array to underscores.
    letters[i] = '\0';                      // Terminate the "C" string.

    if (!(used = new char[i + 11]))         // Ensure there's enough system memory to store the
        return 0;                           // letters guessed so far. If not, return false.

    used[0] = '\0';                         // Terminate the "C" string.

    guesses = 10;                           // Initialize the maximum number of incorrect guesses.

    return true;                            // Everything's ok, so return true.
};

/*----------------------------------------------------------------------------------------------*/
/* This is the function to test whether a letter has already been tried.                        */
/* ---------------------------------------------------------------------                        */
/*                                                                                              */
/* Call with:   char    -   a character integer containing the letter to guess.                 */
/*                                                                                              */
/* Returns:     bool    -   True  (1) if we've already used this character.                     */
/*                          False (0) if we haven't used this character yet.                    */
/*----------------------------------------------------------------------------------------------*/
bool    hangman::isused(char c)             // Function tests to see whether the letter has
{                                           // already been tried.
        int x = strlen(used);               // Get the length of the "used letters" string.

        while (x)                           // Try every letter in the string array.
        {                                   // Remember arrays are relative to zero (thus - 1).
                                            // We don't care about case, thus the tolower's. 
            if (tolower(c) == tolower(used[x - 1]))
                return true;                // If we find a match, return true.
            else                            // Otherwise,
                x--;                        // decrement the array subscript until it's zero.
        }
        return false;                       // No match, so return false.
}

/*----------------------------------------------------------------------------------------------*/
/* This is the function that tries a new letter and stores it in the used letter array.         */
/* ------------------------------------------------------------------------------------         */
/*                                                                                              */
/* This function also decrements the remaining guesses counter if the character doesn't exist   */
/* in the word to solve.                                                                        */
/*                                                                                              */
/* Call with:   char    -   a character integer containing the letter to guess.                 */
/*                                                                                              */
/* Returns:     bool    -   True  (1) if the character appears one or more times in the word.   */
/*                          False (0) if the character doesn't appear in the word.              */
/*----------------------------------------------------------------------------------------------*/
bool    hangman::guess(char c)              // Function tests whether a letter is in the word.
{
        unsigned
        int     x;                          // General purpose unsigned integer.
        bool    f = false;                  // Boolean return flag initialized to false.

        x = strlen(used);                   // Get the length of the used letters array.

        used[x] = c;                        // Store this letter at the end of the used letter
        used[x + 1] = '\0';                 // array and terminate the "C" string.

        x = 0;                              // Re-initialize x to zero.

        while (x < strlen(word))            // Test all the characters in the word.
        {                                   // We don't care about case (thus the tolower's).
            if (tolower(c) == tolower(word[x]))
            {                               // If it's a match, store it in the correct position
                letters[x] = word[x];       // in the correct letters array.
                f = true;                   // Set the return flag to true.
            }

            x++;                            // Increment the word subscript to try the next letter.
        }

        if (!f)                             // If the flag has not been set to true, the guess 
            if (guesses)                    // was incorrect, so decrement the remaining guesses
                guesses--;                  // allowed counter.

        return f;                           // Return a boolean true of false.
}

/*----------------------------------------------------------------------------------------------*/
/* This function returns the number of guesses remaining.                                       */
/* ------------------------------------------------------                                       */
/*                                                                                              */
/* Call with:   void    -   nothing.                                                            */
/*                                                                                              */
/* Returns:     int     -   an integer reflecting the number of guesses remaining.              */
/*----------------------------------------------------------------------------------------------*/
int     hangman::remaining(void)
{
        return  guesses;                    // Return the number of guesses remaining.
}

/*----------------------------------------------------------------------------------------------*/
/* This function returns whether you're hanged or not.                                          */
/* ---------------------------------------------------                                          */
/*                                                                                              */
/* Call with:   void    -   nothing.                                                            */
/*                                                                                              */
/* Returns:     bool    -   a boolean true or false.                                            */
/*                          False (0) if you still have guesses remaining.                      */
/*                          True  (1) if the guesses counter has been decremented to zero.      */
/*----------------------------------------------------------------------------------------------*/
bool    hangman::hanged(void)
{
    if (guesses)                            // Is guesses non-zero?
        return false;                       // Return false.

    return true;                            // Otherwise, return true.
}

/*----------------------------------------------------------------------------------------------*/
/* This function returns whether you've solved the word or not.                                 */
/* ------------------------------------------------------------                                 */
/*                                                                                              */
/* Call with:   void    -   nothing.                                                            */
/*                                                                                              */
/* Returns:     int     -   an integer.                                                         */
/*                          non-zero if you've correctly guessed the word.                      */
/*                          Zero if you haven't guessed the word yet.                           */
/*----------------------------------------------------------------------------------------------*/
int     hangman::solved(void)
{       
        return !strcmp(letters, word);      // Return the compliment of the string compare.
}

/*----------------------------------------------------------------------------------------------*/
/* This function displays the correctly guessed letters so far.                                 */
/* ------------------------------------------------------------                                 */
/*                                                                                              */
/* Call with:   void    -   nothing.                                                            */
/*                                                                                              */
/* Returns:     void    -   nothing.                                                            */
/*----------------------------------------------------------------------------------------------*/
void    hangman::display(void)
{
        cout << letters << endl << endl;    // Display the "letters" character string.
}

/*----------------------------------------------------------------------------------------------*/
/* This function returns a pointer to the word to solve character array.                        */
/* ---------------------------------------------------------------------                        */
/*                                                                                              */
/* Call with:   void    -   nothing.                                                            */
/*                                                                                              */
/* Returns:     char *  -   A pointer the the character array containing the word to solve.     */
/*----------------------------------------------------------------------------------------------*/
char   *hangman::theword(void)
{
        return word;                        // Return the pointer to the word character array.
}

/*----------------------------------------------------------------------------------------------*/
/* This is the hangman object destructor.                                                       */
/* --------------------------------------                                                       */
/*                                                                                              */
/* It returns all of the resources that the hangman object allocated back to the operating      */
/* system.                                                                                      */
/*                                                                                              */
/* Call with:   void    -   nothing.                                                            */
/*                                                                                              */
/* Returns:     void    -   nothing.                                                            */
/*----------------------------------------------------------------------------------------------*/
hangman::~hangman(void)
{
    if  (word)                              // If we allocated memory for the word array,
        delete [] word;                     // release it.

    if  (letters)                           // If we allocated memory for the letters array,
        delete [] letters;                  // release it.

    if  (used)                              // If we allocated memory for the used array,
        delete [] used;                     // release it.
}                                           // End of Hangman class definition.

/*----------------------------------------------------------------------------------------------*/

class   wordfile                            // Beginning of wordfile class definition.
{
public:                                     // Public wordfile functions and data.
            wordfile(void);                 // Constructor creates the wordfile object.
    char   *getword(char *);                // Member function to read a word from a file.
           ~wordfile(void);                 // Destructor destroys a wordfile object.

protected:                                  // Protected wordfile functions and data.
                                            // Only the wordfile object and its subclasses
                                            // can use these.

    bool    openfile(char *);               // Member function to open a wordfile file.
    void    closefile(void);                // Member function to close a wordfile file.
    int     countwords(void);               // Member function to count the words in a file.
    int     randomword(void);               // Member function to generate a random word number.

private:                                    // Private wordfile functions and data.
                                            // Only the wordfile object can access these.

    ifstream                                // Input file stream:
           *fstr;                           // Pointer to and ifstream ios derived object.

    char    word[MAXWORDSIZE];              // Character array that contains the random word.
    int     nwords;                         // Integer that contains the number of words in the 
};                                          // file.

/*----------------------------------------------------------------------------------------------*/
/* This is the wordfile class constructor.                                                      */
/* --------------------------------------                                                       */
/*                                                                                              */
/* It initializes the private wordfile member variables.                                        */
/*                                                                                              */
/* Call with:   void    -   Nothing.                                                            */
/*                                                                                              */
/* Returns:             -   Nothing (Constructors aren't allowed to return anything.            */
/*----------------------------------------------------------------------------------------------*/
wordfile::wordfile(void)
{
    fstr    =   0;                          // Set the ifstream pointer to zero.
    word[0] = '\0';                         // Initialize the word array to a null "C" string.
    nwords  =   0;                          // Initialize the word counter to zero.
}

/*----------------------------------------------------------------------------------------------*/
/* This function opens a file containing a list of words to guess.                              */
/* ---------------------------------------------------------------                              */
/*                                                                                              */
/* Call with:   char *  -   A pointer to a character array containing the file name to open.    */
/*                                                                                              */
/* Returns:     bool    -   True  (1) if the input file stream was successfully opened.         */
/*                          False (0) if there was a problem opening the input file stream.     */
/*----------------------------------------------------------------------------------------------*/
bool    wordfile::openfile(char *f)
{
    fstr = new ifstream(f,                  // Construct a new input file stream object and
                        ios::in);           // try to open it for reading an existing file;

    if  (fstr->is_open())                   // Test whether the ifstream opened properly.
        return true;                        // If it did, return true.
    else
        return false;                       // Otherwise, return false.
}

/*----------------------------------------------------------------------------------------------*/
/* This function closes a file containing a list of words to guess.                             */
/* ----------------------------------------------------------------                             */
/*                                                                                              */
/* Call with:   void    -   Nothing.                                                            */
/*                                                                                              */
/* Returns:     void    -   Nothing.                                                            */
/*----------------------------------------------------------------------------------------------*/
void    wordfile::closefile(void)
{
    if  (fstr)                              // If the input file stream pointer is not zero,
    {                                       // and if the input file stream is still open,
        if  (fstr->is_open())               // destroy the object (which closes the file and
            fstr->~ifstream();              // releases its internal buffer) - a simple close
                                            // does not release the internal buffer.
        fstr = 0;                           // Set the input file stream pointer to zero.
    }
}

/*----------------------------------------------------------------------------------------------*/
/* This function counts the number of words in the file.                                        */
/* -----------------------------------------------------                                        */
/*                                                                                              */
/* Call with:   void    -   Nothing.                                                            */
/*                                                                                              */
/* Returns:     int     -   An integer containing the number of words found in the file.        */
/*----------------------------------------------------------------------------------------------*/
int     wordfile::countwords(void)
{
    while   (!fstr->eof())                  // Read the file until we reach end of file (EOF).
    {
        fstr->getline(word, MAXWORDSIZE);   // Read a word character array up to MAXWORDSIZE in
                                            // length.
        int x    = fstr->rdstate();         // Get the I/O status for the previous read.

        if  ((x == ios::goodbit) ||         // If there were no errors (EOF is ok),
             (x == ios::eofbit))            // increment the word counter.
             nwords++;
        else    
             return 0;                      // Otherwise return zero.
    }
    
    fstr->seekg(0);                         // Set the word file position back to the beginning
    fstr->clear(ios::goodbit);              // of the file and clear the end of file (EOF) flag.

    return nwords;                          // Return the number of words counted.
}

/*----------------------------------------------------------------------------------------------*/
/* This function tries to generate a random number to randomly select a word.                   */
/* --------------------------------------------------------------------------                   */
/*                                                                                              */
/* Note: Most C Runtime psuedo random number generators are really flakey.                      */
/*                                                                                              */
/* Call with:   void    -   Nothing.                                                            */
/*                                                                                              */
/* Returns:     int     -   An integer containing the random word number to read.               */
/*----------------------------------------------------------------------------------------------*/
int     wordfile::randomword(void)
{                                           // Display what we're doing.
    cout << "Selecting a random word out of a list of "
         <<  nwords << " words." << endl;

    srand(time(NULL));                      // Seed the random number generator with the number
                                            // of seconds elapsed since midnight, Jan 1, 1970.
    int i, x;                               // Declare some general purpose integers.

    for (x = 0; x < 7; x++)                 // Use a prime number (7) and get the seventh
        i = rand();                         // number from the random number generator.

    while (i > nwords)                      // Make the random number fall within the number of
        i = i/10;                           // words in the file by dividing by 10 until the
                                            // number is within our range.

                                            // Display the word number we picked.
    cout << "Selected word number "
         << i << endl << endl;

    return i;                               // Return the word number.
}

/*----------------------------------------------------------------------------------------------*/
/* This function returns a randomly selected word from the wordfile.                            */
/* -----------------------------------------------------------------                            */
/*                                                                                              */
/* Call with:   char *  -   A pointer to a character array file name.                           */
/*                                                                                              */
/* Returns:     char *  -   A pointer to a character array containing the random word.          */
/*----------------------------------------------------------------------------------------------*/
char   *wordfile::getword(char *f)
{
    int     i;                              // Declare a general purpose integer.
    
    if (!openfile(f))                       // Open the word list file.
        return 0;                           // Return a zero pointer if there was a problem.

    if (!countwords())                      // Count the number of words in the file.
        return 0;                           // Return a zero pointer if there was a problem.

    i = randomword();                       // Get a random word number.

    for (int x = 0; x < i; x++)             // Find the word within the file by reading each
    {                                       // word starting from the first one, until we
        fstr->getline(word, MAXWORDSIZE);   // reach the word number that was picked by the
                                            // random number generator.
        int e    = fstr->rdstate();         // Get the status of the last read I/O.

        if  ((e == ios::failbit) ||         // If there were any I/O errors while reading the
             (e == ios::badbit))            // file, return a zero pointer.
             return 0;
    }

    if ((i = strlen(word)) < 2)             // Make sure our word is at least 2 bytes in length.
        return 0;                           // Return a zero pointer if it's less.

    closefile();                            // We're done with the file, so close it.

    return word;                            // Return the pointer to the word we found.
}

/*----------------------------------------------------------------------------------------------*/
/* This is the wordfile object destructor.                                                      */
/* ---------------------------------------                                                      */
/*                                                                                              */
/* It returns all of the resources that the wordfile object allocated back to the operating     */
/* system.                                                                                      */
/*                                                                                              */
/* Call with:   void    -   nothing.                                                            */
/*                                                                                              */
/* Returns:     void    -   nothing.                                                            */
/*----------------------------------------------------------------------------------------------*/
wordfile::~wordfile(void)
{
    closefile();                            // Close the file if someone inadvertently left it
}                                           // open.
                                            // End of wordfile class definition.

/*----------------------------------------------------------------------------------------------*/
/* This is the main entry point of the hangman program.                                         */
/* ----------------------------------------------------                                         */
/*                                                                                              */
/* Call with:   void    -   Nothing.                                                            */
/*                                                                                              */
/* Returns:     int     -   An integer return code.                                             */
/*                          0  if everything went ok.                                           */
/*                          8  if the word file could not be opened.                            */
/*                          12 if the operating system had insufficient real memory resources   */
/*                             to allocate the neccessary arrays.                               */
/*----------------------------------------------------------------------------------------------*/
int main    (void)                          // Begining of program (entry point).
{
    char   *w;

    cout << "Hangman" << endl               // Display a title on the screen.
         << "Tutored to Laurie Beatty by Marc Niegowski"
         << endl      << endl;

    wordfile wf;                            // Build a wordfile object.

    if (!(w = wf.getword("hangman.txt")))   // Read a random word from the "hangman.txt" file.
    {
        cout << "Error reading the hangman.txt data file containing"
             << endl << "a list of words to guess."
             << endl << endl;

        return 8;                           // Return to the operating system with condition
    }                                       // code 8 if there was a problem opening the file.

    hangman hm;                             // Build a hangman object.

    if (!hm.guessword(w))                   // Store a word in the hangman object.
    {                                       // If we couldn't allocate memory for the arrays...
        cout << "There isn't enough system memory to run this program."
             << endl;

        return 12;                          // Return to the operating system with condition
    }                                       // code 12.

    while (!hm.hanged())                    // While we're not hanged...
    {
        char c;                             // General purpose character integer.
                                            // Display the number of guesses remaining.
                                            // We get this number from the hangman object.
        cout << hm.remaining()
             << " Guesses remaining"
             << endl << endl;
        
        hm.display();                       // The hangman object will display the guesses so far.

        cout << "Guess a letter: "          // Prompt the user for a letter and
             << flush;                      // flush the buffer (no new line manipulator).

        while (true)                        // Start an indefinite loop.
        {
            c = getch();                    // Get a character from the keyboard.
            if (((c >= 'A') && (c <= 'Z')) ||
                ((c >= 'a') && (c <= 'z')) ||
                 (c == ' ') || (c == '-'))  // We only want A-Z or a-z or a space or hyphen. 
                break;                      // Get out if we have a valid character.
        }

        cout << c                           // Display the letter the user chose
             << endl << endl;               // and send out a couple of new lines.

        if (hm.isused(c))                   // The hangman object will test if the letter is
                                            // already used.
                                            
            cout << "You've already tried " // If it has been, display a message and ask for
                 << c                       // another letter.
                 << ", try another letter."
                 << endl << endl;
        else                                // Otherwise, the hangman object will test the
            hm.guess(c);                    // letter for one or more matches in the word.

        if (hm.solved())                    // The hangman object will test to see whether
            break;                          // the word has been solved.  If it has, break 
    }                                       // out of the "while not hanged" loop.
    
    if (hm.solved())                        // If it's solved, display the solved word and
    {                                       // a congrats. message.
        cout << "Correct '"
             << hm.theword()
             << "'." << endl;

        cout << "Congratulations, you solved the word!"
             << endl << endl;
    }
    else                                    // Otherwise, display a hanged message
    {                                       // followed by the word to solve.
        cout << "Sorry, you're hanged!"
             << endl;

        cout << "The word was '"
             <<  hm.theword()
             << "'." << endl << endl;
    }

    return 0;                               // Return to the operating system with return code 0.
}

#ifdef  UNIX                                // UNIX/LINUX only.

char    getch()                             // Function to read a raw character from the keyboard.
{
    fd_set  kb;                             // Declare a file descriptor for the keyboard.
    char    ch = '\0';                      // Declare a character and initialize it to null.
    
    termios newtty,                         // Declare a termios structure for the new TTY
            oldtty;                         // settings and one to save the current settings.
            
    if (tcgetattr(0, &oldtty) == -1)        // Get the current TTY attributes.
    {
        cout << "Unable to save the TTY attributes."
             << endl << endl;

        exit(8);                            // Exit to the operating system with a condition code
    }                                       // 8 if we weren't able to save the current settings.
    
    newtty  = oldtty;                       // Start out with the same TTY attributes.
    
    newtty.c_lflag     &= ~ICANON;          // Turn of the wait for end of line (EOL).
    newtty.c_lflag     &= ~ECHO;            // Don't echo any characters to the display.
    newtty.c_cc[VMIN]   =  1;               // Set the minimum character buffer.
    newtty.c_cc[VTIME]  =  0;               // Set the minimum wait time.
    
    if (tcsetattr(0, TCSAFLUSH, &newtty) == -1)
    {                                       // Set our new tty attributes.
        cout << "Unable to set the TTY attributes."
             << endl << endl;

        exit(8);                            // If it fails, return to the operating system
    }                                       // with a condition code of 8.
    
    FD_ZERO(&kb);                           // Clear out the file descriptor set.
    FD_SET(0, &kb);                         // Add STDIN (fd 0) to the file descriptor set.
    
    select(1, &kb, NULL, NULL, NULL);       // Wait for a character from STDIN.
    
    read(1, &ch, 1);                        // Read one byte from STDIN.

    if (tcsetattr(0, TCSAFLUSH, &oldtty) == -1)
    {                                       // Restore the original TTY settings.
        cout << "Unable to restore the TTY attributes."
             << endl << endl;

        exit(8);                            // Exit to the operating system with a condition
    }                                       // code 8 if it fails.

    return ch;                              // Return the character we read.
}

#endif                                      // End of UNIX/LINUX only.

I will continue to add tips and techniques as time permits.

Please direct any inquiries or problems regarding this web to webmaster@marcsweb.com


Page design, composition and HTML by Marc Niegowski
Copyright © 1998-2012, Marc Niegowski - Connectivity, Inc., All Rights Reserved
23 W. Fourth Street • Media • Pennsylvania • 19063-2805 • USA
Phone: 610-566-0227 • Fax: 610-566-0641 • Email: Marc@Tech-Center.com

Revision Date: Wednesday, November 15, 2006 10:02:03 AM