// print_message // these '//' are for comments ... the same as in HLA
#include <iostream> // this includes the library header file to allow io
int main() // all our C++ programs will need to have an 'int main' function ...
{
// cout, endl, flush, cin are all in the std namespace
// :: is the C++ scope operator
// display Hello World! on the default outout device, often the console screen
std::cout << "Hello World!" << std::endl;
std::cout << "Press 'Enter' key to continue ... "
<< std::flush; // dump cout stream buffer to the standard output device
// wait for the 'Enter' key to be pressed ...
std::cin.get();
return 0; // this line will be supplied by the C++ compiler if left off ...
}
// print_message2 // these are for comments ... the same as in HLA
#include <iostream> // this includes the library header file to allow io
using namespace std;
int main() // all our C++ programs will need to have an 'int main' function ...
{
// display Hello World! on the standard outout device, often the console screen
cout << "Hello World!" << endl;
cout << "Press 'Enter' key to continue ... "
<< flush; // dump cout stream buffer to the standard output device
// wait for the 'Enter' key to be pressed ...
cin.get();
return 0; // this line will be supplied by the C++ compiler if left off ...
}
// print_message3 // these '//' are for comments ... the same as in HLA
#include <iostream> // this includes the library header file to allow io
// NOTE: Comments are stripped off by the compiler,
// (everything past ... and including the '//' char's on a line),
// when it compiles your xxx.cpp text program file ...
// So you may USE comments FREELY to help guide/document
// your programs 'LOGIC FLOW' ... and this will NOT increase at all the size of
// the final compiled/linked xxx.exe file ...
int main() // all our C++ programs will need to have an 'int main' function ...
{
// cout, endl, flush, cin are all in the std namespace
// :: is the C++ scope operator
using std::cout;
using std::endl;
using std::flush;
using std::cin;
// display Hello World! on the standard outout device, often the console screen
cout << "Hello World!" << endl;
cout << "Press 'Enter' key to continue ... "
<< flush; // dump cout stream buffer to the standard output device
// wait for the 'Enter' key to be pressed ...
cin.get();
return 0; // this line will be supplied by the C++ compiler if left off ...
}
// get_input (using cin >> ...)
// NOTE: if you need to enter a 'name' that has a space in it, the commands ...
// string name;
// cin >> name;
// will NOT get that whole name ... It will ONLY GET the PART up to the first ('white') space ...
// and leave the rest ... still in the cin 'in-stream buffer'
// NOTE: ... but ... THIS IS the desired thing ...in SOME program situations!
// NOTE: See the program (after this one) that demo's getline( cin, name) ...
// getline(..) gets the whole line (and clears the '\n' char at the end)
// Note: with getline(..) the '\n' char is discarded .. and is not part of the string
// Using getline(..) is an easy C++ way of getting strings
// (i.e. the whole line into a string)
#include <iostream> // this includes the library header file to allow io
#include <string> // this includes C++ strings ...
using namespace std;
int main()
{
// construct 2 C++ string objects with initial value "" the empty string
string first_name, last_name; // Note: use 'meaning-full' (i.e. helpful) variable names ...
cout << "'" << first_name << "','" << last_name << "'\n"; // show that initial value really is ""
cout << "\nPlease enter your first name : ";
cin >> first_name; // get input (from keyboard) via the cin 'in stream'
cout << "\nNow enter your last name : ";
cin >> last_name; // NOTE: cin >> ***SKIPS over ALL leading 'whitespace(s)'***
// ***but LEAVES ALL trailing whitespace like '\n' char in
// the cin 'in-stream biffer'*** ... (which IS THE DESIRED
// behaviour in SOME program situations!)
cout << "\nAre you really " << last_name << ", " << first_name << "?\n"
<< "\nPress 'Enter' key to continue ... " << flush;
// wait for the 'Enter' key to be pressed ...
// flush cin stream of '\n' (the newline char) and all proceeding char's
// that may have been (accidently) typed ...
cin.sync();
cin.get();
}
// get_input2
// note: getline(..) gets the whole line (and clears the '\n' char at the end)
// an easy C++ way of getting strings (i.e. the whole line into a string)
#include <iostream> // this includes the library header file to allow io
#include <string> // this includes C++ strings ...
using namespace std;
int main()
{
cout << "\nPlease enter your first name : ";
string first_name;
getline(cin, first_name); // get input (from keyboard) via getline(..) function
cout << "\nNow enter your last name : ";
string last_name;
getline(cin, last_name);
cout << "\nAre you really " << last_name << ", " << first_name << "?\n"
<< "\nPress 'Enter' key to continue ... " << flush;
cin.get(); // wait for 'Enter' to be pressed ...
}
// add_nums
#include <iostream>
using namespace std;
int main()
{
int num1 = 23; // initialize num1 to 23
int num2 = 77; // initialize num2 to 77
cout << "The sum of " << num1 << " and " << num2 << " is "
<< num1 + num2 << endl << endl;
cout << "Enter an integer: ";
cin >> num1;
cout << "Enter a second integer: ";
cin >> num2;
cout << "The sum of " << num1 << " and " << num2 << " is "
<< num1 + num2 << endl
<< "\nPress 'Enter' key to continue ... " << flush;
// wait for the 'Enter' key to be pressed ...
// flush cin stream of '\n' (the newline char) and all proceeding char's
// that may have been (accidently) typed ...
cin.sync();
cin.get();
}
// repeat_proc
#include <iostream>
#include <string> // re. string reply; getline( cin, reply );
using namespace std;
// The following function (procedure) asks for two integers to be entered
// and then finds their sum.
// It then prints out the two integers just input
// and also their sum.
// Note: a 'procedure' does not return a value via a return statement
void get_nums_find_sum()
{
cout << "Enter an integer: ";
int num1=0;
cin >> num1;
cout << "Enter a second integer: ";
int num2=0;
cin >> num2;
cin.sync(); // flush cin stream of all char's up to and including '\n' ...
cout << "The sum of " << num1 << " and " << num2 << " is "
<< num1 + num2;
}
int main()
{
for( ;; ) // a C/C++ forever loop ... until break ... or return
{
// now execute the function (as defined above)
get_nums_find_sum();
cout << "\n\nMore (y/n) ? ";
string reply;
getline( cin, reply );
// defaults to 'yes' ...
if( reply[0]=='n' || reply[0]== 'N' ) // we just want the 1st char in reply
return 0; // exit main function ...
// else ... if we reach here ...
cout << "\nOk ... Here we go again.\n" << endl;
}
}
// repeat_proc2
#include <iostream>
#include <string>
using namespace std;
// This function has a C style char string prompt passed in
// and returns a 'validated' integer ...
int getInteger( char prompt[] )
{
for( ;; ) // loop foever ... until break or return ...
{
cout << prompt;
int tempInt;
cin >> tempInt;
if( !cin.good() ) // if some non-integer char was entered first ...
{
cout << "\nERROR! Integers only please in the range "
<< "allowed for an 'int' ...\n";
cin.clear(); // clear error flags ...
cin.sync(); // flush cin stream ...
continue; // goto the top of the for loop and start again right now
}
// if we reach here ... no error flags ... so have a valid int
cin.sync(); // so first 'flush' cin stream ...
return tempInt; // then return a valid integer ...
}
}
// The following function (procedure) asks for two integers to be entered
// and then finds their sum.
// It then prints out the two integers just input
// and also their sum.
// Note: a 'procedure' does not return a value via a return statement
void get_nums_find_sum()
{
// Note: here we call the function defined above to get a 'valid' integer
int num1 = getInteger( "Enter an integer: " );
int num2 = getInteger( "Enter a second integer: " );
cout << "The sum of " << num1 << " and " << num2 << " is "
<< num1 + num2;
}
int main()
{
for( ;; ) // a C/C++ forever loop ... until break ... or return
{
// now execute the function (as defined above)
get_nums_find_sum();
cout << "\n\nMore (y/n) ? ";
string reply;
getline( cin, reply );
// defaults to 'yes' ...
if( reply[0]=='n' || reply[0]== 'N' ) // we just want the 1st char in reply
return 0; // exit main function ...
// else ... if we reach here ...
cout << "\nOk ... Here we go again.\n" << endl;
}
}
// repeat_proc3
#include <iostream>
#include <string> // re. the statements: string reply; getline( cin, reply );
#include <climits> // re. using the values: INT_MIN and INT_MAX
using namespace std;
// This function demo's a C style char string prompt
// being passed in ... and returning a 'validated' integer
int getInteger( char prompt[] )
{
int tempInt;
for( ;; ) // loop foever ... until break or return
{
cout << prompt;
cin >> tempInt;
if( cin.good() )
{
cin.sync(); // so first 'flush' cin stream ...
return tempInt; // then return valid integer
}
// if we reach here ... error flag(s) set...
cout << "\nValid input is an integer in the range "
<< INT_MIN << " to " << INT_MAX <<" ...\n";
cin.clear(); // clear error flags ...
cin.sync(); // flush cin stream ...
}
}
// The following function (procedure) asks for two integers
// to be entered and then finds their sum. It then prints
// out the two integers just input and also their sum. Note:
// a 'procedure' does not return a value via a return statement
void get_nums_find_sum()
{
// Note: here we call the function defined above to
// get a 'valid' integer
int num1 = getInteger( "Enter an integer: " );
int num2 = getInteger( "Enter a second integer: " );
cout << "The sum of " << num1 << " and " << num2 << " is "
<< num1 + num2;
}
// returns 'true' or 'false' ...
bool more()
{
cout << "\n\nMore (y/n) ? ";
string reply;
// recall get's the whole line (scraps '\n' at end)
getline( cin, reply );
// defaults to 'yes' (must enter 'n' or 'N' to get 'false')
// we just use the 1st char in reply
if( reply[0]=='n' || reply[0]== 'N' )
return false;
// else ... if we reach here ...
cout << "\nOk ... Here we go again ...\n";
return true;
}
int main()
{
// Here we call (repeatedly) just two functions ...
// 1: get_nums_find_sum();
// 2: more(); ... while more returns 'true'
do
{
get_nums_find_sum();
}while( more() );
}
// testing123
#include <iostream> // include the io header file to allow io functions ...
using namespace std;
int main()
{
cout << "Ok. Testing " << 1234567890 << endl; // just to give some output …
cout << "\nPress 'Enter' to continue ... " << flush;
cin.get(); // wait for 'Enter' ...
return 0;
}
#include <iostream>
#include "myDoIt.h"
// compNamNum
#include <iostream>
int main()
{
char cName[] = "Dumb Computer"; // in memory with label cName
int cNumb = 1234567890; // in memory with label cNumb
// cout is part of the <iostream> library
// in the std namespace, '\n' is for a 'new line' for all OS’s ... and endl also ... but endl also flushes buffer
std::cout << "The name of this computer is " << cName << std::endl;
std::cout << "The number of this computer is " << cNumb << std::endl
<< "\nPress 'Enter' to exit ..." << std::flush;
std::cin.get();
}
// test_showNameNumb
#include <iostream>
using namespace std;
// Note syntax of how string and number get passed to the following function
// Note: A function must be declared/defined before it can be called by a program.
// 1st variable passed is a C string and the 2nd is an int
// NOTE! ',' separator
void printout( char cNam[], int cNum )
{
cout << "The name.number of this computer is " << cNam << "." << cNum << endl;
}
int main()
{
// Note that 1st passed is a constant string, 2nd passed is a constant int
// Note the ',' separator used between parameters
// when functions are called …
printout( "1_Dumb_Computer", 123456789 );
printout( "2_Dumb_Computer", 234567890 );
printout( "3_Dumb_Computer", 345678901 );
cout << "\nPress 'Enter' to exit ..." << flush;
cin.get();
}
// fileName: bare_bones.cpp
#include <iostream>
using namespace std;
int main()
{
return 0;
}
// guessIt
#include <iostream>
using namespace std;
// Note: procedure playgame is the main game ...
void playgame()
{
cout << "THE COMPUTER will roll the dice AFTER\n"
<< "YOU ENTER a number in the RANGE 2..12\n"
<< "Ok ... what is your guess: ";
int userNum;
cin >> userNum;
cin.sync(); // flush cin stream ...
// The following tasks are yet to be coded:
// 1. get two random numbers 1..6 for each die
// 2. see if sum of die matches the number the user guessed
// 3. report success or falure
cout << "You entered " << userNum << endl;
}
int main()
{
int reply;
// since we presume that the user wants to play at least one time ...
do // ... we can use the do..while(..) structure
{
playgame();
cout << "\nPlay again (y/n) ? ";
reply = cin.get(); // NOTE! cin.get() return type is an 'int'
cin.sync(); // flush cin stream ...
}while( !(reply=='n' || reply=='N') ); // i.e. until n or N entered
}
// This function returns true if x <= 12 ...
// otherwise it returns false
bool isValid( int x )
{
if(x <= 12)
return true;
// else ... if reach here ...
return false;
}
// guessIt2
#include <iostream>
using namespace std;
// This function returns false if x < 2 or x > 12 ...
// otherwise it returns true (if x is a valid integer)
bool isValid( int x )
{
if( !cin.good() )
{
cin.clear(); // in case error flags set ...
cin.sync(); // flush cin stream ...
cout << "\nNon integer entered ... ";
return false;
}
if( x < 2 || x > 12 )
{
cout << "\nOut of range 2..12 ... ";
cin.sync(); // flush cin stream ...
return false;
}
// else ... if reach here ...
cin.sync(); // flush cin stream ...
return true;
}
// Note: void function (i.e. procedure) playgame is the main game ...
void playgame()
{
cout << "THE COMPUTER will roll the dice AFTER\n"
<< "YOU ENTER a number in the RANGE 2..12\n";
int userNum;
do
{
cout << "Your guess 2..12 : ";
cin >> userNum;
}while( !isValid( userNum ) );
// The following tasks are yet to be coded:
// 1. get two random numbers 1..6 for each die
// 2. see if sum of die matches the number the user guessed
// 3. report success or falure
cout << "You entered " << userNum << endl;
}
int main()
{
int reply;
// since we presume that the user wants to play at least one time ...
do // ... we can use the do..while(..) structure
{
playgame();
cout << "\nPlay again (y/n) ? ";
reply = cin.get(); // NOTE! cin.get() return type is an 'int'
cin.sync(); // flush cin stream ...
}while( !(reply=='n' || reply=='N') ); // i.e. until n or N entered
}
/* rand example: guess the number */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main ()
{
int iSecret, iGuess;
/* initialize random seed: */
srand ( time(NULL) );
/* generate secret number: */
iSecret = rand() % 10 + 1;
do {
printf ("Guess the number (1 to 10): ");
scanf ("%d",&iGuess);
if (iSecret<iGuess) puts ("The secret number is lower");
else if (iSecret>iGuess) puts ("The secret number is higher");
} while (iSecret!=iGuess);
puts ("Congratulations!");
return 0;
}
// guessIt3
#include <iostream>
#include <cstdlib> // re. rand
#include <ctime> // re. time
using namespace std;
// This function returns false if x < 2 or x > 12 ...
// otherwise it returns true (if x is an integer)
bool isValid( int x )
{
if( !cin.good() )
{
cin.clear(); // in case error flags set ...
cin.sync(); // flush cin stream ...
cout << "\nNon integer entered ... ";
return false;
}
if( x < 2 || x > 12 )
{
cout << "\nOut of range 2..12 ... ";
cin.sync(); // flush cin stream ...
return false;
}
// else ... if reach here ...
cin.sync(); // flush cin stream ...
return true;
}
// Note: void function (i.e. procedure) playgame is the main game ...
void playgame()
{
cout << "THE COMPUTER will roll the dice AFTER\n"
<< "YOU ENTER a number in the RANGE 2..12\n";
int userNum;
do
{
cout << "Your guess 2..12 : ";
cin >> userNum;
}while( !isValid( userNum ) );
// Note: userNum is first passed to isValid
// Then isValid returns true or false.
// get two random numbers 1..6 for each die
int die1 = rand() % 6 + 1;
int die2 = rand() % 6 + 1;
// see if sum matches
if( die1 + die2 == userNum )
cout << "MATCH!\n"; // report success
else
cout << "NO match!\n"; // report failure
cout << "You entered " << userNum << endl
<< "And the computer rolled " << die1 << " & " << die2
<< " or " << die1 + die2 << "." << endl;
}
int main()
{
// initialize random seed
srand ( time(NULL) );
int reply;
// since we presume that the user wants to play at least one time ...
do // ... we can use the do..while(..) structure
{
playgame();
cout << "\nPlay again (y/n) ? ";
reply = cin.get(); // NOTE! cin.get() return type is an 'int'
cin.sync(); // flush cin stream ...
}while( !(reply=='n' || reply=='N') ); // i.e. until n or N entered
}
// guessIt4
#include <iostream>
#include <cstdlib> // re. rand
#include <ctime> // re. time
using namespace std;
// using globals to reduce parameter passing ... for this simple simulation
int cCents = 100; // defaults for Computer and Player
int pCents = 100;
int cWins = 0;
int pWins = 0;
int numGames = 0;
// This function returns false if x < 2 or x > 12 ...
// otherwise it returns true (if x is an integer)
bool isValid( int x, int low, int high)
{
if( !cin.good() )
{
cin.clear(); // in case error flags set ...
cin.sync(); // flush cin stream ...
cout << "\nNon integer entered ... ";
return false;
}
if( x < low || x > high )
{
cout << "\nOut of range 2..12 ... ";
cin.sync(); // flush cin stream ...
return false;
}
// else ... if reach here ...
cin.sync(); // flush cin stream ...
return true;
}
// Note: void function (i.e. procedure) playgame is the main game ...
void playgame()
{
cout << "THE COMPUTER will roll the dice AFTER\n"
<< "YOU ENTER a number in the RANGE 2..12\n";
int userNum;
do
{
cout << "Your guess 2..12 : ";
cin >> userNum;
}while( !isValid( userNum, 2, 12 ) );
// Note: userNum is first passed to isValid
// Then isValid returns true or false.
// get two random numbers 1..6 for each die
int die1 = rand() % 6 + 1;
int die2 = rand() % 6 + 1;
// see if sum matches
if( die1 + die2 == userNum )
{
cout << "MATCH!\n"; // report success
pCents += userNum; // player wins
cCents -= userNum; // computer loses
}
else
{
cout << "NO match!\n"; // report failure
pCents -= userNum; // player loses
cCents += userNum; // computer wins
}
cout << "You entered " << userNum << endl
<< "And the computer rolled " << die1 << " & " << die2
<< " or " << die1 + die2 << "." << endl;
}
int main()
{
// initialize random seed
srand ( time(NULL) );
cout << "Computer stakes 100..1000 (cents) : ";
cin >> cCents;
cin.clear(); // in case non-integer entered ...
cin.sync();
if( cCents < 100 ) cCents = 100; // don't allow values less than 100
if( cCents > 1000 ) cCents = 1000; // don't allow values more than 1000
cout << "Player stakes 100..1000 (cents) : " ;
cin >> pCents;
cin.clear(); // in case non-integer entered ...
cin.sync();
if( pCents < 100 ) pCents = 100;
if( pCents > 1000 ) pCents = 1000;
int pCentsInitial = pCents; // get copies ...
int cCentsInitial = cCents;
cout << "\nThe computer staked " << cCents << " and the player staked "
<< pCents << " cents." << endl;
int reply;
// since we presume that the user wants to play at least one time ...
do // ... we can use the do..while(..) structure
{
++numGames;
playgame();
cout << "\nAfter game "<<numGames<<" player has "<<pCents<<" cents"
<< "\nand the computer has " << cCents << " cents\n";
cout << "\nPlay again (y/n) ? ";
reply = cin.get(); // NOTE! cin.get() return type is an 'int'
cin.sync(); // flush cin stream ...
}while( !(reply=='n' || reply=='N') && pCents > 0 && cCents > 0 );
// don't allow, (i.e. correct for), 'in-hole' stuations ...
if( pCents < 0 ) // player in hole
{
cCents -= -pCents; // i.e. decrease computer balance
pCents = 0; // so now can up balance of player to zero
}
else if( cCents < 0 ) // computer in hole
{
pCents -= cCents; // decrease player balance
cCents = 0; // so now can up balance of computer to zero
}
// can insert the starting 'stakes' here ...
// cCents, and pCents hold the values we need to print out with message
cout << "\nAfter " << numGames << " games, the computer has "
<< cCents << " cents\n"
<< "and the player has " << pCents << " cents" << endl;
// calclate the computer winnings
cWins = cCents - cCentsInitial;
// calculate the player winnings
pWins = pCents - pCentsInitial;
if( cWins > 0 ) // computer wins
{ // take the negative of pWins ...
cout << "The computer wins " << cWins
<< " and the player loses " << -pWins << endl;
}
else // computer loses
{ // take neg cWins ...
cout << "The player wins " << pWins
<< " and the computer loses " << -cWins << endl;
}
cout << "\nPress 'Enter' to continue ... " << flush;
cin.get(); // wait for 'Enter' ...
return 0;
}
// memoryFlowLab
#include <iostream>
using namespace std;
char myCharArray[255]; // reserve 255 bytes of memory for 255 char's
char myCh = 'z'; // reserve 1 byte of memory for 1 character
int myInt = 12345; // reserve (4 bytes on many systems) i.e. 32 bits, for an int
double myD = 1.23; // reserve (8 bytes on many systems)
// the following shows how to declare a 'pointer' type variable ...
double* pD = &myD;
int* pInt = &myInt; // now pInt holds address of myInt
char* pCh = &myCh;
char* pChAry = myCharArray;
int main()
{
int myInt2[] = {0, 1, 2, 3, 4};
cout << "&myInt2[0] is " << (int) &myInt2[0]
<< " and &myInt2[4] is " << (int) &myInt2[4] << endl;
// '&' means 'take the address of' ...
cout << "\nThe address of myCharArray is " << (int)&myCharArray
<< "\nThe address of myCharArray[0] is " << (int)&myCharArray[0]
<< "\nThe address of myCharArray[254] is " << (int)&myCharArray[254]
<< "\nThe address of myChr is " << (int)&myCh
<< "\nThe address of myInt is " << (int)&myInt
<< "\nThe address of myD is " << (int)&myD
<< "\nThe value of pD is " << (int)pD
<< "\nThe value of pInt is " << (int)pInt
<< "\nThe value of pChAry is " << (int)pChAry
<< "\n\nThe address of pChAry is " << (int)&pChAry
<< endl;
cout << "\nThe sizeof(myCharArray) is " << sizeof(myCharArray)
<< "\nThe sizeof(pChAry) is " << sizeof(pChAry)
<< "\nThe sizeof(myCharArray[0]) is " << sizeof(myCharArray[0])
<< "\nThe sizeof(myCh) is " << sizeof(myCh)
<< "\nThe sizeof(pCh) is " << sizeof(pCh)
<< "\nThe sizeof(myInt) is " << sizeof(myInt)
<< "\nThe sizeof(pInt) is " << sizeof(pInt)
<< "\nThe sizeof(myD) is " << sizeof(myD)
<< "\nThe sizeof(pD) is " << sizeof(pD)
<< endl;
// Note: the compiler concatenates ADJACENT strings ... ok:)
cout << "\n\nWhat to learn:\n\n"
"As the program flows,"
" (i.e. executes), as we have written it\n"
"from the 'top' to the 'bot' ...\n"
"do the values of the addresses in memory decrease or increase?\n";
cout << "\nPress 'Enter' to continue ... " << flush;
cin.get(); // wait for 'Enter' ...
return 0;
}
// memoryFlowLab2
#include <iostream>
#include <iomanip> // re. setw(..) and hex
using namespace std;
// An example of initializing at the same time as declaring variables.
// We have printed out the value of the memory addresses of some variables, so
// lets ALSO print out the (typed) values in these addresses ...
// reserve 256 bytes of memory for 256 char's ... last 248 are empty
char myCharArray[256] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', '\0' };
// reserve 1 byte of memory for 1 character
char myChr = 'z';
// set p, a pointer to 'char', to hold the address of the first element in myCharArray
char* p = myCharArray;
int main()
{
cout << hex << showbase
<< "(int)myCharArray = " << (int)myCharArray
<< "\n&myCharArray = " << &myCharArray
<< "\nThe (typed) VALUE at THAT ADDRESS is " << myCharArray;
cout << "\n\nThe address of variable myCharArray[0] is "
<< (int)&myCharArray[0]
<< "\nThe (typed) VALUE at THAT ADDRESS is " << myCharArray[0];
cout << "\n\nThe address of variable myCharArray[1] is "
<< (int)&myCharArray[1]
<< "\nThe (typed) VALUE at THAT ADDRESS is " << myCharArray[1];
cout << "\n\nThe address of variable myCharArray[254] is "
<< (int)&myCharArray[254]
<< "\nThe (int)VALUE IN THAT ADDRESS is " << (int)myCharArray[254];
cout << "\n\nThe address of variable myCharArray[255] is "
<< (int)&myCharArray[255]
<< "\nThe (int)VALUE IN THAT ADDRESS is " << (int)myCharArray[255];
cout << "\n\nThe address of variable myCharArray[256] is "
<< (int)&myCharArray[256]
<< "\nThe (typed) VALUE at THAT ADDRESS is " << myCharArray[256];
cout << "\n\nThe address of variable myChr is " << (int)&myChr
<< "\nThe (typed) VALUE at THAT ADDRESS is " << myChr << endl << endl;
cout << "\nCan you figure out all the above outputs?"
<< " Press 'Enter' to continue ... ";
cin.get(); // wait for 'Enter' key to be pressed ...
// ok here is an example using the C++ for.. loop structure
// let's use a register as a counter to give the maximum speed counting ...
for( register int i=0; i < 256; ++i )
cout << myCharArray[ i ] << ",";
int w = 13;
// Now ... print out some headers, right-adjusted in 10 character wide fields.
cout << "\n\n" << setw(w) << "hex address" << setw(w) << "value"
<< setw(w) << "(int)value" << setw(w) << "index" << "\n\n";
for( int i=0; i<10; ++i )
cout << setw(w) << hex << (int)&myCharArray[i]
<< setw(w) << myCharArray[i]
<< setw(w) << dec << (int)myCharArray[i] <<setw(w) << i << endl;
cout << "\nCan you figure out all these above outputs?"
<< " Press 'Enter' to continue ... ";
cin.get(); // wait for 'Enter' key to be pressed ...
// Now ... print out some headers, right-adjusted in 10 character wide fields.
cout << "\n\n" << setw(w) << "hex address" << setw(w) << "value" << endl;
cout << hex;
for( int i=0; i<17; ++i )
{
cout << setw(w) << (int)p << setw(w) << *p << endl;
++p; // go to next byte (address)
}
// this shows that array 'bounds' are NOT checked
// and thus are the ... *RESPONSIBILITY of the PROGRAMMER*
p = myCharArray; // re-set address ...
p += 256; // go to 1 past last char ... i.e. the 'z' of 'mychr'
cout << "...\n" << setw(w) << (int)p << setw(w) << *p
<< " ... array bound NOT checked" << endl
<< setw(w) << (int)&myCharArray[256] << setw(w) << myCharArray[256]
<< " ... array bound NOT checked" << endl;
cout << "\nPress 'Enter' to continue ... " << flush;
cin.get(); // wait for 'Enter' ...
return 0;
}
// memoryFlowLab3
#include <iostream>
#include <iomanip>
using namespace std;
// An example of initializing at the same time as declaring variables.
// We have printed out the value of the memory addresses of some variables, so
// lets ALSO print out the (typed) values in these addresses ...
// reserves 80 bytes of memory for 20 int32's. Note: (20*4bytes) = 80bytes
// (if sizeof(int) on your system is 4 bytes ...)
int myIntAry[20] = {1,2,3,4,5,6,7,8,9,0}; // last 10 are empty ...
int myInt = 987654321;
// set p, a pointer to 'myInt', to hold the address of the first element in myIntAry
int* p = myIntAry;
int main()
{
cout << "myIntAry is " << myIntAry
<< "\nThe (typed) VALUE at THAT ADDRESS is " << *myIntAry;
cout << "\n\nThe address of variable myIntAry[0] is " << &myIntAry[0]
<< "\nThe (typed) VALUE at THAT ADDRESS is " << myIntAry[0];
cout << "\n\nThe address of variable myIntAry[1] is " << &myIntAry[1]
<< "\nThe (typed) VALUE at THAT ADDRESS is " << myIntAry[1];
cout << "\n\nThe address of variable myIntAry[18] is " << &myIntAry[18]
<< "\nThe (typed) VALUE at THAT ADDRESS is " << myIntAry[18];
cout << "\n\nThe address of variable myIntAry[19] is " << &myIntAry[19]
<< "\nThe (int) VALUE at THAT ADDRESS is " << (int)myIntAry[19];
cout << "\n\nThe address of variable myIntAry[20] is " << &myIntAry[20]
<< "\nThe (int) VALUE at THAT ADDRESS is " << (int)myIntAry[20];
cout << "\n\nThe address of variable myInt32 is " << & myInt
<< "\nThe (typed) VALUE at THAT ADDRESS is " << myInt
<< endl << endl;
// ok here is an example using the C++ for..loop structure
// let's use a register as a counter to give the maximum speed counting ...
for( register int i=0; i<=20; ++i ) // will go over 'bounds' ...
cout << myIntAry[i] << " ";
cout << "\nCan you figure out all the above outputs?"
<< " Press 'Enter' to continue ... ";
cin.get(); // wait for 'Enter' key to be pressed ...
// Now ... print out some headers, right-adjusted in 10 character wide fields.
int w = 10;
cout << "\n\n" << setw(w) << "address" << setw(w) << "value" << "\n\n";
for( int i=0; i<=20; ++i) // goes out of bounds ...
cout << setw(w) << &myIntAry[i] << setw(w) << myIntAry[i] << endl;
cout << "\nCan you figure out all these above outputs?"
<< " Press 'Enter' to continue ... ";
cin.get(); // wait for 'Enter' key to be pressed ...
// Now ... print out some headers, right-adjusted in 10 character wide fields.
cout << "\n\n" << setw(w) << "address" << setw(w) << "value" << endl;
for( int i=0; i<=20; ++i) // goes out of bounds ...
cout << setw(w) << p << setw(w) << *p++ << endl; // go to next int address
cout << "\nPress 'Enter' to continue ... " << flush;
cin.get(); // wait for 'Enter' ...
return 0;
}
// types ... some C++ data types
#include <iostream>
#include <string>
#include <iomanip>
#include <climits>
#include <cstring> // re. strcpy( to, from )
using namespace std;
unsigned short uShort = 0xff; // at least this large
short iShort = 0x7f; // at least this large
char ca = 'a';
char cz = 'z';
char cA = 'A';
char cZ = 'Z';
unsigned int uInt = 0xFFFF; // at least this large
int iInt = 0x7fff; // at least this large
unsigned long uLong = 0xffffffff;
long iLong = 0x7fffffff;
float f = 1234567890.123e-47;
double d = 1234567890.123e-316;
string s = "Pausing now ... Press 'Enter' to continue ...";
int main()
{
// get some new memory big enough to copy the C++ string into a C string ...
char* cstr = new char [s.size()+1]; // +1 for the '\0' char at the end ...
strcpy(cstr, s.c_str()); // convert s, a C++ string, to a C string, then copy
cout << "The sizeof(char) is " << sizeof(char)
<< "\nThe sizeof(short) is " << sizeof(short)
<< "\nThe sizeof(int) is " << sizeof(int)
<< "\nThe sizeof(long) is " << sizeof(long)
<< "\nThe sizeof(long long) is " << sizeof(long long)
<< "\nThe sizeof(float) is " << sizeof(float)
<< "\nThe sizeof(double) is " << sizeof(double)
<< "\nThe sizeof(long double) is " << sizeof(long double)
<< endl << endl;
for( int i='0'; i<='9'; ++i )
cout << setw(5) << (char)i;
cout << " ... as char's\n";
cout << hex << showbase; // ********** hex
for( int i='0'; i<='9'; ++i )
cout << setw(5) << i;
cout << " ... hex values\n";
for( int i='0'; i<='9'; ++i )
cout << setw(5) << dec << i - '0'; // ********** dec
cout << " ... numeric value extracted\n\n";
for( int i='A'; i<='Z'; ++i )
cout << setw(5) << (char)i;
cout << endl << hex; // ************* hex
for( int i='A'; i<='Z'; ++i)
cout << setw(5) << (int)i;
cout << endl << endl;
for( int i='a'; i<='z'; ++i )
cout << setw(5) << (char)i;
cout << endl;
for( int i='a'; i<='z'; ++i)
cout << setw(5) << (int)i;
cout << endl;
cout << endl << cstr;
cin.get();
cout << endl << endl;
cout << "uShort = " << uShort << " and iShort = " << iShort << endl
<< "uInt = " << uInt << " and iInt = " << iInt << endl
<< "uLong = " << uLong << " and iLong = " << iLong << endl
<< setprecision(13)
<< "f = " << f << " and d = " << d << endl
<< dec; // ************** dec
cout << "\nString s ...\n"<< s << "\nhas s.length() = "
<< s.length() << endl;
for( int i=0; i<5; ++i )
for( int j=0; j<10; ++j )
{
if( j<9) cout << j+1;
else cout << 0;
}
cout << " ...check the string length." << endl << endl;
// static_cast<<type>>(<value>);
int tmpInt = -1;
uInt = static_cast <unsigned> (tmpInt);
// data interpretation ...
cout << "tmpInt = " << tmpInt
<< " but interpreted as an unsigned = " << uInt << endl
<< " ... or interpreted as hex = " << hex << uInt << endl // **** hex
<< dec; // ***************************************************** dec
int w =15;
cout << left << setw(w)
<< SHRT_MIN << "Minimum value for an object of type short int\n"
<< setw(w)
<< SHRT_MAX << "Maximum value for an object of type short int\n"
<< setw(w)
<< USHRT_MAX<< "Maximum value for an object of type unsigned short int\n"
<< setw(w)
<< INT_MIN << "Minimum value for an object of type int\n"
<< setw(w)
<< INT_MAX << "Maximum value for an object of type int\n"
<< setw(w)
<< UINT_MAX << "Maximum value for an object of type unsigned int\n"
<< setw(w)
<< LONG_MIN << "Minimum value for an object of type long int\n"
<< setw(w)
<< LONG_MAX << "Maximum value for an object of type long int\n"
<< setw(w)
<< ULONG_MAX<< "Maximum value for an object of type unsigned long int"
<< endl;
// ok ... just for good practice (not really needed in this simple program
// To PREVENT MEMORY LEAKS ... ALWAYS delete any NEW dynamic mem when
// your program NO longer needs it ... and while you still HAVE a VALID
// POINTER to it ... so that you can specify that memory to be deleteD ...
delete [] cstr; // NOTE the syntax ... when you delete an array ... use []
cout << endl << s;
cin.get()
}
// realMath ... finds the running average of test scores
#include <iostream>
#include <iomanip>
using namespace std;
// function prototypes ... Note the semi-colon at the end here ...
// but NOT at the end of the header line, later, in each function definition
bool more();
int getInteger( char prompt[] );
int main()
{
cout << "The following program asks for input of test scores\n"
<< "and then finds the average of the scores todate:\n\n";
// initial all these 'counters' here, to zero, before we start the loop ...
int count = 0, totOutOf = 0, totScores = 0;
do
{
++count;
int score = getInteger("Enter score: ");
totScores += score; // shorter code for: totScores = totScores + score;
int outOf = getInteger("Enter outOf: ");
totOutOf += outOf;
// find average ... so far ...
// NOTE *we NEED to CAST the int totScores to a double BEFORE we divide*
// ... otherwise ... we get INTEGER division, which we do NOT want here
double average = double(totScores)/totOutOf * 100; // in % ...
// report ... set output format to 1 decimal places in an 5 char. field
cout << "The average of " << count << " test(s) with "
<< totScores << " marks out of " << totOutOf << " is "
<< setprecision(1) << fixed << setw(5) << average << "%" << endl;
}while( more() );
}
// defaults to 'Yes' ...
bool more()
{
cout << "\nMore ... (y/n) ? " << flush;
int reply = cin.get();
cin.sync(); // flush cin ...
return !( reply == 'n' || reply == 'N' );
}
// passes in a C string prompt ... returns valid int
int getInteger( char prompt[] )
{
for( ;; ) // forever loop ... until return from function
{
cout << prompt;
int tmpInt;
cin >> tmpInt;
if( !cin.good() )
{
cin.clear(); // clear error flags ...
cin.sync(); // flush cin ...
cout << "\nEnter an integer only ...\n";
continue; // right now from the top of the forever loop ...
}
// if you reach here ... good data .. so
cin.sync(); // flush cin stream ...
return tmpInt; // ... return good data right now
}
}
#include <iostream>
#include <string>
using namespace std;
const int MAX_COUNT = 3; // to keep our debuging short and simple
struct MyContacts // a C/C++ style data record ...
{
string theName;
string thePhone;
}; // Note: semi-colon here tells compiler we have reached the end of struct
string takeIn( string message )
{
cout << message << ": " << flush;
string tmpStr;
getline( cin, tmpStr );
return tmpStr;
}
// the number of contacts taken into the book is returned ...
// and array of MyContacts is updated ... (and returned by ref.)
int getBook( MyContacts book[], int max_num )
{
bool more = true;
int i = 0;
string reply;
while( i < max_num && more )
{
book[i].theName = takeIn( "Enter name " );
book[i].thePhone = takeIn( "Enter phone " );
++i;
cout << "More y/n ? " << flush; // defaults to yes (i.e. 'true') ...
getline( cin, reply );
more = !( reply[0] == 'n' || reply[0] == 'N' );
}// end while ...
return i; // i.e. the count of new contacts
}
// Note: we can pass in a const array ... since
// we are just printing out values there
void printBook( const MyContacts book[], int max_num )
{
cout << "\nYour 'book' :";
for( int i = 0; i < max_num; ++i )
{
cout << "\n\t\t" << book[i].theName
<< "\n\t\t" << book[i].thePhone
<< endl;
}
}
int main()
{
// at compile time, the compiler knows 'MAX_COUNT',
// so can reserve the requested memory ... for ...
MyContacts myBook[ MAX_COUNT ]; // an array with MAX_COUNT of MyContacts
// getBook returns the number of contacts ...
int numContacts = getBook( myBook, MAX_COUNT );
printBook( myBook, numContacts );
cout << "\nNote! The size of each of MyContacts, sizeof(MyContacts) = "
<< sizeof(MyContacts) << ", since each of the\n"
<< "2 strings in the record 'MyContacts' is really"
<< " only a " << sizeof(string) << " byte pointer.\n"
<< "\nPress 'Enter' to continue ... " << flush;
cin.get();
}
#include <iostream>
#include <string>
using namespace std;
const int MAX_COUNT = 3; // to keep our debugging short and simple
struct MyContacts // a C/C++ style data record ...
{
string theName;
string thePhone;
}; // Note: semi-colon here tells compiler we have reached the end of struct
string takeIn( const string& message )
{
string reply, tmpStr;
for( ;; ) // a C/C++ forever loop until break (or return, if in a function)
{
cout << message << ": " << flush;
getline( cin, tmpStr );
cout << "You input " << tmpStr << " ok (y/n) ? " << flush;
getline( cin, reply );
if( reply[0] == 'y' || reply[0] == 'Y' )
return tmpStr;
}
}
// the number of contacts taken into the book is returned ...
int getBook( MyContacts book[], const int max_num )
{
bool more = true;
int i = 0;
string reply;
while( i < max_num && more )
{
book[i].theName = takeIn( "Enter name " );
book[i].thePhone = takeIn( "Enter phone " );
++i;
cout << "More y/n ? " << flush; // defaults to yes (i.e. 'true') ...
getline( cin, reply );
more = !( reply[0] == 'n' || reply[0] == 'N' );
}// end while ...
return i; // i.e. the count of new contacts
}
// Note: we can pass in a const array ... since
// we are just printing out values there
void printBook( const MyContacts book[], const int max_num )
{
cout << "\nYour 'book' :";
for( int i = 0; i < max_num; ++i )
{
cout << "\n\t\t" << book[i].theName
<< "\n\t\t" << book[i].thePhone
<< endl;
}
}
int main()
{
// at compile time, the compiler knows 'MAX_COUNT',
// so can reserve the requested memory ... for ...
MyContacts myBook[ MAX_COUNT ]; // an array with MAX_COUNT of MyContacts
// getBook returns the number of contacts ...
int numContacts = getBook( myBook, MAX_COUNT );
printBook( myBook, numContacts );
cout << "\nNote! The size of each of MyContacts, sizeof(MyContacts) = "
<< sizeof(MyContacts) << ", since each of the\n"
<< "2 strings in the record 'MyContacts' is really"
<< " only a " << sizeof(string) << " byte pointer.\n"
<< "\nPress 'Enter' to continue ... " << flush;
cin.get();
}
// stringsCppTest.cpp
#include <iostream>
#include <string>
using namespace std;
int main()
{
string test;
do
{
cout << "Enter 'test' string (empty string to exit) : " << flush;
getline( cin, test );
cout << "You entered " << &test[0] << endl;
}
while( test.size() );
}
// simpleFileio
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
// creates an ofstream 'stream' object called 'fout' for/to the file "myfile.txt"
ofstream fout( "myfile.txt" ); // opens the file "myfile.txt" for output
// can check if file was opened ok ... like this
// if( ! fout ) {;} // print error message and do something like ... exit(1); ... perhaps
for( int i = 0; i < 10; ++i )
fout << i << endl;
fout.close(); // close the file stream to the file and flush ...
// any char's in the stream into that file ...
ifstream fin( "myfile.txt" ); // opens the file "myfile.txt" for input
int num;
// print ALL the numbers in the file on the console screen ...
while( fin >> num ) // Note: this loop will not be entered if !fin, i.e. file failed to open
cout << num << " ";
cout << "\n\nPress 'Enter' to continue ... " << flush;
cin.get();
}
// program fileRecords
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
const int MAX_COUNT = 3; // to keep our debuging short and simple
struct MyContacts // a C/C++ style data record ...
{
string theName;
string thePhone;
}; // Note: semi-colon here tells compiler we have reached the end of struct
string takeIn( const string& message )
{
string reply, tmpStr;
for( ;; ) // a C/C++ forever loop until break (or return, if in a function)
{
cout << message << ": " << flush;
getline( cin, tmpStr );
cout << "You input " << tmpStr << " ok (y/n) ? " << flush;
getline( cin, reply );
if( reply[0] == 'y' || reply[0] == 'Y' )
return tmpStr;
}
}
// the number of contacts taken into the book is returned ...
// (and the updated array of MyContacts is returned ...
// recall C/C++ arrays 'passed by ref. automatically')
int getBook( MyContacts book[], const int max_size )
{
bool more = true;
int i = 0;
while( i < max_size && more )
{
book[i].theName = takeIn( "Enter name " );
book[i].thePhone = takeIn( "Enter phone " );
++i;
if( i < max_size )
{
cout << "More y/n ? " << flush; // defaults to yes (i.e. 'true') ...
string reply;
getline( cin, reply );
more = !( reply[0] == 'n' || reply[0] == 'N' );
}
}// end while ...
return i; // i.e. the count of new contacts
}
// Note: we can pass in a const array ... since
// we are just printing out values there
void printBook( const MyContacts book[], const int size )
{
cout << "\nYour 'book' :";
for( int i = 0; i < size; ++i )
{
cout << "\n\t\t" << book[i].theName
<< "\n\t\t" << book[i].thePhone
<< endl;
}
}
void fileBook( ofstream& out, const MyContacts book[], const int size )
{
for( int i = 0; i < size; ++i )
{
out << book[i].theName << endl
<< book[i].thePhone << endl;
}
}
int main()
{
// at compile time, the compiler knows 'MAX_COUNT',
// so can reserve the requested memory ... for ...
MyContacts myBook[ MAX_COUNT ]; // an array with MAX_COUNT of MyContacts
// getBook returns the number of contacts ...
int numContacts = getBook( myBook, MAX_COUNT );
printBook( myBook, numContacts );
ofstream fout( "myFile.txt" );
fileBook( fout, myBook, numContacts );
fout.close();
// just to leave extra room for reading anything extra that might be there
// (so we can show here that nothing else was there ...)
MyContacts myBook2[ MAX_COUNT*2 ];
ifstream fin( "myFile.txt" ); // open an ifstream stream to the file
int i = 0;
// fill the array from the file ...
while
(
i < MAX_COUNT*2 &&
getline(fin, myBook2[i].theName) &&
getline(fin, myBook2[i].thePhone)
)
++i;
fin.close(); // close the input file ... i now holds the count of records read
cout << "From file ... ";
printBook( myBook2, i );
cout << "Press 'Enter' to continue ... " << flush;
cin.get();
}
// addToContacts.cpp
// Chapter 15:
// The Computer reads/updates (adds to, or sets to 'zero') its files ...
// Note the beginnings of a menu added here ... and all the additions/changes
// so that we can now call the functions in the 'MENU' below ... from the menu.
// Note all the if... else if... else... logic added re. reading/writing files.
#include <iostream>
#include <iomanip> // for formatting cout output here ...
#include <fstream>
#include <sstream> // for stringstream conversions
#include <string>
#include <cctype> // for isdigit, toupper
using namespace std;
const int MAX_NUM = 10; // to keep our debuging short and simple
const char MY_FILE[] = "myRecords.dat";
const string indent(14, ' '); // construct string 'indent' with 14 space char's
const string MENU = indent + "1. Add new contacts\n" +
indent + "2. Show book\n" +
indent + "3. File book\n" +
indent + "4. Load book from file\n" +
indent + "5. Initial memory\n" +
indent + "0. Quit\n" +
"Your choice : ";
struct MyContacts // a 'struct' may be used for a C/C++ style 'data record' ...
{
string theName;
string thePhone;
}; // Note: semi-colon here tells compiler we have reached the end of 'struct'
// prompts for input via the passed in 'message'
// and returns the string that the user entered ...
string takeIn( const string& message )
{
string tmpStr;
cout << message << ": " << flush;
getline( cin, tmpStr );
return tmpStr;
}
// validate that the phone number is a 10 digit string like: 1234567890
// and to save making a local copy can pass in the C++ string by 'const ref'
bool isValidPhone( const string& pNum )
{
if( pNum.length() != 10 )
{
cout << "\nError: Phone number must have 10 digits.\n";
return false;
}
for( int j = 0; j<10; ++ j )
{
if( !isdigit( pNum[j] ) )
{
cout << "\nError: Integers only for Phone number.\n";
return false; // break out if this for loop right now ...
}
}
// if reach here ...
return true;
}
// the number of contacts in the book is returned ... and (by ref) the updated book
int updateBook( MyContacts book[], const int start_i, const int max_num )
{
if( start_i == max_num )
{
cout << "The book is filled ... Set 'MAX_NUM' to a larger number." << endl;
return max_num;
}
string reply;
int i = start_i;
bool more = true;
while( i < max_num && more )
{
stringstream ss;
ss << "[" << i+1 << "] ";
string tmpStr = ss.str(); // convert stringstream 'ss' to string 'tmpStr'
// note C++ string 'tmpStr' is in the middle, so we can concatenate here
book[i].theName = takeIn( "Name"+tmpStr+"(or press 'Enter' to exit) " );
if( book[i].theName.length() == 0 ) return i; // 0 len, so exit function
book[i].thePhone = takeIn( "Phone number"+tmpStr+"... all 10 digits " );
if( !isValidPhone(book[i].thePhone) ) continue; // from top of while now
cout << "Ok ... (y/n) ? " << flush;
getline( cin, reply );
if( !( reply[0] == 'y' || reply[0] == 'Y') ) continue; // at top 'while
++i; // since reached here, data accepted above, so increment counter
cout << "More ... (y/n) ? " << flush; // defaults to yes (i.e. 'true')
getline( cin, reply );
more = !( reply[0] == 'n' || reply[0] == 'N' );
}// end while ...
return i; // i.e. the count of new contacts
}
// Note: we can pass in a const array ... since here,
// we are just printing out values ... (i.e. no changes)
void showBook( const MyContacts book[], const int num )
{
if( num < 1 ) return;
cout << "\nYour 'book' has room for " << MAX_NUM - num
<< " more contacts...\n\n";
int i;
for( i = 0; i < num; ++i )
{ // 26 char's total width for each, so have just 3*26=78 char's on a line
cout << right << "[" << setw(2) << i+1 <<"] "
<< left << setw(20) << book[i].thePhone + " " + book[i].theName
<< " "; // Note: 5 + 20 + 1 = 26 char's
if( (i+1) % 3 == 0 ) cout << endl; // 3 on a line ...
}
if( i % 3 ) cout << endl; // i.e. if (the above) i+1 = 1 or 2 ...
}
// uses global variable MY_FILE
int fileBook( const MyContacts book[], const int num )
{
ofstream fout( MY_FILE );
if( ! fout ) return -1; // to signal error condition ...
int i;
for( i = 0; i < num; ++i )
{
fout << book[i].theName << endl
<< book[i].thePhone << endl;
}
fout.close();
return i;
}
// uses global variable MY_FILE ... recall C/C++ arrays are 'passed by ref.'
int loadBook( MyContacts book[], const int max_num )
{
ifstream fin( MY_FILE ); // open an istream stream to the file
if( !fin ) return -1; // to signal error condition ...
int i = 0;
while // here we fill the array from the file ...
(
i < max_num && // upto the max size of the array
getline(fin, book[i].theName) &&
getline(fin, book[i].thePhone)
)
++i;
fin.close(); // close the input file, i now holds the count of records read
return i; // return the number of records read into the array ...
}
int main()
{
// at compile time, the compiler knows 'MAX_NUM',
// so can reserve the requested memory ... for ...
MyContacts myBook[ MAX_NUM ]; // an array with MAX_NUM of MyContacts
// update from file ... if file exits ... if any records there
int numContacts = loadBook( myBook, MAX_NUM );
if( numContacts >= 0 )
{
cout << "The number of records in memory now is " << numContacts;
showBook( myBook, numContacts );
}
else
{
cout << "The file " << MY_FILE << " could not be opened ... "
<< "Perhaps it doesn't exist yet?" << endl;
numContacts = 0; // reset to zero (from -1 error value returned above)
}
int choice, numFiled, reply;
do
{
cout << endl << MENU << flush;
choice = cin.get();
cin.sync(); // 'flush' cin stream ...
switch( choice )
{
case '1' : // updateBook returns the number of contacts ...
numContacts = updateBook( myBook, numContacts, MAX_NUM );
break;
case '2' : // showBook
showBook( myBook, numContacts );
break;
case '3' : // fileBook
if( numContacts > 0 )
{
numFiled = fileBook( myBook, numContacts );
if( numFiled == numContacts)
cout << "All " << numContacts << " contacts were filed ok ..."
<< endl;
else
cout << "File error ... Only " << numFiled << " of "
<< numContacts << " filed." << endl;
}
else
{
cout << "Do you really want to write an EMPTY file (y/n) ? "
<< flush;
reply = cin.get();
cin.sync(); // flush cin stream ...
if( reply == 'y' || reply == 'Y' )
{
numFiled = fileBook( myBook, 0 );
if( numFiled == 0 )
cout << "File " << MY_FILE << " now empty." << endl;
if( numFiled == numContacts)
cout << "All " << numContacts
<< " contacts were filed ok ..." << endl;
else cout << "Error writing to file " << MY_FILE << endl;
}
else cout << "Ok ... aborted writing an empty file." << endl;
}
break;
case '4' : // loadBook from file into memory ...
if( numContacts > 0 )
{
cout << "Do you want to over-write the " << numContacts
<< " in memory (y/n) ? " << flush;
reply = toupper( cin.get() );
cin.sync();
if( reply == 'Y' )
{
numContacts = loadBook( myBook, MAX_NUM );
cout << numContacts << " records were loaded into memory ..."
<< endl;
}
else cout << "Ok ... over-write aborted ..."
<< endl;
}
else
{
numContacts = loadBook( myBook, MAX_NUM );
if( numContacts >= 0 )
cout << numContacts << " records were loaded into memory ..."
<< endl;
else
{
numContacts = 0; // reset to zero
cout << "The file " << MY_FILE << " could not be opened ..."
<< " Perhaps it doesn't exist yet?" << endl;
}
}
break;
case '5' : // set memory record counter to zero to allow over-writes
if( numContacts > 0 )
{
cout << "Do you want to ignore " << numContacts
<< " in memory (y/n) ? " << flush;
reply = toupper( cin.get() );
cin.sync();
if( reply == 'Y' )
{
numContacts = 0;
cout << numContacts << " records now in memory ..." << endl;
}
else cout << "Ok ... memory 'ignore' aborted ..." << endl;
}
break;
case '0' :
break;
default : cout << "Not implemented yet ..." << endl;
}
}while( choice != '0' );
}
// editContacts.cpp
// Chapter 15:
// The edit function is added here ... Also note the use of a C++ vector
// container, (similar to an array), to hold each struct of 'MyContacts' (and...
// note the few changes in converting from an array to a STL vector container.)
// We will use push_back ... so our vector of struct's can grow to be as big
// as available RAM ...
// Note: a global boolean variable 'FILE_CHANGES' is used to track file-updates
// Eventually ...
// the Computer updates (edits, deletes, sorts, chops-duplicates-in) its files
// (Actually ... we are preventing duplicate entries of phone numbers on input here, to demo how.)
#include <iostream>
#include <iomanip> // for formatting cout output here ...
#include <fstream>
#include <sstream> // for stringstream conversions
#include <string>
#include <vector> // to hold each struct of 'MyContacts'
#include <cctype> // for isdigit, toupper
// globals ...
using namespace std;
const char MY_FILE[] = "myRecords.dat";
const string indent(14, ' '); // construct string 'indent' with 14 space char's
const string MENU = indent + "1. A dd new contacts\n" +
indent + "2. V iew book\n" +
indent + "3. E dit book\n" +
indent + "4. F ile book\n" +
indent + "5. L oad book from file\n" +
indent + "6. I nitial memory\n" +
indent + "0. Q uit\n" +
"Your choice : ";
// a global variable to flag file updates of any changes ... before exiting
bool FILE_CHANGES = false;
struct MyContacts // a 'struct' may be used for a C/C++ style 'data record' ...
{
string theName;
string thePhone;
}; // Note: semi-colon here tells compiler we have reached the end of 'struct'
// forward function declarations / function prototypes ...
string takeIn( const string& message );
bool isValidPhone( const string& pNum );
int existPhone( const string& pNum, const vector < MyContacts >& v );
int addBook( vector < MyContacts >& book );
void viewByPhone( int index, vector < MyContacts >& book );
void viewBook( const vector < MyContacts >& v );
void editBook( vector < MyContacts >& v );
int fileBook( const vector < MyContacts >& v );
int loadBook( vector < MyContacts>& v );
int main()
{
// construct an empty vector to hold each struct of 'MyContacts'
// the number of records is available via a call to myBook.size() ... now 0
vector < MyContacts > myBook;
// update from file ... if file exits ... if any records there
int numContacts = loadBook( myBook );
if( numContacts >= 0 )
{
cout << "The number of records in memory now is " << numContacts
<< " ... \n\n";
viewBook( myBook );
}
else
{
cout << "The file " << MY_FILE << " could not be opened ... "
<< "Perhaps it doesn't exist yet?" << endl;
}
int choice, numFiled, reply;
do
{
cout << endl << MENU << flush;
choice = toupper( cin.get() );
cin.sync(); // 'flush' cin stream ...
switch( choice )
{
case '1' : case 'A' : // addBook returns the number of contacts ...
numContacts = addBook( myBook );
break;
case '2' : case 'V' : // viewBook
viewBook( myBook );
break;
case '3' : case 'E' : // editBook
editBook( myBook );
break;
case '4' : case 'F' : // fileBook
if( numContacts > 0 )
{
numFiled = fileBook( myBook );
if( numFiled == numContacts )
{
cout << "All " << numContacts << " contacts were filed ok ..."
<< endl;
FILE_CHANGES = false; // update global file flag ...
}
else
cout << "File error ... Only " << numFiled << " of "
<< numContacts << " filed." << endl;
}
else
{
cout << "Do you really want to write an EMPTY file (y/n) ? "
<< flush;
reply = cin.get();
cin.sync(); // flush cin stream ...
if( reply == 'y' || reply == 'Y' )
{
numFiled = fileBook( myBook );
if( numFiled == 0 )
cout << "File " << MY_FILE << " now empty." << endl;
if( numFiled == numContacts)
{
cout << "All " << numContacts
<< " contacts were filed ok ..." << endl;
FILE_CHANGES = false; // update global file flag
}
else cout << "Error writing to file " << MY_FILE << endl;
}
else cout << "Ok ... aborted writing an empty file." << endl;
}
break;
case '5' : case 'L' : // loadBook from file into memory ...
if( numContacts > 0 )
{
cout << "Do you want to over-write the " << numContacts
<< " in memory (y/n) ? " << flush;
reply = toupper( cin.get() );
cin.sync();
if( reply == 'Y' )
{
myBook.clear(); // re-set myBook to the empty vector
numContacts = loadBook( myBook);
cout << numContacts << " records were loaded into memory ..."
<< endl;
FILE_CHANGES = false; // update flag ...
}
else cout << "Ok ... over-write aborted ..."
<< endl;
}
else // numContacts == 0 to start ...
{
numContacts = loadBook( myBook ); // so load from file ...
if( numContacts >= 0 )
{
cout << numContacts << " records were loaded into memory ..."
<< endl;
FILE_CHANGES = false; // update file flag ...
}
else
{
numContacts = 0; // reset to zero (from -1 set above)
cout << "The file " << MY_FILE << " could not be opened ..."
<< " Perhaps it doesn't exist yet?" << endl;
}
}
break;
case '6' : case 'I' : // set memory counter to zero for over-writes
if( numContacts > 0 )
{
cout << "Do you want to ignore " << numContacts
<< " in memory (y/n) ? " << flush;
reply = toupper( cin.get() );
cin.sync();
if( reply == 'Y' )
{
myBook.clear(); // re-set myBook to the empty vector
numContacts = 0;
FILE_CHANGES = true; // update file flag
cout << numContacts << " records now in memory ..." << endl;
}
else cout << "Ok ... memory 'ignore' aborted ..." << endl;
}
break;
case '0' : case 'Q' :
if( FILE_CHANGES )
{
cout << "Do you want to update the file with the "
<< numContacts << " records in memory (y/n) ? " << flush;
reply = toupper( cin.get() );
cin.sync();
if( reply == 'Y' )
{
numFiled = fileBook( myBook );
if( numFiled == numContacts )
{
cout << "All " << numContacts << " contacts were filed ok ..."
<< endl;
// FILE_CHANGES = false; // update global file flag
}
else
cout << "File error ... Only " << numFiled << " of "
<< numContacts << " filed." << endl;
}
else cout << "Ok ... file update aborted ..." << endl;
}
cout << "Exit program (y/n) ? ";
reply = toupper( cin.get() );
cin.sync();
if( reply == 'Y' )
{
return 0;
}
cout << "Ok ... 'Exit program' aborted ..." << endl;
choice = 'a'; // to abort exit at end of do{...}while(...)
break;
default : cout << "Not implemented yet ..." << endl;
}
}while( choice != '0' );
}
// prompts for input via the passed in 'message'
// and returns the string that the user entered ...
string takeIn( const string& message )
{
string tmpStr;
cout << message << ": " << flush;
getline( cin, tmpStr );
return tmpStr;
}
// validate that the phone number is a 10 digit string like: 1234567890
// and to save making a local copy can pass in the C++ string by 'const ref'
bool isValidPhone( const string& pNum )
{
if( pNum.length() != 10 )
{
cout << "\nError: Phone number must have 10 digits.\n";
return false;
}
for( int j = 0; j<10; ++ j )
{
if( !isdigit( pNum[j] ) )
{
cout << "\nError: Integers only for Phone number.\n";
return false; // break out if this for loop right now ...
}
}
// if reach here ...
return true;
}
int existPhone( const string& pNum, const vector < MyContacts >& v )
{
for( unsigned i = 0; i < v.size(); ++ i)
if( v[i].thePhone == pNum ) return i;
// else if reach here ...
return -1; // as flag that doesn't exist
}
// the number of contacts in the book is returned ...
int addBook( vector < MyContacts >& book )
{
string reply;
bool more = true;
int i = book.size();
MyContacts mcTmp;
while( more )
{
stringstream ss;
ss << "[" << i << "] ";
string tmpStr = ss.str(); // convert stringstream 'ss' to string 'tmpStr'
// note C++ string 'tmpStr' is in the middle, so we can concatenate here
mcTmp.theName = takeIn( "Name"+tmpStr+"(or press 'Enter' to exit) " );
if( mcTmp.theName.length() == 0 ) return i; // 0 len, so exit function
mcTmp.thePhone = takeIn( "Phone number"+tmpStr+"... all 10 digits " );
if( !isValidPhone(mcTmp.thePhone) ) continue; // from top of while now
if( existPhone(mcTmp.thePhone, book) > -1 )
{
cout << "That number is used ...\n";
continue;
}
cout << "Ok ... (y/n) ? " << flush;
getline( cin, reply );
if( !( reply[0] == 'y' || reply[0] == 'Y') ) continue; // at top 'while
book.push_back( mcTmp ); // ok ... add this record to the end of vector
++i; // since reached here, data accepted above, so increment counter
FILE_CHANGES = true; // update global variable
cout << "More ... (y/n) ? " << flush; // defaults to yes (i.e. 'true')
getline( cin, reply );
more = !( reply[0] == 'n' || reply[0] == 'N' );
}// end while ...
return i; // i.e. the count of new contacts
}
void viewByPhone( int index, vector < MyContacts >& book )
{
cout << right << book[index].thePhone + " " + book[index].theName << endl;
}
// Note: we can pass in a const vector by ref ... since here,
// we are just printing out values ... (i.e. no changes)
void viewBook( const vector < MyContacts >& v )
{
if( v.size() == 0 ) return;
int i;
for( i = 0; i < v.size(); ++i )
{ // 39 char's total width for each, so have just 2*39=78 char's on a line
cout << right << "[" << setw(2) << i+1 <<"] "
<< left << setw(33) << v[i].thePhone + " " + v[i].theName
<< " "; // Note: 5 + 33 + 1 = 39 char's
if( (i+1) % 2 == 0 ) cout << endl; // 2 on a line ...
}
if( i % 2 ) cout << endl; // i.e. if (the above) i+1 = 1 ...
}
void editBook( vector < MyContacts >& v )
{
cout << "Enter phone number of contact to edit: " << flush;
string pNumStr;
getline( cin, pNumStr );
if( !isValidPhone( pNumStr ) )
{
cout << "Invalid! ... Valid numbers are 10 digits ..." << endl;
return;
}
int i;
if( (i = existPhone( pNumStr, v )) < 0 )
{
cout << "That number is not here ..." << endl;
return;
}
// ok we reached here ... so take in name
viewByPhone( i, v );
cout << "\nEdit this one ... (y/n) ? " << flush;
int reply = toupper( cin.get() );
cin.sync();
if( !(reply == 'Y') ) { cout << "Edit aborted ...\n"; return; }
// ok we reached here ... so ...
cout << "Enter edited name : ";
string nameStr, phoneStr;
getline( cin, nameStr );
do
{
cout << "Enter edited phone : ";
getline( cin, phoneStr );
}while( !isValidPhone( phoneStr ) && (existPhone(phoneStr, v) && phoneStr !=pNumStr ) );
cout << "Ok to update with " << phoneStr << " " << nameStr << " (y/n) ? "
<< flush;
reply = toupper( cin.get() );
cin.sync();
if( reply == 'Y' )
{
v[i].theName = nameStr;
v[i].thePhone = phoneStr;
cout << "Updated ...\n";
FILE_CHANGES = true; // update global file flag
}
else cout << "Edit aborted ...\n";
}
// uses global variable MY_FILE
int fileBook( const vector < MyContacts >& v )
{
ofstream fout( MY_FILE );
if( ! fout ) return -1; // to signal error condition ...
int i;
for( i = 0; i < v.size(); ++i )
{
fout << v[i].theName << endl
<< v[i].thePhone << endl;
}
fout.close();
FILE_CHANGES = false; // update global file flag ...
return i;
}
// uses global variable MY_FILE ... Note: vector is 'passed in/back by ref.'
int loadBook( vector < MyContacts>& v )
{
ifstream fin( MY_FILE ); // open an istream stream to the file
if( !fin ) return -1; // to signal error condition ...
int i = 0;
MyContacts mcTmp; // get a 'temp' struct to hold each new record ...
while // here we fill the array from the file ...
(
getline(fin, mcTmp.theName) &&
getline(fin, mcTmp.thePhone)
)
{
++i;
v.push_back( mcTmp ); // add each new record to the end of the vector
}
fin.close(); // close the input file, i now holds the count of records read
return i; // return the number of records read into the vector
}
// sortContacts.cpp
// Chapter 15:
// The STL sort function is added here ...
#include <iostream>
#include <iomanip> // for formatting cout output here ...
#include <fstream>
#include <sstream> // for stringstream conversions
#include <string>
#include <vector> // to hold each struct of 'MyContacts'
#include <cctype> // for isdigit, toupper
#include <algorithm> // for sorting a vector container ...
// globals ...
using namespace std;
const char MY_FILE[] = "myRecords.dat";
const string indent(14, ' '); // construct string 'indent' with 14 space char's
const string MENU = indent + "1. A dd new contacts\n" +
indent + "2. V iew book\n" +
indent + "3. E dit book\n" +
indent + "4. S ort book\n" +
indent + "5. F ile book\n" +
indent + "6. L oad book from file\n" +
indent + "7. I nitial memory\n" +
indent + "0. Q uit\n" +
"Your choice : ";
// a global variable to flag file updates of any changes ... before exiting
bool FILE_CHANGES = false;
struct MyContacts // a 'struct' may be used for a C/C++ style 'data record' ...
{
string theName;
string thePhone;
}; // Note: semi-colon here tells compiler we have reached the end of 'struct'
// forward function declarations / function prototypes ...
string takeIn( const string& message );
bool isValidPhone( const string& pNum );
int existPhone( const string& pNum, const vector < MyContacts >& v );
int addBook( vector < MyContacts >& book );
void viewByPhone( int index, vector < MyContacts >& book );
void viewBook( const vector < MyContacts >& v );
void editBook( vector < MyContacts >& v );
bool compare_nocaseName(const MyContacts& first, const MyContacts& second);
bool compare_phone(const MyContacts& first, const MyContacts& second);
int fileBook( const vector < MyContacts >& v );
int loadBook( vector < MyContacts>& v );
int main()
{
// construct an empty vector to hold each struct of 'MyContacts'
// the number of records is available via a call to myBook.size() ... now 0
vector < MyContacts > myBook;
// update from file ... if file exits ... if any records there
int numContacts = loadBook( myBook );
if( numContacts >= 0 )
{
cout << "The number of records in memory now is " << numContacts
<< " ... \n\n";
viewBook( myBook );
}
else
{
cout << "The file " << MY_FILE << " could not be opened ... "
<< "Perhaps it doesn't exist yet?" << endl;
}
int choice, numFiled, reply;
do
{
cout << endl << MENU << flush;
choice = toupper( cin.get() );
cin.sync(); // 'flush' cin stream ...
switch( choice )
{
case '1' : case 'A' : // addBook returns the number of contacts ...
numContacts = addBook( myBook );
break;
case '2' : case 'V' : // viewBook
viewBook( myBook );
break;
case '3' : case 'E' : // editBook
editBook( myBook );
break;
case '4' : case 'S' : // sort ...
cout << "Sort by name or phone (n/p) ? " << flush;
reply = toupper( cin.get() );
cin.sync(); // flush cin stream ...
if( reply == 'P' )
{
sort(myBook.begin(), myBook.end(), compare_phone);
cout << "Now sorted by phone numbers ...\n";
FILE_CHANGES = true;
}
else if( reply == 'N' )
{
sort(myBook.begin(), myBook.end(), compare_nocaseName);
FILE_CHANGES = true;
cout << "Now sorted by names ...\n";
}
else cout << "Not sorted ...\n";
break;
case '5' : case 'F' : // fileBook
if( numContacts > 0 )
{
numFiled = fileBook( myBook );
if( numFiled == numContacts )
{
cout << "All " << numContacts << " contacts were filed ok ..."
<< endl;
FILE_CHANGES = false; // update global file flag ...
}
else
cout << "File error ... Only " << numFiled << " of "
<< numContacts << " filed." << endl;
}
else
{
cout << "Do you really want to write an EMPTY file (y/n) ? "
<< flush;
reply = cin.get();
cin.sync(); // flush cin stream ...
if( reply == 'y' || reply == 'Y' )
{
numFiled = fileBook( myBook );
if( numFiled == 0 )
cout << "File " << MY_FILE << " now empty." << endl;
if( numFiled == numContacts)
{
cout << "All " << numContacts
<< " contacts were filed ok ..." << endl;
FILE_CHANGES = false; // update global file flag
}
else cout << "Error writing to file " << MY_FILE << endl;
}
else cout << "Ok ... aborted writing an empty file." << endl;
}
break;
case '6' : case 'L' : // loadBook from file into memory ...
if( numContacts > 0 )
{
cout << "Do you want to over-write the " << numContacts
<< " in memory (y/n) ? " << flush;
reply = toupper( cin.get() );
cin.sync();
if( reply == 'Y' )
{
myBook.clear(); // re-set myBook to the empty vector
numContacts = loadBook( myBook);
cout << numContacts << " records were loaded into memory ..."
<< endl;
FILE_CHANGES = false; // update flag ...
}
else cout << "Ok ... over-write aborted ..."
<< endl;
}
else // numContacts == 0 to start ...
{
numContacts = loadBook( myBook ); // so load from file ...
if( numContacts >= 0 )
{
cout << numContacts << " records were loaded into memory ..."
<< endl;
FILE_CHANGES = false; // update file flag ...
}
else
{
numContacts = 0; // reset to zero (from -1 set above)
cout << "The file " << MY_FILE << " could not be opened ..."
<< " Perhaps it doesn't exist yet?" << endl;
}
}
break;
case '7' : case 'I' : // set memory counter to zero for over-writes
if( numContacts > 0 )
{
cout << "Do you want to ignore " << numContacts
<< " in memory (y/n) ? " << flush;
reply = toupper( cin.get() );
cin.sync();
if( reply == 'Y' )
{
myBook.clear(); // re-set myBook to the empty vector
numContacts = 0;
FILE_CHANGES = true; // update file flag
cout << numContacts << " records now in memory ..." << endl;
}
else cout << "Ok ... memory 'ignore' aborted ..." << endl;
}
break;
case '0' : case 'Q' :
if( FILE_CHANGES )
{
cout << "Do you want to update the file with the "
<< numContacts << " records in memory (y/n) ? " << flush;
reply = toupper( cin.get() );
cin.sync();
if( reply == 'Y' )
{
numFiled = fileBook( myBook );
if( numFiled == numContacts )
{
cout << "All " << numContacts << " contacts were filed ok ..."
<< endl;
// FILE_CHANGES = false; // update global file flag
}
else
cout << "File error ... Only " << numFiled << " of "
<< numContacts << " filed." << endl;
}
else cout << "Ok ... file update aborted ..." << endl;
}
cout << "Exit program (y/n) ? ";
reply = toupper( cin.get() );
cin.sync();
if( reply == 'Y' )
{
return 0;
}
cout << "Ok ... 'Exit program' aborted ..." << endl;
choice = 'a'; // to abort exit at end of do{...}while(...)
break;
default : cout << "Not implemented yet ..." << endl;
}
}while( choice != '0' );
}
// prompts for input via the passed in 'message'
// and returns the string that the user entered ...
string takeIn( const string& message )
{
string tmpStr;
cout << message << ": " << flush;
getline( cin, tmpStr );
return tmpStr;
}
// validate that the phone number is a 10 digit string like: 1234567890
// and to save making a local copy can pass in the C++ string by 'const ref'
bool isValidPhone( const string& pNum )
{
if( pNum.length() != 10 )
{
cout << "\nError: Phone number must have 10 digits.\n";
return false;
}
for( int j = 0; j<10; ++ j )
{
if( !isdigit( pNum[j] ) )
{
cout << "\nError: Integers only for Phone number.\n";
return false; // break out if this for loop right now ...
}
}
// if reach here ...
return true;
}
// returns the index, if it exists ... or -1 if not exists ...
int existPhone( const string& pNum, const vector < MyContacts >& v )
{
for( unsigned i = 0; i < v.size(); ++ i)
if( v[i].thePhone == pNum ) return i;
// else if reach here ...
return -1; // as flag that doesn't exist
}
// the number of contacts in the book is returned ...
int addBook( vector < MyContacts >& book )
{
string reply;
bool more = true;
int i = book.size();
MyContacts mcTmp;
while( more )
{
stringstream ss;
ss << "[" << i << "] ";
string tmpStr = ss.str(); // convert stringstream 'ss' to string 'tmpStr'
// note C++ string 'tmpStr' is in the middle, so we can concatenate here
mcTmp.theName = takeIn( "Name"+tmpStr+"(or press 'Enter' to exit) " );
if( mcTmp.theName.length() == 0 ) return i; // 0 len, so exit function
mcTmp.thePhone = takeIn( "Phone number"+tmpStr+"... all 10 digits " );
if( !isValidPhone(mcTmp.thePhone) ) continue; // from top of while now
if( existPhone(mcTmp.thePhone, book) > -1 )
{
cout << "That number is used ...\n";
continue;
}
cout << "Ok ... (y/n) ? " << flush;
getline( cin, reply );
if( !( reply[0] == 'y' || reply[0] == 'Y') ) continue; // at top 'while
book.push_back( mcTmp ); // ok ... add this record to the end of vector
++i; // since reached here, data accepted above, so increment counter
FILE_CHANGES = true; // update global variable
cout << "More ... (y/n) ? " << flush; // defaults to yes (i.e. 'true')
getline( cin, reply );
more = !( reply[0] == 'n' || reply[0] == 'N' );
}// end while ...
return i; // i.e. the count of new contacts
}
// a valid index must be passed in ...
void viewByPhone( int index, vector < MyContacts >& book )
{
//cout << right << book[index].thePhone + " " + book[index].theName << endl;
cout << right << book.at(index).thePhone + " " + book.at(index).theName
<< endl; // with bounds checking ...
}
// Note: we can pass in a const vector by ref ... since here,
// we are just printing out values ... (i.e. no changes)
void viewBook( const vector < MyContacts >& v )
{
if( v.size() == 0 )
{
cout << "The book is empty ...\n";
return;
}
int i;
for( i = 0; i < v.size(); ++i )
{ // 39 char's total width for each, so have just 2*39=78 char's on a line
cout << right << "[" << setw(2) << i+1 <<"] "
<< left << setw(33) << v[i].thePhone + " " + v[i].theName
<< " "; // Note: 5 + 33 + 1 = 39 char's
if( (i+1) % 2 == 0 ) cout << endl; // 2 on a line ...
}
if( i % 2 ) cout << endl; // i.e. if (the above) i+1 = 1 ...
}
void editBook( vector < MyContacts >& v )
{
cout << "Enter phone number of contact to edit: " << flush;
string pNumStr;
getline( cin, pNumStr );
if( !isValidPhone( pNumStr ) )
{
cout << "Invalid! ... Valid numbers are 10 digits ..." << endl;
return;
}
int i;
if( (i = existPhone( pNumStr, v )) < 0 )
{
cout << "That number is not here ..." << endl;
return;
}
// ok we reached here ... so take in name
viewByPhone( i, v );
cout << "\nEdit this one ... (y/n) ? " << flush;
int reply = toupper( cin.get() );
cin.sync();
if( !(reply == 'Y') ) { cout << "Edit aborted ...\n"; return; }
// ok we reached here ... so ...
cout << "Enter edited name : ";
string nameStr, phoneStr;
getline( cin, nameStr );
do
{
cout << "Enter edited phone : ";
getline( cin, phoneStr );
}while( !isValidPhone( phoneStr ) && (existPhone(phoneStr, v) && phoneStr !=pNumStr ) );
cout << "Ok to update with " << phoneStr << " " << nameStr << " (y/n) ? "
<< flush;
reply = toupper( cin.get() );
cin.sync();
if( reply == 'Y' )
{
v[i].theName = nameStr;
v[i].thePhone = phoneStr;
cout << "Updated ...\n";
FILE_CHANGES = true; // update global file flag
}
else cout << "Edit aborted ...\n";
}
// uses global variable MY_FILE
int fileBook( const vector < MyContacts >& v )
{
ofstream fout( MY_FILE );
if( ! fout ) return -1; // to signal error condition ...
int i;
for( i = 0; i < v.size(); ++i )
{
fout << v[i].theName << endl
<< v[i].thePhone << endl;
}
fout.close();
FILE_CHANGES = false; // update global file flag ...
return i;
}
// uses global variable MY_FILE ... Note: vector is 'passed in/back by ref.'
int loadBook( vector < MyContacts>& v )
{
ifstream fin( MY_FILE ); // open an istream stream to the file
if( !fin ) return -1; // to signal error condition ...
int i = 0;
MyContacts mcTmp; // get a 'temp' struct to hold each new record ...
while // here we fill the array from the file ...
(
getline(fin, mcTmp.theName) &&
getline(fin, mcTmp.thePhone)
)
{
++i;
v.push_back( mcTmp ); // add each new record to the end of the vector
}
fin.close(); // close the input file, i now holds the count of records read
return i; // return the number of records read into the vector
}
// name comparison here is NOT case sensitive ...
bool compare_nocaseName(const MyContacts& first, const MyContacts& second)
{
unsigned int i=0;
while( i<first.theName.length() && i<second.theName.length() )
{
if( tolower(first.theName[i]) < tolower(second.theName[i]) ) return true;
else if( tolower(first.theName[i]) > tolower(second.theName[i]) ) return false;
++i;
}
if( first.theName.length() < second.theName.length() ) return true;
else if( first.theName.length() > second.theName.length() ) return false;
else return first.thePhone < second.thePhone;
}
bool compare_phone(const MyContacts& first, const MyContacts& second)
{
return first.thePhone < second.thePhone;
}
// deleteContacts.cpp
// Chapter 15:
// The STL list delete function is added here ...
// Note we have switched from a STL vector conatiner to a STL list container ...
// to allow easy deletes ...
// Note the use of iterators like 'it' and the syntax: it->theName, it->thePhone
#include <iostream>
#include <iomanip> // for formatting cout output here ...
#include <fstream>
#include <sstream> // for stringstream conversions
#include <string>
#include <list> // to hold each struct of 'MyContacts'
#include <cctype> // for isdigit, toupper
// globals ...
using namespace std;
const char MY_FILE[] = "myRecords.dat";
const string indent(14, ' '); // construct string 'indent' with 14 space char's
const string MENU = indent + "1. A dd new contacts\n" +
indent + "2. V iew contacts in the book\n" +
indent + "3. E dit/D elete a contact in the book\n" +
indent + "4. S ort book\n" +
indent + "5. F ile book\n" +
indent + "6. L oad book from file\n" +
indent + "7. I nitial memory\n" +
indent + "0. Q uit\n" +
"Your choice : ";
// a global variable to flag file updates of any changes ... before exiting
bool FILE_CHANGES = false;
struct MyContacts // a 'struct' may be used for a C/C++ style 'data record' ...
{ // constructor ...
MyContacts(string name, string phone) : theName(name), thePhone(phone) {}
string theName;
string thePhone;
}; // Note: semi-colon here tells compiler we have reached the end of 'struct'
// forward function declarations / function prototypes ...
string takeIn( const string& message );
bool isValidPhone( const string& pNum );
// returns a valid iterator to phone# if exits in list ... otherwise returns NULL
list< MyContacts >::iterator existPhone( const string& pNum, list< MyContacts >& book );
int addBook( list < MyContacts >& book );
void viewByPhone( const list< MyContacts >::iterator it );
void viewBook( const list < MyContacts >& v );
void editBook( list < MyContacts >& v );
bool compare_nocaseName(const MyContacts& first, const MyContacts& second);
bool compare_phone(const MyContacts& first, const MyContacts& second);
int fileBook( const list < MyContacts >& v );
int loadBook( list < MyContacts>& v );
int main()
{
// construct an empty list to hold each struct of 'MyContacts'
// the number of records is available via a call to myBook.size() ... now 0
list < MyContacts > myBook;
// update from file ... if file exits ... if any records there
int numContacts = loadBook( myBook );
if( numContacts >= 0 )
{
cout << "The number of records in memory now is " << numContacts
<< " ... \n\n";
viewBook( myBook );
}
else
{
cout << "The file " << MY_FILE << " could not be opened ... "
<< "Perhaps it doesn't exist yet?" << endl;
}
int choice, numFiled, reply;
do
{
cout << endl << MENU << flush;
choice = toupper( cin.get() );
cin.sync(); // 'flush' cin stream ...
switch( choice )
{
case '1' : case 'A' : // addBook returns the number of contacts ...
numContacts = addBook( myBook );
break;
case '2' : case 'V' : // viewBook
viewBook( myBook );
break;
case '3' : case 'E' : case 'D' : // edit/delete a contact ...
editBook( myBook );
numContacts = myBook.size(); // update in case of deletes ...
break;
case '4' : case 'S' : // sort ...
cout << "Sort by name or phone (n/p) ? " << flush;
reply = toupper( cin.get() );
cin.sync(); // flush cin stream ...
if( reply == 'P' )
{
myBook.sort(compare_phone);
cout << "Now sorted by phone numbers ...\n";
FILE_CHANGES = true;
}
else if( reply == 'N' )
{
myBook.sort(compare_nocaseName);
FILE_CHANGES = true;
cout << "Now sorted by names ...\n";
}
else cout << "Not sorted ...\n";
break;
case '5' : case 'F' : // fileBook
if( numContacts > 0 )
{
numFiled = fileBook( myBook );
if( numFiled == numContacts )
{
cout << "All " << numContacts << " contacts were filed ok ..."
<< endl;
FILE_CHANGES = false; // update global file flag ...
}
else
cout << "File error ... Only " << numFiled << " of "
<< numContacts << " filed." << endl;
}
else
{
cout << "Do you really want to write an EMPTY file (y/n) ? "
<< flush;
reply = cin.get();
cin.sync(); // flush cin stream ...
if( reply == 'y' || reply == 'Y' )
{
numFiled = fileBook( myBook );
if( numFiled == 0 )
cout << "File " << MY_FILE << " now empty." << endl;
if( numFiled == numContacts)
{
cout << "All " << numContacts
<< " contacts were filed ok ..." << endl;
FILE_CHANGES = false; // update global file flag
}
else cout << "Error writing to file " << MY_FILE << endl;
}
else cout << "Ok ... aborted writing an empty file." << endl;
}
break;
case '6' : case 'L' : // loadBook from file into memory ...
if( numContacts > 0 )
{
cout << "Do you want to over-write the " << numContacts
<< " in memory (y/n) ? " << flush;
reply = toupper( cin.get() );
cin.sync();
if( reply == 'Y' )
{
list <MyContacts> tmp; // contruct an empty list
myBook = tmp; // re-set myBook to the empty list
numContacts = loadBook( myBook);
cout << numContacts << " records were loaded into memory ..."
<< endl;
FILE_CHANGES = false; // update flag ...
}
else cout << "Ok ... over-write aborted ..."
<< endl;
}
else // numContacts == 0 to start ...
{
numContacts = loadBook( myBook ); // so load from file ...
if( numContacts >= 0 )
{
cout << numContacts << " records were loaded into memory ..."
<< endl;
FILE_CHANGES = false; // update file flag ...
}
else
{
numContacts = 0; // reset to zero (from -1 set above)
cout << "The file " << MY_FILE << " could not be opened ..."
<< " Perhaps it doesn't exist yet?" << endl;
}
}
break;
case '7' : case 'I' : // set memory counter to zero for over-writes
if( numContacts > 0 )
{
cout << "Do you want to ignore " << numContacts
<< " in memory (y/n) ? " << flush;
reply = toupper( cin.get() );
cin.sync();
if( reply == 'Y' )
{
list <MyContacts> tmp; // contruct an empty list
myBook = tmp; // re-set myBook to the empty list
numContacts = 0;
FILE_CHANGES = true; // update file flag
cout << numContacts << " records now in memory ..." << endl;
}
else cout << "Ok ... memory 'ignore' aborted ..." << endl;
}
break;
case '0' : case 'Q' :
if( FILE_CHANGES )
{
cout << "Do you want to update the file with the "
<< numContacts << " records in memory (y/n) ? " << flush;
reply = toupper( cin.get() );
cin.sync();
if( reply == 'Y' )
{
numFiled = fileBook( myBook );
if( numFiled == numContacts )
{
cout << "All " << numContacts << " contacts were filed ok ..."
<< endl;
// FILE_CHANGES = false; // update global file flag
}
else
cout << "File error ... Only " << numFiled << " of "
<< numContacts << " filed." << endl;
}
else cout << "Ok ... file update aborted ..." << endl;
}
cout << "Exit program (y/n) ? ";
reply = toupper( cin.get() );
cin.sync();
if( reply == 'Y' )
{
return 0;
}
cout << "Ok ... 'Exit program' aborted ..." << endl;
choice = 'a'; // to abort exit at end of do{...}while(...)
break;
default : cout << "Not implemented yet ..." << endl;
}
}while( choice != '0' );
}
// prompts for input via the passed in 'message'
// and returns the string that the user entered ...
string takeIn( const string& message )
{
string tmpStr;
cout << message << ": " << flush;
getline( cin, tmpStr );
return tmpStr;
}
// validate that the phone number is a 10 digit string like: 1234567890
// and to save making a local copy can pass in the C++ string by 'const ref'
bool isValidPhone( const string& pNum )
{
if( pNum.length() != 10 )
{
cout << "\nError: Phone number must have 10 digits.\n";
return false;
}
for( int j = 0; j<10; ++ j )
{
if( !isdigit( pNum[j] ) )
{
cout << "\nError: Integers only for Phone number.\n";
return false; // break out if this for loop right now ...
}
}
// if reach here ...
return true;
}
// returns a valid iterator if ID is used already ... otherwise returns NULL
list< MyContacts >::iterator existPhone( const string& pNum, list< MyContacts >& book )
{
list< MyContacts >::iterator it;
for( it = book.begin(); it != book.end(); ++it )
{
if( it->thePhone == pNum )
return it;
}
return NULL;
}
// the number of contacts in the book is returned ...
// (and the updated list of MyContacts objects is returned by ref.)
int addBook( list < MyContacts >& book )
{
string reply;
bool more = true;
int i = book.size();
while( more )
{
stringstream ss;
ss << "[" << i+1 << "] ";
string tmpStr = ss.str(); // convert stringstream 'ss' to string 'tmpStr'
// note C++ string 'tmpStr' is in the middle, so we can concatenate here
string name = takeIn( "Name"+tmpStr+"(or press 'Enter' to exit) " );
if( name.length() == 0 ) return i; // 0 len, so exit function
string phone = takeIn( "Phone number"+tmpStr+"... all 10 digits " );
if( !isValidPhone(phone) ) continue; // from top of while now
if( existPhone(phone, book) != NULL )
{
cout << "That number is used ...\n";
continue;
}
cout << "Ok ... (y/n) ? " << flush;
getline( cin, reply );
if( !( reply[0] == 'y' || reply[0] == 'Y') ) continue; // at top 'while
book.push_back( MyContacts(name, phone) ); // ok ... add this record to the end of list
++i; // since reached here, data accepted above, so increment counter
FILE_CHANGES = true; // update global variable
cout << "More ... (y/n) ? " << flush; // defaults to yes (i.e. 'true')
getline( cin, reply );
more = !( reply[0] == 'n' || reply[0] == 'N' );
}// end while ...
return i; // i.e. the count of new contacts
}
void viewByPhone( const list< MyContacts >::iterator it )
{
cout << right << it->thePhone + " " + it->theName << endl;
}
// Note: we can pass in a const list by ref ... since here,
// we are just printing out values ... (i.e. no changes)
void viewBook( const list < MyContacts >& v )
{
if( v.size() == 0 )
{
cout << "The book is empty ...\n";
return;
}
int i=0;
list< MyContacts >::const_iterator it;
for( it =v.begin(); it != v.end(); it++, i++ )
{ // 39 char's total width for each, so have just 2*39=78 char's on a line
cout << right << "[" << setw(2) << i+1 <<"] "
<< left << setw(33) << it->thePhone + " " + it->theName
<< " "; // Note: 5 + 33 + 1 = 39 char's
if( (i+1) % 2 == 0 ) cout << endl; // 2 on a line ...
}
if( i % 2 ) cout << endl; // i.e. if (the above) i+1 = 1 ...
}
// uses gloabal variable FILE_CHANGES ...
void editBook( list < MyContacts >& v )
{
cout << "Enter phone number of contact to edit/delete: " << flush;
string pNumStr;
getline( cin, pNumStr );
if( !isValidPhone( pNumStr ) )
{
cout << "Invalid! ... Valid numbers are 10 digits ..." << endl;
return;
}
list< MyContacts >::iterator it;
if( (it = existPhone( pNumStr, v )) == NULL )
{
cout << "That number is not here ..." << endl;
return;
}
// ok we reached here ... so take in conatct ...
viewByPhone( it );
cout << "\nEdit/Delete this one ... (e/d) ? " << flush;
int reply = toupper( cin.get() );
cin.sync();
if( !(reply == 'E' || reply == 'D') )
{
cout << "Edit/Delete aborted ...\n";
return;
}
if(reply == 'D')
{
v.erase( it ); // Ok ... delete it ...
cout << "Contact deleted ...\n";
FILE_CHANGES = true; // update global file flag ...
return;
}
// ok we reached here ... so ...
cout << "Enter edited name : ";
string nameStr, phoneStr;
getline( cin, nameStr );
for( ;; )
{
cout << "Enter edited phone : ";
getline( cin, phoneStr );
if( !isValidPhone(phoneStr) )
{
cout << "Valid numbers are 10 digits ...\n";
continue; // loop to get a valid number ...
}
if(existPhone(phoneStr, v)!=NULL) // i.e. the number exits
{
if(phoneStr!=pNumStr) // see if it is other than the 'old number'
{
cout << "That phone number is used ...\n";
continue; // loop to get a good number ...
}
else break; // ok to use 'old' number ...
}
else break; // ok to use a new number that doesn't exist yet ...
}
cout << "Ok to update with " << phoneStr << " " << nameStr << " (y/n) ? "
<< flush;
reply = toupper( cin.get() );
cin.sync();
if( reply == 'Y' )
{
it->theName = nameStr;
it->thePhone = phoneStr;
cout << "Updated ...\n";
FILE_CHANGES = true; // update global file flag
}
else cout << "Edit aborted ...\n";
}
// uses global variable MY_FILE
int fileBook( const list < MyContacts >& v )
{
ofstream fout( MY_FILE );
if( ! fout ) return -1; // to signal error condition ...
int i;
list< MyContacts >::const_iterator it;
for( i = 0, it = v.begin(); it != v.end(); it++, i++ )
{
fout << it->theName << endl
<< it->thePhone << endl;
}
fout.close();
FILE_CHANGES = false; // update global file flag ...
return i;
}
// uses global variable MY_FILE ... Note: list is 'passed in/back by ref.'
int loadBook( list < MyContacts>& v )
{
ifstream fin( MY_FILE ); // open an istream stream to the file
if( !fin ) return -1; // to signal error condition ...
int i = 0;
string name, phone;
while // here we fill the array from the file ...
(
getline(fin, name) &&
getline(fin, phone)
)
{
++i;
v.push_back( MyContacts(name, phone) ); // add each new record to the end of the list
}
fin.close(); // close the input file, i now holds the count of records read
return i; // return the number of records read into the list
}
// name comparison here is NOT case sensitive ...
bool compare_nocaseName(const MyContacts& first, const MyContacts& second)
{
unsigned int i=0;
while( i<first.theName.length() && i<second.theName.length() )
{
if( tolower(first.theName[i]) < tolower(second.theName[i]) ) return true;
else if( tolower(first.theName[i]) > tolower(second.theName[i]) ) return false;
++i;
}
if( first.theName.length() < second.theName.length() ) return true;
else if( first.theName.length() > second.theName.length() ) return false;
else return first.thePhone < second.thePhone;
}
bool compare_phone(const MyContacts& first, const MyContacts& second)
{
return first.thePhone < second.thePhone;
}
// guessIt5
#include <iostream>
#include <cstdlib> // re. rand
#include <ctime> // re. time
using namespace std;
// This function prompts for input and returns only a valid integer
int getValid( char prompt[], int low, int high)
{
for( ;; )
{
cout << prompt << flush;
int tmp;
cin >> tmp;
if( !cin.good() )
{
cin.clear(); // in case error flags set ...
cin.sync(); // flush cin stream ...
cout << "Non integer entered ... ";
continue;
}
if( tmp < low || tmp > high )
{
cout << "Out of range " << low << ".." << high << " ... ";
cin.sync(); // flush cin stream ...
continue;
}
// else ... if reach here ...
cin.sync(); // flush cin stream ...
return tmp;
}
}
// Note: void function (i.e. procedure) playgame is the main game
// Note 2: the use of 'pass by reference' ...
void playgame( int& computerCents, int& playerCents )
{
cout << "THE COMPUTER will roll the dice AFTER\n"
<< "YOU ENTER a number in the RANGE 2..12\n";
int userNum = getValid("Your guess 2..12 : ", 2, 12);
// get two random numbers 1..6 for each die
int die1 = rand() % 6 + 1;
int die2 = rand() % 6 + 1;
// see if sum matches
if( die1 + die2 == userNum )
{
cout << "MATCH!\n"; // report success
playerCents += userNum; // player wins
computerCents -= userNum; // computer loses
}
else
{
cout << "NO match!\n"; // report failure
playerCents -= userNum; // player loses
computerCents += userNum; // computer wins
}
cout << "You entered " << userNum << endl
<< "And the computer rolled " << die1 << " & " << die2
<< " or " << die1 + die2 << "." << endl;
}
int main()
{
// initialize random seed
srand ( time(NULL) );
int cCents = getValid("Computer stakes 100..1000 (cents) : ", 100, 1000);
int cCentsInitial = cCents; // keep a copy
int pCents = getValid("Player stakes 100..1000 (cents) : ", 100, 1000);
int pCentsInitial = pCents;
cout << "\nThe computer staked " << cCents << " and the player staked "
<< pCents << " cents." << endl;
int reply,
numGames = 0;
// since we presume that the user wants to play at least one time ...
do // ... we can use the do..while(..) structure
{
++numGames;
playgame( cCents, pCents ); // computer cents and player cents updated
if( pCents > 0 && cCents > 0 )
{
cout << "\nAfter game "<<numGames<<" player has "
<< pCents<<" cents\n"
<< "and the computer has " << cCents << " cents\n"
<< "\nPlay again (y/n) ? ";
reply = cin.get(); // NOTE! cin.get() return type is an 'int'
cin.sync(); // flush cin stream ...
}
}while( !(reply=='n' || reply=='N') && pCents > 0 && cCents > 0 );
// don't allow, (i.e. correct for), 'in-hole' stuations ...
if( pCents < 0 ) // player in hole
{
cCents -= -pCents; // i.e. decrease computer balance
pCents = 0; // so now can up balance of player to zero
}
else if( cCents < 0 ) // computer in hole
{
pCents -= cCents; // decrease player balance
cCents = 0; // so now can up balance of computer to zero
}
// can insert the starting 'stakes' here ...
// cCents, and pCents hold the values we need to print out with message
cout << "\nAfter " << numGames << " games, the computer has "
<< cCents << " cents\n"
<< "and the player has " << pCents << " cents" << endl;
// calclate the computer winnings
int cWins = cCents - cCentsInitial;
// calculate the player winnings
int pWins = pCents - pCentsInitial;
if( cWins > 0 ) // computer wins
{ // take the negative of pWins ...
cout << "The computer wins " << cWins
<< " and the player loses " << -pWins << endl;
}
else // computer loses
{ // take neg cWins ...
cout << "The player wins " << pWins
<< " and the computer loses " << -cWins << endl;
}
cout << "\nPress 'Enter' to exit ... " << flush;
cin.get(); // wait for 'Enter' ...
}
// this example uses code ...
// modified to use list and const_iterator, derived ...
// from a demo by 'Bench' at DIC
// and illustrates ...
// - friend functions in a class
// - operator overloading to ease read/write records (from a CSV file, here)
// - STL list container
// - and using iterators like 'it' in ...
// std::list< Student >::const_iterator it;
// to access elements in a list (a STL container)
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <list>
class Student
{
public:
friend std::ostream& operator<< (std::ostream&, const Student&);
friend std::istream& operator>> (std::istream&, Student&);
private:
std::string name;
int id;
double fees;
};
std::ostream& operator<<(std::ostream& out, const Student& s)
{
out << std::setw(16) << std::left << s.name << ' '
<< std::setw(10) << s.id << ' '
<< std::setw(7) << std::right
<< std::setprecision(2) << std::fixed << s.fees;
return out;
}
std::istream& operator>>(std::istream& in, Student& s)
{
std::getline(in, s.name, ','); //read name
in >> s.id; //read id
in.ignore(); //ignore next comma
in >> s.fees; //read fees
in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
return in;
}
const char* FNAME = "Students.txt"; // as per example below inside /* */
/*
Peter Pan,1234,2499.99
Paul Simon,2468,3000.00
Fred Perry,1357,1250.50
Tom Jones,5678,600.00
Harry Hill,9876,2255.00
*/
int main()
{
std::ifstream fin( FNAME );
std::list< Student > stud_list;
Student stud;
while( fin >> stud )
stud_list.push_back( stud );
std::cout << stud_list.size()
<< " students were successfully read into the student list ...\n"
<< " Name ID Fees\n";
std::list< Student >::const_iterator it;
int i = 0;
for( it = stud_list.begin(); it != stud_list.end(); ++it )
std::cout << ++i << ": " << *it << std::endl;
std::cout << "\nPress 'Enter' to continue ... " << std::flush;
std::cin.get();
}
// structBook.cpp // using struct Book (instead of parallel arrays)
// this version 2010-06-01
#include <iostream>
#include <sstream>
#include <iomanip>
using namespace std;
const int MAX_RECORDS = 5;
struct Book
{
string title;
float price;
int quantity;
};
void showBook( const Book& );
void showBooks( Book[], int );
void takeInStock( Book[], int& );
void editBook( Book[], int&, int );
int main()
{
Book store[MAX_RECORDS] = {{"nothing",0,0},{"Book 1",77.5,4},{"Book 2",66,3}};
int count = 3;
if(count > 0) showBooks( store, count );
else cout << "Store is empty\n";
cout << endl;
takeInStock( store, count );
if(count > 0) showBooks( store, count );
else cout << "Store is empty\n";
for( ; ; )
{
cout << "\nEnter index of book to edit: " << flush;
string tmp;
getline( cin, tmp );
int i;
if( istringstream(tmp) >> i )
{
editBook( store, count, i );
}
else
{
cout << "Invalid index of " << tmp << " was entered ... Try again.\n";
continue;
}
cout << "More y/n ? " << flush;
int reply = cin.get();
cin.sync();
if( reply == 'n' || reply == 'N' ) break;
}
if(count > 0) showBooks( store, count );
else cout << "Store is empty\n";
cout << "\nPress 'Enter' to exit ... " << flush;
cin.get();
}
void showBook( const Book& b)
{
cout << setw(15) << left << b.title
<< setw(10) << right << b.price
<< fixed << setprecision(2)
<< setw(16) << right << b.quantity << endl;
}
void showBooks( Book st[], int size )
{
cout << "* * * * ALL AVAILABLE BOOK TITLES * * * *\n\n"
<< setw(15) << left << "Title"
<< setw(10) << right << "Price"
<< setw(16) << right << "Quanity" << endl
<< setw(15) << left << "====="
<< setw(10) << right << "====="
<< setw(16) << right << "=======" << endl;
for( int i = 0; i < size; ++i ) showBook( st[i] );
}
void takeInStock( Book st[], int& size )
{
for( ; size < MAX_RECORDS ; )
{
cout << "Enter new title: " << flush;
getline( cin, st[size].title );
cout << "Enter price: " << flush;
string tmp;
getline( cin, tmp );
if( istringstream( tmp ) >> st[size].price )
{
// pass ...
}
else
{
cout << "Price must be a number ... try again ... ";
continue;
}
cout << "Enter quanity: " << flush;
getline( cin, tmp );
if( istringstream( tmp ) >> st[size].quantity )
{
++size;
}
else
{
cout << "Price must be a number ... try again ... ";
continue;
}
cout << "More y/n ? " << flush;
int reply = cin.get();
cin.sync();
if( reply == 'n' || reply == 'N' ) break;
}
if( size == MAX_RECORDS ) cout << "Store is full." << endl;
}
void editBook( Book st[], int& size, int index )
{
int reply;
string tmp, msg = "edited";
if( index > size-1 || index < 0 )
{
cout << index << " NOT in valid range of 0.." << size-1 << endl;
if( index < MAX_RECORDS && size < MAX_RECORDS )
{
cout << "Add to end anyways ... y/n ? " << flush;
reply = cin.get();
cin.sync();
if( reply == 'y' || reply == 'Y' )
{
index = size++;
msg = "new";
goto addNew;
}
}
// else ...
return;
}
// else
showBook( st[index] );
cout << "ok to edit y/n ? " << flush;
reply = cin.get();
cin.sync();
if( !(reply == 'y' || reply == 'Y' ) ) return;
addNew:
// else ...
for( ; ; )
{
cout << "Enter " << msg << " title: " << flush;
getline( cin, st[index].title );
cout << "Enter " << msg << " price: " << flush;
getline( cin, tmp );
if( istringstream( tmp ) >> st[index].price )
{ /* pass ... */ }
else
{
cout << "Price must be a number ... try again ... ";
continue;
}
cout << "Enter " << msg << " quanity: " << flush;
getline( cin, tmp );
if( istringstream( tmp ) >> st[index].quantity )
{ /* pass ... */ }
else
{
cout << "Quanity must be an integer ... try again ... ";
continue;
}
cout << "Ok y/n ? " << flush;
reply = cin.get();
cin.sync();
if( reply == 'y' || reply == 'Y' )
{
if( index == MAX_RECORDS ) cout << "Store is full ... " << endl;
break;
}
}
}
// structBookStore.cpp // using struct Book and struct Store
// this version 2010-06-01
#include <iostream>
#include <sstream>
#include <iomanip>
using namespace std;
const int MAX_RECORDS = 5;
struct Book
{
string title;
float price;
int quantity;
};
struct Store
{
Book bStore[MAX_RECORDS];
int num_recs;
Store() : num_recs(0) {} // default constructor ... initial num_recs to 0
};
void showBook( const Book& );
void showStore( const Store& );
void takeInStock( Store& );
void editBook( Store&, int );
int main()
{
Book shipment1[] = {{"nothing",0,0},{"Book 1",77.5,4},{"Book 2",66,3}};
Store st; // calls default constructor to initial st.num_recs to zero (0)
int i = 0;
while( st.num_recs < MAX_RECORDS && i < int(sizeof shipment1/sizeof shipment1[0]) )
{
st.bStore[st.num_recs++] = shipment1[i++];
}
showStore( st );
cout << endl;
takeInStock( st );
showStore( st );
for( ; ; )
{
cout << "\nEnter index of book to edit: " << flush;
string tmp;
getline( cin, tmp );
int i;
if( istringstream(tmp) >> i )
{
editBook( st, i );
}
else
{
cout << "Invalid index of " << tmp << " was entered ... Try again.\n";
continue;
}
cout << "More y/n ? " << flush;
int reply = cin.get();
cin.sync();
if( reply == 'n' || reply == 'N' ) break;
}
showStore( st );
cout << "\nPress 'Enter' to exit ... " << flush;
cin.get();
}
void showBook( const Book& b)
{
cout << setw(15) << left << b.title
<< setw(10) << right << b.price
<< fixed << setprecision(2)
<< setw(16) << right << b.quantity << endl;
}
void showStore( const Store& st)
{
if( st.num_recs )
{
cout << " * * * * ALL AVAILABLE BOOK TITLES * * * *\n\n"
<< " " << setw(15) << left << "Title"
<< setw(10) << right << "Price"
<< setw(16) << right << "Quanity" << endl
<< " " << setw(15) << left << "====="
<< setw(10) << right << "====="
<< setw(16) << right << "=======" << endl;
for( int i = 0; i < st.num_recs; ++i )
{
cout << "<" << setw(2) << setfill('0') << i << ">"
<< setfill(' ') << " ";
showBook( st.bStore[i] );
}
}
else cout << "Store is empty\n";
}
void takeInStock( Store& st )
{
for( ; st.num_recs < MAX_RECORDS ; )
{
cout << "Enter new title: " << flush;
getline( cin, st.bStore[st.num_recs].title );
cout << "Enter price: " << flush;
string tmp;
getline( cin, tmp );
if( istringstream( tmp ) >> st.bStore[st.num_recs].price )
{
// pass ...
}
else
{
cout << "Price must be a number ... try again ... ";
continue;
}
cout << "Enter quanity: " << flush;
getline( cin, tmp );
if( istringstream( tmp ) >> st.bStore[st.num_recs].quantity )
{
++st.num_recs;
}
else
{
cout << "Price must be a number ... try again ... ";
continue;
}
cout << "More y/n ? " << flush;
int reply = cin.get();
cin.sync();
if( reply == 'n' || reply == 'N' ) break;
}
if( st.num_recs == MAX_RECORDS ) cout << "Store is full." << endl;
}
void editBook( Store& st, int index )
{
int reply;
string tmp, msg = "edited";
if( index > st.num_recs-1 || index < 0 )
{
cout << index << " NOT in valid range of 0.." << st.num_recs-1 << endl;
if( index < MAX_RECORDS && st.num_recs < MAX_RECORDS )
{
cout << "Add to end anyways ... y/n ? " << flush;
reply = cin.get();
cin.sync();
if( reply == 'y' || reply == 'Y' )
{
index = st.num_recs++;
msg = "new";
goto addNew;
}
}
// else ...
return;
}
// else
showBook( st.bStore[index] );
cout << "ok to edit y/n ? " << flush;
reply = cin.get();
cin.sync();
if( !(reply == 'y' || reply == 'Y' ) ) return;
addNew:
// else ...
for( ; ; )
{
cout << "Enter " << msg << " title: " << flush;
getline( cin, st.bStore[index].title );
cout << "Enter " << msg << " price: " << flush;
getline( cin, tmp );
if( istringstream( tmp ) >> st.bStore[index].price )
{ /* pass ... */ }
else
{
cout << "Price must be a number ... try again ... ";
continue;
}
cout << "Enter " << msg << " quanity: " << flush;
getline( cin, tmp );
if( istringstream( tmp ) >> st.bStore[index].quantity )
{ /* pass ... */ }
else
{
cout << "Quanity must be an integer ... try again ... ";
continue;
}
cout << "Ok y/n ? " << flush;
reply = cin.get();
cin.sync();
if( reply == 'y' || reply == 'Y' )
{
if( index == MAX_RECORDS ) cout << "Store is full ... " << endl;
break;
}
}
}
// classBookStore.cpp // using class Book and class Store
// this version 2010-06-01
#include <iostream>
#include <sstream>
#include <iomanip>
#include <cstdlib> // re. exit(1)
using namespace std;
const int MAX_RECORDS = 5; // keep this small for testing ...
class Book
{
public:
Book(string t="", float p=0, int q=0) : title(t), price(p), quantity(q) {}
void showBook();
private:
string title;
float price;
int quantity;
};
class Store
{
public:
Store() : num_recs(0) {} // default constructor ... initial num_recs to 0
void push_back( Book b );
void showStore();
void takeInStock();
void editBook( int );
int size() { return num_recs; } // inline ...
private:
Book bStore[MAX_RECORDS];
int num_recs;
};
int main() /////////////////////////// BEGIN MAIN //////////////////////////////
{
Book shipment1[] =
{
Book("Book 0",100,1),
Book("Book 1",77.5,4),
Book("Book 2",66,3)
};
Store st; // calls default constructor to initial st.num_recs to zero (0)
int i = 0;
while( st.size() < MAX_RECORDS && i < int(sizeof shipment1/sizeof shipment1[0]) )
{
st.push_back( shipment1[i++] );
}
st.showStore();
cout << endl;
st.takeInStock();
st.showStore();
for( ; ; )
{
cout << "\nEnter index of book to edit (-1 to exit) : " << flush;
string tmp;
getline( cin, tmp );
int i;
if( istringstream(tmp) >> i )
{
st.editBook( i );
}
else
{
cout << "Invalid index of " << tmp << " was entered ... Try again.\n";
continue;
}
cout << "More y/n ? " << flush;
int reply = cin.get();
cin.sync();
if( reply == 'n' || reply == 'N' ) break;
}
st.showStore();
cout << "\nPress 'Enter' to exit ... " << flush;
cin.get();
} //////////////////////////////// END MAIN ////////////////////////////////////
void Book::showBook()
{
cout << setw(15) << left << title
<< setw(10) << right << price
<< fixed << setprecision(2)
<< setw(16) << right << quantity << endl;
}
void Store::push_back( Book b )
{
if( num_recs < MAX_RECORDS ) bStore[num_recs++] = b;
else
{
cerr << "Store full ... increase MAX_RECORDS above "
<< MAX_RECORDS << " and recompile ...\n\n"
<<"Press 'Enter' to exit ... " << flush;
string dummy;
getline( cin, dummy );
exit(1);
}
}
void Store::showStore()
{
if( num_recs )
{
cout << " * * * * ALL AVAILABLE BOOK TITLES * * * *\n\n"
<< " " << setw(15) << left << "Title"
<< setw(10) << right << "Price"
<< setw(16) << right << "Quanity" << endl
<< " " << setw(15) << left << "====="
<< setw(10) << right << "====="
<< setw(16) << right << "=======" << endl;
for( int i = 0; i < num_recs; ++i )
{
cout << "<" << setw(2) << setfill('0') << i << ">"
<< setfill(' ') << " ";
bStore[i].showBook();
}
}
else cout << "Store is empty\n";
}
void Store::takeInStock()
{
string title;
float price;
int quantity;
while( num_recs < MAX_RECORDS )
{
cout << "Enter new title: " << flush;
getline( cin, title );
cout << "Enter price: " << flush;
string tmp;
getline( cin, tmp );
if( istringstream( tmp ) >> price )
{
// pass ...
}
else
{
cout << "Price must be a number. Try again ... ";
continue;
}
cout << "Enter quanity: " << flush;
getline( cin, tmp );
if( istringstream( tmp ) >> quantity )
{
// pass ...
}
else
{
cout << "Quanity must be an integer. Try again ... ";
continue;
}
cout << "Ok y/n ? " << flush;
int reply = cin.get();
cin.sync();
if( reply == 'y' || reply == 'y' )
push_back( Book(title, price, quantity) );
else
cout << "skipped ...\n";
cout << "More y/n ? " << flush;
reply = cin.get();
cin.sync();
if( reply == 'n' || reply == 'N' ) break;
}
if( num_recs == MAX_RECORDS ) cout << "Store is full." << endl;
}
void Store::editBook( int index )
{
if( index == -1 ) return;
int reply;
string tmp, msg = "edited";
if( index > num_recs-1 || index < 0 )
{
cout << index << " NOT in valid edit range of 0.." << num_recs-1 << endl;
if( index < MAX_RECORDS && num_recs < MAX_RECORDS )
{
cout << "But there's room ... Add to end anyways y/n ? " << flush;
reply = cin.get();
cin.sync();
if( reply == 'y' || reply == 'Y' )
{
index = num_recs++;
msg = "new";
goto addNew;
}
}
// else ...
return;
}
// else
bStore[index].showBook();
cout << "ok to edit y/n ? " << flush;
reply = cin.get();
cin.sync();
if( !(reply == 'y' || reply == 'Y' ) ) return;
addNew:
// else ...
for( ; ; )
{
cout << "Enter " << msg << " title: " << flush;
string title;
getline( cin, title );
cout << "Enter " << msg << " price: " << flush;
getline( cin, tmp );
float price;
if( istringstream( tmp ) >> price )
{ /* pass ... */ }
else
{
cout << "Price must be a number ... try again ... ";
continue;
}
cout << "Enter " << msg << " quanity: " << flush;
getline( cin, tmp );
int quantity;
if( istringstream( tmp ) >> quantity )
{ /* pass ... */ }
else
{
cout << "Quanity must be an integer ... try again ... ";
continue;
}
cout << "Ok y/n ? " << flush;
reply = cin.get();
cin.sync();
if( reply == 'y' || reply == 'Y' )
{
bStore[index] = Book( title, price, quantity );
if( index == MAX_RECORDS ) cout << "Store is full ... " << endl;
break;
}
}
}