CSC 101 Lecture Notes Week 7, Part 2
Character Strings as Arrays
////
//
// This program reads a character string from the terminal and outputs the
// string characters back to the terminal, one by one.
//
////
#include <iostream.h>
int main() {
char string_value[11]; // Holds up to 10 chars, plus null termination
int i; // Loop and array index
//
// Prompt for and read a value into the string variable.
//
cout << "Input a string up to 10 characters long: ";
cin >> string_value;
//
// Output the individual chars of the string variable one by one.
//
cout << "The significant chars of the string value are: " << endl;
for (i = 0 ; string_value[i] != '\0' ; i++) {
cout << " string_value[" << i << "] = " << string_value[i] << endl;
}
return 0;
}
Input a string up to 10 characters long: hi
The significant chars of the string value are:
string_value[0] = h
string_value[1] = i
| Function | Description |
| int strlen(char* str) | Return the number of characters in str, excluding the null termination. |
| int strcmp(char* str1, char* str2) | Compare str1 with str2, returning 0 if they are lexically, a negative value if str1 is lexically less than str2, and a positive value if st1 is lexically greater than str2. |
| void strcpy(char* to_str, char* from_str) | Copy all of the characters from from_str, including the null, into to_str; from_str must be large enough to hold the number of chars copied. |
////
//
// This file declares functions that illustrate the kinds of card-related
// processing that will be done in programmming assignments 5 and 6.
//
// NOTE: this is a C++ header file, containing only function declarations, but
// no definitions. The companion file card-play.cpp, q.v., contains the
// the definitions of the functions declared here.
//
////
#ifndef card_play_included
#define card_play_included
#include "Boolean.h"
#include <fstream.h>
const int DECK_SIZE = 52; // Number of cards in a deck
const int CARD_STR_LEN = 4; // Number of chars in the string rep of a card
////
//
// Function ReadCardAsString inputs a single card from the terminal and returns
// the card as a string in the reference parameter. The format of the card is
// as described in the program 5 writeup. This function does no validity
// checking of the card spelling, it simply inputs it as a string of two or
// three characters.
//
////
void ReadCardAsString(
char card[CARD_STR_LEN] // Returned card string
);
////
//
// Function ReadCardAsIntAndChar inputs a single card from the terminal and
// returns the card as a two-part value in the face_value and suit reference
// parameters. The format of the card is as described in the program 5
// writeup. The face_value is an integer between 1 and 13. The values 2
// through 10 represent the face value directly. The face value 1 is for an
// Ace, 11 for a Jack, 12 for a Queen, and 13 for a King. The suit is one of
// the characters 'S', 'H', 'D', or 'C'.
//
// This function performs validity checking of the input. Specifically, the
// first one or two characters must be a legal face value and the last
// character must be a legal suit. If the input is legal, the function returns
// TRUE, otherwise FALSE.
//
////
Boolean ReadCardAsIntAndChar(
int& face_value, // Returned face value
char& suit // Returned suit
);
////
//
// Function ReadFaceValue does the face value processing for function
// ReadCardAsIntOrChar, from which it is called.
//
////
void ReadFaceValue(
int& face_value // Returned face value
);
////
//
// Function ReadSuit does the suit processing for function ReadCardAsIntOrChar,
// from which it is called.
//
////
void ReadSuit(
char& suit // Returned suit
);
////
//
// Function ReadDeckFromFile reads a full card deck from the given input file.
// The file is assumed to contain DECK_SIZE legal cards. The deck is returned
// as an array of DECK_SIZE character strings in the deck reference parameter.
//
////
void ReadDeckFromFile(
ifstream& deck_file, // Input file
char deck[DECK_SIZE][CARD_STR_LEN] // Returned deck of cards
// ^^^^^^^^^ ^^^^^^^^^^^^
// ^^^^^^^^^ ^^^^^^^^^^^^ CARD_STR_LEN is the size of each array
// element (a card string)
// ^^^^^^^^^
// ^^^^^^^^^ DECK_SIZE is the size of the deck array
);
////
//
// Function DumpDeck simply dumps a deck of 52 cards to the terminal.
//
////
void DumpDeck(char deck[DECK_SIZE][CARD_STR_LEN]);
#endif
////
//
// This file contains function definitions for the functions declared in
// card-play.h, q.v.
//
// NOTE: this file has no main function. It is designed to be compiled with a
// separate test driver file. For example, to test the card reading functions
// in this file, it is compiled with a separate test driver file as follows:
//
// CC test-card-reads.cpp card-play.cpp -o test-card-reads
//
// File test-card-reads.cpp, q.v., contains a main driver function that calls
// the card reading functions in this file.
//
////
#include "card-play.h"
#include <iostream.h>
#include <fstream.h>
void ReadCardAsString(char card[CARD_STR_LEN]) {
cout << "Input a card: ";
cin >> card;
}
Boolean ReadCardAsIntAndChar(int& face_value, char& suit) {
cout << "Input a card: ";
//
// Initialize the face value to 0 and suit to ' '. If these initial values
// are not changed, then an input error was detected.
//
face_value = 0;
suit = ' ';
//
// Input the face value.
//
ReadFaceValue(face_value);
//
// If a legal face value was read, proceed to input the suit character.
//
if (face_value != 0) {
ReadSuit(suit);
}
//
// Ignore any remaining input chars up to the next newline.
//
cin.ignore(100, '\n');
//
// Return true if face value is non-zero and suit is non-blank, false
// otherwise.
//
if ((face_value != 0) && (suit != ' ')) {
return TRUE;
}
else {
return FALSE;
}
}
void ReadFaceValue(int& face_value) {
char in_char; // Temporary input char
//
// Input the next character from the terminal.
//
cin >> in_char;
//
// Read the next character from the terminal, and check it as legal face
// value. Note the trick for values 2 through 9, which subtracts the ASCII
// value of the character '0' to obtain the integer value of the character.
//
// If the char is between 2 and 9, compute its value with a cute trick.
// Viz., subtract the value of character '0' from the input char value.
// This will convert the digit character value to its numeric integer
// value. See pages 518-520, and page A30 of the textbook for more info.
//
if ((in_char >= '2') && (in_char <= '9')) {
face_value = in_char - '0';
}
//
// If the input char is for an ace, jack, queen, or king, make its face
// value 1, 11, 12, or 13, respectively.
//
else if (in_char == 'A') {
face_value = 1;
}
else if (in_char == 'J') {
face_value = 11;
}
else if (in_char == 'Q') {
face_value = 12;
}
else if (in_char == 'K') {
face_value = 13;
}
//
// If the input char is a '1', make sure the next char is a '0', and make
// the face value 10.
//
else if (in_char == '1') {
cin >> in_char;
if (in_char == '0') {
face_value = 10;
}
}
//
// Check that a legal face value was read. If not, output an error
// message.
//
if (face_value == 0) {
cout << "Illegal face value for card." << endl;
}
}
void ReadSuit(char& suit) {
char in_char; // Temporary input char
//
// Input the next character from the terminal.
//
cin >> in_char;
//
// Check that the suit char is legal and output an error message if
// not.
//
if ((in_char == 'C') || (in_char == 'D') ||
(in_char == 'H') || (in_char == 'S')) {
suit = in_char;
}
else {
cout << "Illegal suit for card." << endl;
}
}
void ReadDeckFromFile(ifstream& deck_file,
char deck[DECK_SIZE][CARD_STR_LEN]) {
int i;
//
// Loop through the input file, putting the file data values into
// successive elements of the deck array.
//
for (i = 0; deck_file; i++) {
deck_file >> deck[i];
}
}
void DumpDeck(char deck[DECK_SIZE][CARD_STR_LEN]) {
int i;
//
// Loop through the deck, outputting each element to the terminal.
//
for (i = 0; i < DECK_SIZE; i++) {
cout << "Card " << i << ": " << deck[i] << endl;
}
}
////
//
// This program performs some basic tests on the functions defined in
// card-play.cpp, q.v.
//
// NOTE: these tests are not exhaustive, they just do some basics. More
// thorough testing is done in other testing programs, such as
// card-read-tests.cpp, q.v.
//
////
#include "card-play.h"
#include <iostream.h>
#include <fstream.h>
const int MAX_HAND_SIZE = 20; // Maximum number of cards in any hand
int main() {
//
// Declare some variable to work with.
//
char deck[DECK_SIZE][CARD_STR_LEN]; // Basic deck
char players_hand[MAX_HAND_SIZE][CARD_STR_LEN]; // Sample hand of cards
char dealers_hand[MAX_HAND_SIZE][CARD_STR_LEN]; // " " " "
ifstream deck_file; // File containing cards
char card[CARD_STR_LEN]; // Sample card as string
int card_face_value; // Sample card as int
char card_suit; // and char
//
// Read a card from the terminal as a string.
//
ReadCardAsString(card);
cout << "Card read as string: " << card << endl;
//
// Read a card from the terminal as an int and char.
//
ReadCardAsIntAndChar(card_face_value, card_suit);
cout << "Card read as face value and suit: "
<< card_face_value << ", " << card_suit << endl;
//
// Open the sample card deck file, read it in, and dump it back out.
//
deck_file.open("fulldeck");
ReadDeckFromFile(deck_file, deck);
DumpDeck(deck);
//
// Perform some additional tests on the card handling functions.
//
cout << "Input a card value: ";
cin >> players_hand[0];
cout << "Value just put in players_hand[0] = " << players_hand[0] << endl;
cout << "Size of dealer's and player's hands (should be 20*4): "
<< sizeof(dealers_hand) << ", " << sizeof(players_hand) << endl;
cout << "Size of a hand elem: " << sizeof(players_hand[0]) << endl;
return 0;
}