sábado, 30 de noviembre de 2013

Game of Life C++ Program Example

#include <iostream>
#include <cstdlib>
using namespace std;

const int xRow=42+2;
const int xCol=77+2;
int Xrow=xRow;
int Xcol=xCol;
int Xnum;

void dspCont();
void dspMenu();
void dspGMenu();
void subMenu();
void runGame(int num[][xCol], int &xrow, int &xcol, char fld);
void scrPaint(int num[][xCol],char fld);
void clcNeigh(int num[][xCol],int &xrow, int &xcol, char fld);
void chkTest(char fld[]);

int main()
{
  char menu1=' ';

  while(menu1 != 'Q' || menu1 != 'q' )

    {
      dspMenu();

      cout << "Q. Quit" << endl;
      cout << ' ' << endl;
      cin >> menu1 ;

      switch(menu1)
{
case '1':

 dspMenu();
 subMenu();

 break;

case '2':
 int Erow, Ecol;

 dspMenu();

 cout << "** Row/Col Limits : " << xRow-2 << "/" <<
   xCol-2 << " **\n " << endl;
 cout << "Enter Row & Col " ;
 cin >> Erow >> Ecol;

 if (Erow > 0 && Erow < (xRow+1)-2 )
   if ( Ecol > 0 && Ecol < (xCol+1)-2 )
     {
Xcol = Ecol+2;
Xrow = Erow+2;
     }

 break;

case '3':
 cout << '\n' << endl;
 cout << " **The Game of Life** \n";
 cout << "The mathematician John Horton Conway invented the 'Game of Life'."
      << "Through not a 'game' in any traditional sense, it provides"
      << "interesting behavior that is specified with only a few rules";

 cout << "The program follows the rule of LIFE to show the continuing behavior of the configuration." << endl;
 cout << "Generations mark the passing of time."
      << "Each generation brings births and deaths to the LIFE continuity." << endl;
 cout << "The births and deaths follow the following set of rules:" << endl;

 cout << "     1. We define each cell to have 8 neighbord cells.\n";
 cout << "     2. If an occupied cell has zero or one neighbors, it dies of loneliness.\n";
 cout << "     3. If an empty cell has exactly 3 ocuppied neighbor cells, there is a birth"
      << " of a new cell to replace the empty cell.\n";
 cout << "     4. Births and deaths are instantaneous and occur at the changes of generations."
      << " A cell dying for whatever reason may help cause birth, but a"
      << " newborn cell cannot resurrect a cell that is dying, nor will a"
      << " cell's death prevent the death of another, say, by reducing the local population\n";

 dspCont();

case 'Q':
 break;
}

      if(menu1 == 'Q' || menu1 == 'q' )

break;
    }

  cout << "\n" << endl;
  cout << "ALL DONE ! \n \n " << endl;

  return 0;
}
void subMenu()
{
  char menu2=' ';
  int cnt[xRow][xCol];
  int pRow=1;
  int pCol=1;

  scrPaint(cnt,'C');
  bool mnuflg=false;

  while(menu2 != 'Q' || menu2 != 'q' )
    {
      if(menu2=='d' || menu2=='D')
{
 mnuflg=false;
}
      if(mnuflg)
{
 cout << "Position : ( " << pRow << "-" << pCol << " )" << endl;
 cout << "Press 1=Fill 2=Blank -D-one " << endl;
}
      else
{
 cout<< "" << endl;
 cout  << "Press -F-ill -C-lear -S-elect -R-un -Q-uit " << endl;
}
   
   
      cout  << "" << endl;
   
      cin >> menu2 ;

      switch(menu2)
{
case 'D': case 'd':
 scrPaint(cnt, 'P');
 break;

case 'S': case 's': case '1': case '2':
 mnuflg=true;
 runGame(cnt,pRow,pCol,menu2);
 scrPaint(cnt, 'P');
 break;

case 'R': case 'r':
 if(!mnuflg)
   {
     pRow=1,pCol=1;
     runGame(cnt,pRow,pCol,menu2);
     scrPaint(cnt, 'P');
   }
 break;

case 'C': case 'c':
 if(!mnuflg)
   {
     scrPaint(cnt, 'C');
     pRow=1,pCol=1;
   }
 break;

case 'F': case 'f':
 if(!mnuflg)
   {
     scrPaint(cnt, 'F');
     pRow=1,pCol=1;
   }
 break;

case 'Q':
 break;
}
      if(menu2 == 'Q' || menu2 == 'q' )
break;
    }

}

void dspMenu()
{

  cout << ' ' << endl;
  cout << "Game of Life\n " << endl;
  cout << "1. Run Game ( calculate at -" << Xrow-2 << "- Rows and -" << Xcol-
    2 << "- Columns " << endl;
  cout << "2. Change the Game Dimensions of rows / cols " << endl;
  cout << "3. Read Me" << endl;
  cout << " " << endl;
}

void dspGMenu()
{

  cout << " ** Game of Life ** " << endl;
}

void dspCont()
{
  char chcc;
  cout << " \n Press C and then <RET> to Continue " ;
  cin >> chcc;
}

void scrPaint(int num[][xCol], char fld)
{
  dspGMenu();
  char line[80];

  for(int i=0;i<Xrow;i++)
    {
      for(int ii=0;ii<Xcol;ii++)
{
 if(fld=='F' || fld=='C')
   {
     if(i!= 0 && i!=Xrow-1 && ii!=0 && ii!=Xcol-1)
clcNeigh(num,i,ii,fld);
     else
num[i][ii]='+';}
 line[ii]=num[i][ii];
 cout << line[ii];
}
      cout << '\n';
    }
}

void runGame(int num[][xCol],int &xrow, int &xcol, char fld)
{
  bool flgx=false;

  if(xrow<Xrow && xcol<Xcol)
    {
      for(int i=0;i<Xrow;i++)
{
 for(int ii=0;ii<Xcol;ii++)
   {
     if(i!= 0 && i!=Xrow-1 && ii!=0 && ii!=Xcol-1)
{
 switch(fld)
   {
   case 'S': case 's': case '1': case '2':
     if(ii==xcol && i==xrow && !flgx)
{
 clcNeigh(num,xrow,xcol,fld);
 flgx=true;
}
     break;

   case 'R': case 'r':
     clcNeigh(num,i,ii,fld);
     break;
   }
}
   }
}
      switch(fld)
{
case 'S': case 's': case '1': case '2':
 xcol=xcol+1;
 if(xcol>Xcol-2)
   {
     xcol=1;
     if(xrow<Xrow-2)
{
 xrow=xrow+1;
}
     else
xrow=1;
   }
}
    }
}

void clcNeigh(int num[][xCol],int &xrow, int &xcol, char fld)
{
  switch(fld)
    {
    case 'C': case 'c': case '2':
      num[xrow][xcol]=' ';
      break;

    case 'F': case 'f': case '1':
      num[xrow][xcol]='*';
break;

    case 'R': case 'r':
      char srchArray[8];
      srchArray[0]=num[xrow-1][xcol-1];
      srchArray[1]=num[xrow][xcol-1];
      srchArray[2]=num[xrow+1][xcol-1];
      srchArray[3]=num[xrow-1][xcol];
      srchArray[4]=num[xrow+1][xcol];
      srchArray[5]=num[xrow-1][xcol+1];
      srchArray[6]=num[xrow][xcol+1];
      srchArray[7]=num[xrow+1][xcol+1];

      int xHit=0;

      for(int x=0;x<8;x++)
{
 if(srchArray[x]=='*')
   {
     xHit=xHit+1;
   }
}

      switch(xHit)
{
case 3:
 num[xrow][xcol]='*';
 break;

case 2:
 // Nothing
 break;

default:
 num[xrow][xcol]=' ';
 break;
}
      break;
    }
}

void chkTest(char fld[])
{
  char chkTest;
  cout << fld << endl;
  cin >> chkTest;
}

Dynamic Arrays

A dynamic array is an array whose size is determined when the program is running, not when you write the program.

Array variables are actually pointer variables that point to the first indexed variable. For example:

int a[10];
typedef int* IntPtr;
IntPtr p;

Variables a and p are the same kind of variable

  • Since a is a pointer variable that points to a[0], 
  • p = a; 
  • causes p to point to the same location as a
  • Pointer variable p can be used as if it were an array variable.
  • Variable a can be used as a pointer variable except the pointer value in a cannot be changed.


Normal arrays require that the programmer determine the size of the array when the program is written. Dynamic arrays can be created with just the right size while the program is running.

Dynamic arrays are created using the new operator.  For example, to create an array of 10 elements of:



type double:
typedef double* DoublePtr;
DoublePtr d;
d = new double[10];

d can now be used as if it were an ordinary array!

When finished with the array, it should be deleted to return memory to the freestore.  For example:

delete [] d;

  • The brackets tell C++ a dynamic array is being deleted so it must check the size to know how many indexed variables to remove.

  • Pointer Arithmetic:

    Arithmetic can be performed on the addresses contained in pointers.
    You can add and subtract with pointers:
    • The ++ and - - operators can be used
    • Two pointers of the same type can be subtracted to obtain the number of indexed variables between.
    • This code shows one way to use pointer arithmetic:
                             for (int i = 0; i < array_size; i++)
                                   cout << *(d + i) << " " ;      // same as cout << d[i] << " " ;

    Multidimensional Dynamic Arrays:

    To create a 3x4 multidimensional dynamic array
    • View multidimensional arrays as arrays of arrays
    • First create a one-dimensional dynamic array
      • Start with a new definition:
        • typedef int* IntArrayPtr;
      • Now create a dynamic array of pointers named m:
        • IntArrayPtr *m = new IntArrayPtr[3];
    • For each pointer in m, create a dynamic array of int's
        • for (int i = 0; i<3; i++)
        • m[i] = new int[4];
    • The dynamic array created on the previous slide 
    • could be visualized like this:


    Deleting Multidimensional Arrays:

    To delete a multidimensional dynamic array, each call to new that created an array must have a
    corresponding call to delete[ ].  For example:

    for ( i = 0; i < 3; i++)
    delete [ ] m[i];           //delete the arrays of 4 int's
    delete [ ] m;              // delete the array of IntArrayPtr's





    Pointers


    About pointers...
    • A pointer is the memory address of a variable. 
    • Memory addresses can be used as names for variables.  
      • If a variable is stored in three memory locations, the address of the first can be used as a name for the variable.
      • When a variable is used as a call-by-reference argument, its address is passed.
    • An address used to tell where a variable is stored in memory is a pointer.
    Declaring Pointers

    Pointer variables must be declared to have a pointer type.  For example,to declare a pointer variable p that can "point" to a variable of type double:

    double *p;
    • The asterisks identifies p as a pointer variable


    To declare multiple pointers in a statement, use the asterisk before each pointer variable.  For example:

    int *p1, *p2, v1, v2;

    Operators with Pointers:

    The & operator can be used to determine the address of a variable which can be assigned to a pointer variable.  For example:  

    p1 = &v1;

    p1 is now a pointer to v1
    v1 can be called v1 or "the variable pointed to by p1"

    C++ uses the * operator in yet another way with pointers.

    A Pointer example:

    v1 = 0;
    p1 = &v1;
    *p1 = 42;
    cout << v1 << endl;
    cout << *p1 << endl;

    Output:
    42
    42

    The assignment operator = is used to assign the value of one pointer to another.  For example, if p1 still points to v1 then:

    p2 = p1;

    causes *p2, *p1, and v1 all to name the same variable.



    The new Operator

    Using pointers, variables can be manipulated even if there is no identifier for them.  To create a pointer to a new "nameless" variable of type int we use:  p1 = new int; 

    The new variable is referred to as *p1  

    Variables created using the new operator are called dynamic variables.  For example:


    Explanation:


    new and Class Types

    Using operator new with class types calls a constructor as well as allocating memory.  If MyType is a class type, then:
    • MyType *myPtr;                              // creates a pointer to a variable of type MyType
    • myPtr = new MyType;                     // calls the default constructor
    • myPtr = new MyType (32.0, 17);    // calls Mytype(double, int);
    New dynamic variables use memory in the freestore.  If all of the freestore is used, calls to new will
    fail.  When variables are no longer needed, they can be deleted and the memory they used is returned to the freestore.

    When dynamic variables are no longer needed, delete them to return memory to the freestore.  For example:

    delete p;

    The value of p is now undefined and the memory used by the variable that p pointed to is back in the freestore.

    Dangling Pointers:
    • Using delete on a pointer variable destroys the dynamic variable pointed to.
    • If another pointer variable was pointing to the dynamic variable, that variable is also undefined.
    • Undefined pointer variables are called dangling pointers.
      • Dereferencing a dangling pointer (*p) is usually disastrous.
    Automatic Variables:

    Variables declared in a function are created by C++ and destroyed when the function ends.  These are called automatic variables because their creation and destruction is controlled automatically.  The programmer manually controls creation and destruction of pointer variables with operators new and delete

    Variables declared outside any function definition are global variables.

    Type Definitions:

    A name can be assigned to a type definition, then used to declare variables.  The keyword typedef is used to define new type names. 

    Syntax: typedef Known_Type_Definition New_Type_Name;

    To avoid mistakes using pointers, define a pointer type name.  For example:

    typedef int* IntPtr;

    Defines a new type, IntPtr, for pointer variables containing pointers to int variables.

    IntPtr p;    is equivalent to    int *p;

    A second advantage in using typedef to define a pointer type is seen in parameter lists.  For example:

    void sample_function(IntPtr& pointer_var);

    is less confusing than

    void sample_function( int*& pointer_var);



    String and Vectors Part 2

    The Standard string Class

    The string class allows the programmer to treat strings as a basic data type.  The string class is defined in the string library and the names are in the standard namespace.
    To declare a string class we use: #include <string>

    Variables of type string can be assigned with the = operator.  For example:

    string s1, s2, s3;
    ...
    s3 = s2;

    Variable of type string can be concatenated with the + operator.  For example:

    string s1, s2, s3;
    ...
    s3 = s1 + s2;

    If s3 is not large enough to contain s1 + s2, more space is allocated.

    The default string constructor initializes the string to the empty string.  Another string constructor takes a C-string argument.  For example:

    string phrase;               // empty string
    string noun ("ants");     // a string version of "ants"


    Mixing string and C-string

    It is natural to work with strings in the following manner

    string phrase = "I love" + adjective + " " + noun + "!";

    It is not so easy for C++! It must either convert the null-terminated C-strings, such as "I love", to strings, or it must use an overloaded + operator that works with strings and C-strings.

    I/O with Class string

    • The insertion operator << is used to output object of type string.
    • The extraction operator >> can be used to input data for objects of type string.
      • >> skips whitespace and stop on encountering more whitespace
      • >> cannot be used to read a blank character
    getline and Type string


    A getline function exists to read entire lines into a string variable.  This version of getline is not a member of the istream class, it is a non-member function.

    Syntax for using getline with string objects:

    getline(Istream_Object, String_Object);

    Remember: To read one character at a time use cin.get (reads values of type char, not type string).

    Another version of getline...
    • The versions of getline we have seen, stop reading at the end of line marker '\n'
    • getline can stop reading at a character specified in the argument list
      • This code stop reading when a '?' is read:
                                    string line;
                                    cout << "Enter some input:\n";
                                    getline(cin, line, '?');

    getline returns a reference to its first arguments.  For example, this code will read in a line of text into s1 and
    a string of non-whitespace characters into s2:


    These are the declarations of the versions of  getline for string objects we have seen:
    • istream& getline(istream& ins, string& str_var, char delimiter);
    • istream& getline(istream& ins, string& str_var);
    Recall cin >> n skips whitespace to find what it is to read then stops reading when whitespace is found.  cin >> leaves the '\n' character in the input stream.  For example:

    int n;
    string line;
    cin >> n;
    getline(cin, line);

    One member that we can used to read and discard all the characters, including '\n' that remain in a line is the ignore member function.  For example:

    cin.ignore(1000, '\n');
    reads up to 1000 characters or to '\n'

    ignore takes two arguments:  First, the maximum number of characters to discard and second, the character that stops reading and discarding.  

    The string class allows the same operations we used with C-string... and more.
    Characters in a string object can be accessed as if they are in an array.

    The string class member function length returns the number of characters in the string object.  For example:

    int n = string_var.length( );

    at is an alternative to using []'s to access characters in a string.  at checks for valid index value.  Fox example:

    string str("Mary");
    cout << str[6] << endl;
    cout << str.at(6) << endl;
    str[2] = 'X';
    str.at(2) = 'X';

    Other string class functions are found in...


    Comparison of strings:

    Comparison operators work with string objects.
    • Objects are compared using lexicographic order (Alphabetical ordering using the order of symbols in the ASCII character set.).
    • = = returns true if two string objects contain the same characters in the same order.
    • <, >, <=, >= can be used to compare string objects.

    The substr member function is used to locate a substring within a string.

    string Object to C-strings:
     

    Recall the automatic conversion from C-string to string: 

    char a_c_string[] = "C-string";
    string_variable = a_c_string;
     
    strings are not converted to C-strings.  Both of these statements are illegal:

    a_c_string = string_variable;
    strcpy(a_c_string, string_variable);

    The string class member function c_str returns the C-string version of a string object. For Example:

    strcpy(a_c_string, string_variable.c_str( ) );
     
    This line is still illegal:

    a_c_string = string_variable.c_str( ) ;

    Recall that operator = does not work with C-strings

    Vectors

    Vectors are like arrays that can change size as your program runs.  They have a base type.
    To declare an empty vector with base type int:

    vector<int> v;

    <int> identifies vector as a template class.
    You can use any base type in a template class:

    vector<string> v;

    Vectors elements are indexed starting with 0.

  • [ ]'s are used to read or change the value of an item:

  •                     v[i] = 42;
                        cout << v[i];

    [ ]'s cannot be used to initialize a vector element.

    Elements are added to a vector using the member function push_back.  push_back adds an element in the next available position.  For example:

    vector<double> sample;
    sample.push_back(0.0);
    sample.push_back(1.1);
    sample.push_back(2.2);

    The member function size returns the number of elements in a vector.  For example, to print each element of a vector given the previous vector initialization:

    for (int i= 0; i < sample.size( ); i++)
    cout << sample[i] << endl;

    The vector class member function size returns an unsigned int (non-negative integers).

    A vector constructor exists that takes an integer argument and initializes that number of elements.  For example:

    vector<int> v(10);

    initializes the first 10 elements to 0
    v.size( ) would return 10
      • []'s can now be used to assign elements 0 through 9
      • push_back is used to assign elements greater than 9
    The vector constructor with an integer argument initializes elements of number types to zero and they initializes elements of class types using the default constructor for the class.

    To use the vector class, we include the vector library: #include<vector>

    More about vectors...
    • The assignment operator with vectors does an element by element copy of the right hand vector.
    • Attempting to use [ ] to set a value beyond the size of a vector may not generate an error.
    • A vector's capacity is the number of elements allocated in memory.
    • Size is the number of elements initialized.
    • When a vector runs out of space, the capacity is automatically increased.
    • When efficiency is an issue, the member function reserve can increase the capacity of a vector.  For example:
      • v.reserve(32); // at least 32 elements
      • v.reserve(v.size( ) + 10); // at least 10 more
    • resize can be used to shrink a vector.  For example:
      • v.resize(24); //elements beyond 24 are lost

    String and Vectors Part 1

    An Array Type for String:

    C-string...

    • can be used to represent string of characters
    • are stored as arrays of characters
    • use the null character '\0' to end a string
    To declare a C-string variable, declare an array of characters: char s[11]
    Declaring a C-string as char s[11] creates space for only 10 characters.

    A C-string variables does not need a size variable.  The null character immediately follows the last character of the string.

    To declare a C-string variable, use the syntax:

    char Array_name[Maximum_C_String_Size + 1];

    +1 reserves the additional character needed by '\0'


    To initialize a C-string during declaration, the null character '\0' is added for you.

    Another alternative is:

    char short_string[] = "abc";

    but not this:

    char short_string[] = {'a', 'b', 'c'};

    This attempt does not cause the \0 to be inserted in the array.

    Very important: If the null character is lost, the array cannot act like a C-string.



    Assignment of C-string

    A common method to assign a value to a C-string variable is to use strcpy, define in the cstring library.  For example:

    #include <cstring>
    ...
    char a_string[11];
    strcpy (a_string, "Hello");

    Place "Hello" followed by the null character in a_string.

    strcpy can create problems if not used carefully
    • strcpy does not check the declared length of the first argument.  
    • It is possible for strcpy to write characters beyond the declared size of the array.
    A solution for strcpy is using strncpy
    • strncpy uses a third argument representing the maximum number of characters to copy.
    For example:

    char another_string[10];
    strncpy(another_string, a_string_variable, 9);

    This code copies up to 9 characters into another_string, leaving one space for '\0'

    The = = operator does not work as expected with C-string.  The predefined function strcmp is used to compare C-string variables.  For example:

    #include <cstring>
    ...
    if (strcmp(c_string1, c_string2))
         cout << "Strings are not the same.";
    else
         cout << "String are the same.";

    strcmp compares the numeric codes of elements in the C-string a character at a time.  If the two C-sting are the same, strcmp returns 0.
    As soon as the caracters do not match:
    • strcmp returns a negative value if the numeric code in the first parameter is less
    • strcmp returns a positive value if the numeric code in the second parameter is less
    • Non-zero values are interpreted as true

    More C-string Functions:

    Another C-string function is strlen.  This function returns the number of characters in a string.

    int x = strlen (a_string);

    Another one is the strcat function that concatenates two C-strings.
    • The second argument is added to the end of the first
    • The result is placed in the first argument
    For example:

    char string_var[20] = "The rain";
    strcat(string_var, "in Spain");

    Now string_var contains "The rainin Spain"

    The strncat is a safer version of strcat.  A third parameter specifies a limit for the number of character to concatenate.  For example:

    char string_var[20] = "The rain";
    strncat(string_var, "in Spain", 11);




    C-string as Arguments and Parameters:

    C-string variable are arrays.  
    C-string arguments and parameters are used just like arrays.
    • If a function change the value of a C-string parameter, it is best to include a parameter for the declared size of the C-string.
    • If a function does not change the value of a C-string parameter, the null character can detect the end of the string and no size argument is needed.
    C-string output and input:

    C-string can be output with the insertion operator.  For example:

    char news[] = 'C-strings";
    cout << news << "Wow." << endl;

    C-string can be input with the extraction operator.  For example:

    char a[80], b[80];
    cout << "Enter input: " << endl;
    cin >> a >> b;
    cout << a << b << "End of Output";

    could produce:

    Enter input:
    Do be do to you!
    DobeEnd of Output

    Whitespace end reading of data.

    C-string input and output work the same way with file streams.  Just replace cin with the name of an input-file stream and the cout with the name of an output-file stream.

    Reading an Entire Line:

    Predefined member function getline can read an entire line, including spaces.

    getline is a member of all input streams that has two arguments, the first is a C-string variable to receive input and the second is an integer, usually the size of the first argument specifying the maximum number of elements in the first argument getline is allowed to fill.

    Using getline:

    char a[80];
    cout << "Enter input: " << endl;
    cin.getline(a, 80);
    cout << a << "End of Output";

    and could produce:

    Enter some input:
    Do be do to you!
    Do be do to you!End of Output

    getline stops reading when the number of characters, less one, specified in the second argument have been place in the C-string.

    getline syntax:

    cin.getline(String_Var, Max_Characters + 1);

    cin can be replaced by any input stream
    Max_Characters + 1  reserves one element for the null character.

    More about C-string...
    • When doing numeric input, it is useful to read input as a string of characters, then covert the string to a number.
      • "1234" is a string characters
      • 1234 is a number
    • To read an integer as characters
      • Read input as characters into a C-string, removing unwanted characters
      • Use the predefined function atoi to convert the C-string to an int value.
        • atoi ("1234") returns the integer 1234
        • atoi("#123") returns 0 because # is not a digit
    • Larger integers can be converted using the predefined function atol
      • atol returns a value of type long
    • C-string can be converted to type double using the predefined function atof
      • atof returns a value of type double
        • atof("9.99") returns 9.99
        • arof("$9.99") returns 0.0 because the $ is not a digit
    The conversion functions atoi, atol & atof are found in the cstdlib library.



    Arrays Problem Example (from Labs)

    Write a function called delete_repeats that has a partially filled array of
    characters as a formal parameter and that deletes all repeated letters from the array.
    Since a partially filled array requires two arguments, the function will actually have two
    formal parameters: an array parameter and a formal parameter of type int that gives
    the number of array positions used. When a letter is deleted, the remaining letters are
    moved forward to fill in the gap. This will create empty positions at the end of the array
    so that less of the array is used. Since the formal parameter is a partially filled array, a
    second formal parameter of type int will tell how many array positions are filled. This
    second formal parameter will be a call-by-reference parameter and will be changed to
    show how much of the array is used after the repeated letters are deleted.
    For example, consider the following code:
    char a[10];
    a[0] = ’a’;
    a[l] = ’b’;
    a[2] = ’a’;
    a[3] = ’c’;
    int size = 4;
    delete_repeats(a, size);

    After this code is executed, the value of a[0] is ’a’, the value of a[1] is ’b’, the value of
    a[2] is ’c’, and the value of size is 3. (The value of a[3] is no longer of any concern,
    since the partially filled array no longer uses this indexed variable.)
    You may assume that the partially filled array contains only lowercase letters. Embed
    your function in a suitable test program.


    #include<iostream>
    using namespace std;

    void input(char word[], int& size);
    void delete_repeats(char word[], int& size);
     
    int main()
    {
      int size;
      char array[81];
      input(array,size);
      delete_repeats(array,size);
      cout << "resulting array: ";
      for( int i = 0; i < size; i++ ) {
        cout << array[i] << " ";
      }
      cout << endl << endl << endl;
      
      return 0;
    }
    void input(char word[], int& size)
    {
      int counter = 0;
      cout << endl;
      cout << "counter = " << counter; //testing
      cout << endl;

      cout << "Please enter a word:\n";
     
      do
        {
         
          cin.get(word[counter]);
          cout << endl;
          cout << "counter = " << counter; 
          cout << ";  word[" << counter << "] = " << (int)word[counter]; //testing
          cout << endl;
          counter++; 
     
        }while (word[counter-1] != '\n'); 
      size = counter - 1;
      cout << size << " size"; 
      cout << endl;
      cout << endl;
      cout << "counter = " << counter; 
      cout << endl;
    }
    void delete_repeats(char word[], int& size)
    {
      for (int i = 0; i < size; i++)
        {
     
          for (int j = i+1; j < size; j++)  
    {
     if (word[i] == word[j])
       {
     
         for (int k = j; k < size - 1; k++) 
    {
     
     word[k]= word[k + 1];
    }
         
         j--;
         size--;
       } 
     cout << "size = " << size;
     cout << endl;
    }
        }
    }

    Multidimensional Arrays

    C++ allows arrays with multiple index values.  For example:

    char page[30][100]; 

    Page has two index values: the first ranges from 0 to 29 and the second ranges from 0 to 99.
    Page can be visualized as an array of 30 rows and 100 columns.

    Recall that the size of an array is not needed when declaring a formal parameter:

    void display_line(const char a[], int size);

    The base type of a multi-dimensional array must be completely specified in the parameter declaration:

    void display_page (cont char page[] [100], int size_dimension_1);


    Two-Dimensional Array Problem Example: