Solved

function for main

Posted on 2004-09-20
7
482 Views
Last Modified: 2012-08-14
I need to test the input from file routine.  How can I add an option from main() to either initialize randomly or input from file?

Here is the code that needs the modification:

# Makefile:
#        It uses the C++ Compiler with all warnings and
#        full debugging; will create a single executable called 'main'
# ---------------------------------------------------------------
# Note: If you want to use the g++ compiler on pegasus or helios
# uncomment the g++ lines and comment the Digital Unix lines

# the Digital Unix C++ compiler needs these lines:
CPP = cxx
CFLAGS = -L/usr/lib/cmplrs/cxx -DPOSIX_4D9 -w0 -gall

# the g++ compiler on pegasus and helios needs these lines:
# CPP = g++
# CFLAGS = -DPOSIX_4D9 -w -g

# link in the math library
LFLAGS = -lm

RM = rm -f
# ----------------------------------------------------------------
# Explanation of macros:
#     $< is any dependent file which is out of file1
#     $* is the target's basename (without extension)
#     $@ is the target's fullname
#
# add suffix .cpp since it is not a default with make util
.SUFFIXES:      .cpp .o
#
# implicit rule for compilation only:
.cpp.o:
      ${CPP} -c ${CFLAGS} $<

OFILES=            main.o life.o util.o

HFILES=            life.h  util.h

# dependencies
#
default:      main      
#
main:           $(OFILES)
            ${CPP} ${CFLAGS} ${LFLAGS} $(OFILES) -o $@

main.o:            main.cpp life.h util.h
life.o:            life.cpp life.h util.h
util.o:            util.cpp util.h

#
clean:
      ${RM} *.o
      ${RM} core
#
veryclean:      clean
      ${RM}  main  
      
/* filename: util.h
   programer: Enrique De Los Santos
   project: Conways Game of Life
   purpose: header file for VT 100 screen functions and usefule I/O utils
   Note: a VT 100 screen is 24 rows and 80 columns in standard mode*/

#ifndef UTIL_H  
#define UTIL_H

/* type bool and false & true are already defined in dUNIX C++
typedef int bool;
const bool false = 0;
const bool true = 1; */

// this is also in /usr/unclude/stdef.h which is used in >stdlib.h>

#define NULL 0L

// useful definitions for flag and screen operations

#define STDSCREEN 80        
#define DOWN 0                        
#define UP   1
#define END   0
#define START 1
#define FAIL    0
#define SUCCESS 1
#define MISS -1
#define HIT   1

// usefule error codes

enum Error_code { success, fail, range_error, underflow, overflow, fatal,
                  not_present, duplicate_error, entry_inserted, entry_found,
                  internal_error };

// screen functions

void clearScreen ();                        // clears all rows of screen                  
void clearTop();                        // clears top row 0 only                        
void clearBelowTop();                         // clears row 1 down on a VT 100 screen                
void goTop();                           // moves cursor to top row 0                          
void topLine(const char * text = " "  );      // display text at row 0           
void bottomLine (char * text = " ");              // displays text at row 23, column 10

// I/O functions
 
void hitAnyKey ();                        // "Hit any key to continue..." prompt                    
void flushInput ();                        // reads 80 chars from stdin                    
void Warning(char *);                        // writes message to stderr                  
void Error(char *);                         // writes message to stderr and exits                    
bool promptYesNo(char * prompt="");             // prompts user to enter yes, no    
void EatWhiteSpace(void);                  // discards white space input              
bool user_says_yes();                        // function prototype

#endif

// end of util.h

/* filename: util.cpp
   programer: Enrique De Los Santos
   project: Conways Game of Life, hw1
   purpose: I/O and VT 100 screen manipulation utility functions*/
   
#include <iostream>
#include <ctype.h>
#include <stdlib.h>
#include "util.h"

/* SCREEN HANDLING FUNCTIONS -
   vertrical position goes from 0-23
   horizontal position goes from 0-79*/

// clear everything on screen
void clearScreen (void)
{
  cout << "\033[2J";          
  cout << "\033[;f";        
}

// goto top-left corner; clear to end of line
void clearTop()

  {cout << "\033[0;0f" << "\033[0K";}

// clear everything except top row
void clearBelowTop()

  {cout << "\033[1;0f" << "\033[1B" << "\033[J";}

// to the top-left corner
void goTop ()

  {cout << "\033[0;0f";}

// goto top-left corner; clear to end of line; print string
void topLine(const char str[])
 
  {cout << "\033[0;0f" << "\033[0K" << str;}

// goto line 23; clear line 23; write text
void bottomLine (char * str)
 
  {cout << "\033[23;0Hf" << "\033[2K" << str;}

// I/O functions

// precondition: the input buffer is empty
void hitAnyKey ()
{
   char ch;
   bottomLine ("Hit any key to continue...");
   cin.get(ch);
   clearScreen();
}

// flush input buffer
void flushInput ()
{
   char buff[81];
   if (cin)
      cin.getline(buff,80);      // flush the input buffer of 80 characters    
}

void Warning(char *message)
{
   cerr << message;
}

void Error(char *message)
{
   cerr << message;
   exit(1);
}

// discard leading white space
void EatWhiteSpace()
{
    char ch;
    do {
      cin.get(ch);
    }
    while(isspace(ch));

    if(ch != EOF)
      cin.putback(ch);
}

bool promptYesNo(char * c)
{
   char ch;
   cout << c << " [y|n]?";
   do {
      cin.get(ch);  
      tolower(ch);
      } while (ch != 'y' && ch != 'n');
   return (ch == 'y');
}

bool user_says_yes()
{
   int c;
   bool initial_response = true;

   do {  
      if (initial_response)
         cout << " (y,n)? " << flush;

      else
         cout << "Respond with either y or n: " << flush;

      do { //  Ignore white space.
         c = cin.get();
      } while (c == '\n' || c ==' ' || c == '\t');
      initial_response = false;
   } while (c != 'y' && c != 'Y' && c != 'n' && c != 'N');
   return (c == 'y' || c == 'Y');
}

// end of util.cpp

/* filename: life.h
   prgrammer: Enrique De Los Santos
   project: Conways Game of Life, hw1*/

#ifndef LIFE_H
#define LIFE_H

const int maxrow = 20, maxcol = 60;    //  grid dimensions

class Life {

public:
   void instructions();
   void initialize(int);
   void func1 (int &);
   //void num_alive(int);
   void print();
   void update();
   bool row_ok(int r);
   bool col_ok(int c);

private:

   int grid[maxrow + 2][maxcol + 2];  //  allows for two extra rows and columns
   int neighbor_count(int row, int col);
   int num_alive ;
   //int x;

};

#endif

// end of life.h

/* Filename: life.cpp
   Programmer: Enrique De Los Santos (Del)
   Project: Conways Game of Life, hw1*/

//purpose: definitions for Life class

#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>

#include <time.h>

using namespace std;

#include "util.h"
#include "life.h"

// 1 = random (default)  2 = file 3 = manual  
void Life::initialize(int choice)
{
   extern int x;
   x  = 5;
   int make_alive;  
   int row, col;
   char filename[50];
   int num_alive = 0;

   for (row = 0; row <= maxrow+1; row++)
       for (col = 0; col <= maxcol+1; col++)
           grid[row][col] = 0;


   // initialize randomly
   if ( choice == 1 )
   {
      // seed the random number generator
      srand((time(NULL)));
   
      // randomly make cells alive  
      for (row = 0; row <= maxrow+1; row++)
          for (col = 0; col <= maxcol+1; col++) {
              make_alive = rand() % 6;
              if ( make_alive == 1 ) {
                 grid[row][col] = make_alive;
                 num_alive ++;
            }
         }
 
   }
   else

   // initialize from file
   if ( choice == 2 )
   {

      cout << "Enter Filename: ";
      cin >> filename;
 
       // open input file
       ifstream infile( filename, ios::in );
       if( !infile ) {
          cerr << "File could not be opened\n";
          exit( 1 );
       }
       /* error checking for EOF and out of bounds  
           you could also use !infile.eof()      */

       while (infile) {
             infile >> row;

           // check to see if you are at eof
           if (!infile.fail())      
              infile >> col;

           // this will prevent you from processing EOF  
           if (!infile.fail() && row_ok(row) && col_ok(col)){
              grid[row][col] = 1;
              num_alive ++;
           }
        }
        infile.close();
     }  
    else
 

    // initialize  manually  
    if ( choice == 3 )
    {
       cout << "\nList coordinate pair for living cells (e.g. 4 5)"
            << " or -1 -1 to end:" << endl;
       cin >> row >> col;

       while (row != -1 || col != -1) {
          if (row >= 1 && row <= maxrow)
             if (col >= 1 && col <= maxcol)
                grid[row][col] = 1;
             else
                cout << "Column " << col << " is out of range." << endl;
          else
             cout << "Row " << row << " is out of range." << endl;
           cin >> row >> col;
           num_alive++;
       }  // user has entered -1 -1
     }    // end code to get input from user

}

int Life::neighbor_count(int row, int col)
/*
Pre:  The Life object contains a configuration, and the coordinates
      row and col define a cell inside its hedge.

Post: The number of living neighbors of the specified cell is returned.*/
{
   int i, j;
   int count = 0;
   for (i = row - 1; i <= row + 1; i++)
       for (j = col - 1; j <= col + 1; j++)
           count += grid[i][j];  //  Increase the count if neighbor is alive.
   count -= grid[row][col];      //  Reduce count, since cell is not its own neighbor.
   return count;
}

void Life::update()
/*
Pre:  The Life object contains a configuration.

Post: The Life object contains the next generation of configuration.*/
{
   int row, col;
   int new_grid[maxrow + 2][maxcol + 2];

   for (row = 1; row <= maxrow; row++)
      for (col = 1; col <= maxcol; col++)
         switch (neighbor_count(row, col)) {
         case 2:
            new_grid[row][col] = grid[row][col];    //  Status stays the same.
            break;
         case 3:
            new_grid[row][col] = 1;                 //  Cell is now alive.
            break;
         default:
            new_grid[row][col] = 0;                 //  Cell is now dead.
         }

   int num_alive = 0;

   for (row = 1; row <= maxrow; row++)
      for (col = 1; col <= maxcol; col++) {
         grid[row][col] = new_grid[row][col];
         // count the number of living cells
         if ( grid[row][col] == 1 )
            num_alive++;
      }
}

void Life::print()
/*
Pre:  The Life object contains a configuration.

Post: The configuration is written for the user.*/
{
   int row, col;
   clearScreen();
   cout << "The current " << maxrow << "x" << maxcol << 
            " grid contains " << num_alive << " cells: "
        << endl;

   for (row = 1; row <= maxrow; row++) {
       for (col = 1; col <= maxcol; col++)
           if (grid[row][col] == 1) cout << '*';
           else cout << ' ';
       cout << endl;
   }
   cout << endl;
}

void Life::instructions()
/*
Pre:  None.

Post: Instructions for using the Life program have been printed.*/
{
   clearScreen();
   cout << "Welcome to Conway's Game of Life." << endl;
   cout << "The grid contains "
        << maxrow << " by " << maxcol;
   cout << " cells." << endl;
   cout << "The occupied cells change from generation to generation" << endl;
   cout << "according to the number of neighboring cells which are alive."
        << endl << endl;
}

bool Life::row_ok(int r)
// performs row range checking on r
{
  return r >= 1 && r <= maxrow;
}

bool Life::col_ok(int c)
// performs column range checking on c
{
  return c >= 1 && c <= maxcol;
}

extern int x = 222;     /* initializes the variable referred to in file1*/

void func1 (int & arg1)  /*  func1 has external linkage, arg1 has no linkage
                             but points back to the variable in main */
{

  arg1 = 200;
  x = 333;
  cout << "\nFUNC1:\n";
  cout << "x: " << x << endl;
  //cout << "y: " << y << endl;
  cout << "arg1: " << arg1 << endl;
}


// end of life.cpp

// main.cpp
/* filename: main.cpp
   programmer: Enrique De Los Santos
   project: Conways Game of Life, hw1
   purpose: driver*/

#include<iostream>

//using namespace std;

#include "util.h"
#include "life.h"

extern int x;     /* identifiers outside any function default to external */
void func1 (int &);   /* prototypes have no linkage  */

int main()  //  Program to play Conway's game of Life.
/*
Pre:  The user supplies an initial configuration of living cells.

Post: The program prints a sequence of pictures showing the changes in
      the configuration of living cells according to the rules for
      the game of Life.
Uses: The class Life and its methods initialize(), print(), and update().
      The functions  instructions(),  user_says_yes().*/

{
   Life configuration;
   void initialize();
   void initialize(int);
   configuration.instructions();
   //configuration.initialize(1); // initialize randomly
   configuration.print();
   cout << "Continue viewing new generations? " << endl;
   while (user_says_yes()) {
      configuration.update();
      configuration.print();
      cout << "Continue viewing new generations? " << endl;
      cout << "x: " << x << endl;

      func1(x);
      cout << "x: " << x << endl;


   }
}

// end of main.cpp

output:







      *


          *


                                                                       *   *   *
          ** *
                       *             *         *

                                            *  *             *

                                                               Continue viewing
new generations?
                  (y,n)?











0
Comment
Question by:edelossantos
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
  • 2
7 Comments
 
LVL 86

Assisted Solution

by:jkr
jkr earned 350 total points
ID: 12104316
You could use

int main(int argc, char** argv)  //  Program to play Conway's game of Life.
/*
Pre:  The user supplies an initial configuration of living cells.

Post: The program prints a sequence of pictures showing the changes in
     the configuration of living cells according to the rules for
     the game of Life.
Uses: The class Life and its methods initialize(), print(), and update().
     The functions  instructions(),  user_says_yes().*/

{
  Life configuration;
//...

   if ( argc != 1) { // was an additional argument given?

      if ( !strcmp(*(argc+1), "-rand")) configuration.initialize(1); // initialize randomly if "-rand" was specified
   } else  configuration.instructions();
 
//...

}
0
 

Author Comment

by:edelossantos
ID: 12104417
jkr, I went ahead and made the changes to main() and came out with this error.  ???


[edeloss2@pegasus hw1]$ make
cxx -c -L/usr/lib/cmplrs/cxx -DPOSIX_4D9 -w0 -gall  main.cpp
cxx: Error: main.cpp, line 33: operand of "*" must be a pointer
      if ( !strcmp(*(argc+1), "-rand")) configuration.initialize(1); // init
ze randomly if "-rand" was specified
--------------------^
cxx: Info: 1 error detected in the compilation of "main.cpp".
make: *** [main.o] Error 1
0
 

Author Comment

by:edelossantos
ID: 12104432
// main.cpp
/* filename: main.cpp
   programmer: Enrique De Los Santos
   project: Conways Game of Life, hw1
   purpose: driver*/

#include<iostream>

//using namespace std;

#include "util.h"
#include "life.h"

extern int x;     /* identifiers outside any function default to external */
void func1 (int &);   /* prototypes have no linkage  */

int main(int argc, char** argv)  //  Program to play Conway's game of Life.
/*
Pre:  The user supplies an initial configuration of living cells.

Post: The program prints a sequence of pictures showing the changes in
      the configuration of living cells according to the rules for
      the game of Life.
Uses: The class Life and its methods initialize(), print(), and update().
      The functions  instructions(),  user_says_yes().*/

{
   Life configuration;
   void initialize();
   void initialize(int);
   if ( argc != 1) { // was an additional argument given?

      if ( !strcmp(*(argc+1), "-rand")) configuration.initialize(1); // initialize randomly if "-rand" was specified
   } else  configuration.instructions();

   configuration.instructions();
   //configuration.initialize(1); // initialize randomly
   configuration.print();
   cout << "Continue viewing new generations? " << endl;
   while (user_says_yes()) {
      configuration.update();
      configuration.print();
      cout << "Continue viewing new generations? " << endl;
      cout << "x: " << x << endl;

      func1(x);
      cout << "x: " << x << endl;



   }
}

// end of main.cpp




0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 14

Assisted Solution

by:wayside
wayside earned 150 total points
ID: 12104436
> How can I add an option from main() to either initialize randomly or input from file?

You could either have your program accept command line arguments, or have the main function prompt for what to do.

To get a command line argument:

change

int main() to

int main (int argc, char *argv[])


Then do something like

int which = atoi(argv[1]);
configuration.initialize(which);

and run your program as

life.exe 1

or

line.exe 2

You can of course make the command line option be textual and do strcmps:

if (strcmp(argv[1], "random") == 0)
   which = 0;

and run it as

life.exe random

To have it prompt, you already do this sort of thing in your program, just output a text string and collect the input before the initialize call.
0
 

Author Comment

by:edelossantos
ID: 12104450
I don't think I gave an additional argument for

if ( argc != 1) { // was an additional argument given?

      if ( !strcmp(*(argc+1), "-rand")) configuration.initialize(1); // initialize randomly if "-rand" was specified
   } else  configuration.instructions();
0
 
LVL 14

Expert Comment

by:wayside
ID: 12104453
I've got to learn to type faster... sigh.
0
 
LVL 86

Accepted Solution

by:
jkr earned 350 total points
ID: 12104460
Sorrry, that line should have been

      if ( !strcmp(*(argv+1), "-rand")) configuration.initialize(1); // init

'argv' instead of 'argc' - a typo :-(
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
ASP.net build a IF/Then Walkthrough Guide 1 279
Would like to move button in a function 3 85
Create a path if not exists 7 108
C++ :Change value from  DisableCMD registry 4 69
Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

733 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question