delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/03/06/02:38:04

From: Matthew Mastracci <mmastrac AT acs DOT ucalgary DOT ca>
Newsgroups: comp.os.msdos.djgpp
Subject: Flushing i/o stream?
Date: Wed, 5 Mar 1997 23:02:00 -0700
Organization: The University of Calgary
Lines: 267
Message-ID: <Pine.A41.3.94.970305225248.60786A-100000@acs2.acs.ucalgary.ca>
NNTP-Posting-Host: mmastrac AT acs2 DOT acs DOT ucalgary DOT ca
Mime-Version: 1.0
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

     How can I flush an error from the console input stream (cin)?  How
can I test if there is an error in the input stream?  I haven't been able
to find the answer in the faq, with info or even examining "iostream.h". 
I know it would be possible to overload the extraction operator, but this
sort of program is designed for people with very little time per problem. 

Here's some sample code, try entering ,0, for the coordinates instead of
1,1 or something bad like that.  You'll get screenfuls of invalid runs as 
the program continuously reads the error from the stream without knowing 
it.  Hit Ctrl-Break to kill the sucker.

Compile with:

gcc fires.cc -o fires.exe -v -Wall -liostream 
(or with your favourite options)

// 1996 Calgary Regional Programming Competition Solution
// Section A, Question 1
// Program: Putting out Fires (fires.cc)
// Author: Matthew Mastracci
// Team: n/a
// Date: 3/4/97
// Compiled without warnings using gcc v2.7.2.1
/*
   Description: This program takes two coordinates on a 10x10 map and computes
   the total number of routes that can be taken, starting at the first point 
   and only moving in the two directions that get closer to the second point.
   Because the total number of movements to get from one point to another will
   be constant for each route and there are only two types of movement to 
   chose from, the problem resembles a binary probability one and we can use
   a portion of Pascal's triangle to calculate the distributions.  
*/

#include <iostream.h>
#include <iomanip.h>
#include <conio.h>

/*** Generic template start ***/

// Outputs team information
void OutputTeam()
{
  cout << "Team: n/a" << endl;
  cout << "Team members: Matthew Mastracci" << endl;
  cout << endl;  
  cout << "Description: This program takes two coordinates on a 10x10 map and computes" << endl;
  cout << "the total number of routes that can be taken, starting at the first point" << endl;
  cout << "and only moving in the two directions that get closer to the second point." << endl;
  cout << "Because the total number of movements to get from one point to another will" << endl;
  cout << "be constant for each route and there are only two types of movement to" << endl;
  cout << "chose from, the problem resembles a binary probability one and we can use" << endl;
  cout << "a portion of Pascal's triangle to calculate the distributions." << endl;
  cout << endl;
  cout << "Hit any key to continue... ";
  // Flush output stream.  Some versions of C++ use independant streams for
  // iostream and conio/stdio functions.
  cout << flush;  

  // Wait for a key
  getch();  

  // Keeps things clean
  cout << endl << endl;

  return;
}
                    
/*** Generic template end ***/

// The map of the city, defined as 11x11 so we can use values from 1 to 10 for
// the coordinates
int CityMap[11][11];

// The location of the station and the fire
int StationX, StationY, FireX, FireY;

// Two values used to mark the station and the fire on the map
const int STATION = -1;
const int FIRE = -2;

// Fills the city map and returns the number of routes to the fire
int FillCityMap(void);

// Prints the calculated city map
void PrintCityMap(void);

// Calculates the number of routes to a point, given the movement directions
int CalculateRoutes(int X, int Y, int XInc, int YInc);

// Returns the sign of X as 1 or -1, or zero if X is zero
int Sign(int X);

int FillCityMap(void)
{
  // Some counters
  int i, j;
  // Our increment for stepping through the map (-1, 0 or 1)
  int XInc, YInc;
  // The number of routes we calculate
  int Routes;

  // Fill the map with zeros
  for (i = 1; i <= 10; i++)
    for (j = 1; j <= 10; j++)
      CityMap[i][j] = 0;
  
  // If FireX > StationX, XInc = 1
  // If FireX < StationX, XInc = -1
  // If FireX = StationX, XInc = 0
  XInc = Sign(FireX - StationX);
  // Same for YInc
  YInc = Sign(FireY - StationY);

  // Could do this in a for loop, but it's a little more readable like this.

  // Iterate over the area encompassed by the station and the fire, 
  // calculating the number of routes to each point as we go.
  i = StationX;
  do {
    j = StationY;
    do {
      CityMap[i][j] = CalculateRoutes(i, j, XInc, YInc);
      j += YInc;
    } while (j != FireY + YInc);
    i += XInc;
  } while (i != FireX + XInc);
  
  // Put the station marker on the map
  CityMap[StationX][StationY] = STATION;

  // Take the number of routes to the fire straight off the map
  Routes = CityMap[FireX][FireY];

  // Replace it with the marker
  CityMap[FireX][FireY] = FIRE;
  
  // Return the number of routes to the fire
  return Routes;
}

void PrintCityMap(void)
{
  // Ensure everything aligns left
  cout.setf(ios::left);
  
  // Loop through the 10x10 map
  for (int i = 1; i <= 10; i++) {
    for (int j = 1; j <= 10; j++) {
      // Nothing here at all?
      if (CityMap[j][i] == 0) 
        cout << "-  ";
      // Station marker?
      else if (CityMap[j][i] == STATION)
        cout << "S  ";
      // Fire marker?
      else if (CityMap[j][i] == FIRE)
        cout << "F  ";
      // None of the above, it's on the route
      else cout << setw(3) << CityMap[j][i];
    }
    cout << endl;
  }
  
  // Done printing the map
  return;
}

int CalculateRoutes(int X, int Y, int XInc, int YInc)
{
  int Routes; 
  
  // If we're on the same horizontal or vertical as the fire, there is only
  // one route
  if ((X == StationX) || (Y == StationY))
    Routes = 1;
  // Otherwise, add the two spaces in the opposite direction of where we're 
  // headed
  else Routes = CityMap[X - XInc][Y] + CityMap[X][Y - YInc];
  
  // Return the number of routes to this space
  return Routes;
}

int Sign(int X)
{
  int Signum;
  
  // Check the sign of X
  if (X > 0)  
    Signum = 1;
  if (X < 0) 
    Signum = -1;
  if (X == 0) 
    Signum = 0;
  
  // Return it
  return Signum;
}

// Main program starts here
int main(void)
{
  // Check if the user wants to try again
  char Repeat;
  // Dummy variable to hold the comma in the coordinates
  char CommaHolder;
  // The number of routes to the fire
  int Routes;
  // Valid input flag
  int Valid;

  // Output team information
  OutputTeam();

  // Main loop
  do {
    
    // Input loop
    do {
      // Validate input
      Valid = 1;
      
      // Input station and fire locations
      cout << "Enter station location (x,y): ";        
      cin >> StationX >> CommaHolder >> StationY;
      cout << "Enter fire location (x,y): ";        
      cin >> FireX >> CommaHolder >> FireY;
      cout << endl;
      
      // Check if input was invalid
      if ((StationX < 1) || (StationX > 10) || (StationY < 1) || 
       (StationY > 10) || (FireX < 1) || (FireX > 10) || (FireY < 1) || 
       (FireY > 10) || ((StationX == FireX) && (StationY == FireY))) {
        Valid = 0;
        cout << "Invalid input!" << endl;
      }
    } while (!Valid);

    // Get the number of routes
    Routes = FillCityMap();

    // Print the map we just filled
    PrintCityMap();
    cout << endl;
    
    // Output the number of routes to the fire
    cout << "The fire can be reached with " << Routes << " different routes." << endl << endl;

    // Check for repeat
    cout << "Again (Y/n)? ";
    cin >> Repeat;
    cout << endl;

  } while ((Repeat != 'N') && (Repeat != 'n'));
  // End of main loop

  // Back to the OS
  return 0;
}


/\/\att /\/\astracci                  mmastrac AT acs DOT ucalgary DOT ca

GCS/GE    d- s+:+ a--- C++++ UA P+ L E-- W+ N++ o K+ w+ O M- V 
          PS++ PE++ Y+ PGP t+++ 5+++ X++ R++ tv+ b+++ DI++++ I 
          G++ e h r* z?

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019