Author Topic: BEGINNING COMPUTER PROGRAMMING (using C++ or C)  (Read 46034 times)

Offline David

  • Hero Member
  • *****
  • Posts: 644
    • View Profile
BEGINNING COMPUTER PROGRAMMING (using C++ or C)
« on: March 01, 2009, 12:42:59 PM »
BEGINNING COMPUTER PROGRAMMING
(using ... a try it and see it approach)


Update:  please see this next link:

http://developers-heaven.net/forum/index.php/topic,2636.0.html

FREE homework help NOW available ...

You can contact me via:
http://sites.google.com/site/securejoules/securetransportservices
http://sites.google.com/site/andeveryeyeshallseehim/home/he-comes


This is a continuation of the Beginning Computer Programming series that started at the following link ...

http://developers-heaven.net/forum/index.php/topic,46.0.html

or

http://developers-heaven.net/forum/index.php?topic=2607.0

You may find many useful example student type programming problems solved in C and C++ at this next link ...

http://developers-heaven.net/forum/index.php/topic,106.0.html

or ... simple Beginning Sample Programs at this next link ...

http://developers-heaven.net/forum/index.php/topic,134.0.html

Please see either of the above first 2 links for 'credits' ...

You may also like to see ...

Six Fast Steps to Programming in C
http://developers-heaven.net/forum/index.php/topic,2022.0.html

Six Fast Steps to Programming in C++
http://developers-heaven.net/forum/index.php/topic,2019.0.html


Table of Contents:

Chapter 01: The Computer prints a message
Chapter 02: The Computer gets some input
Chapter 03: The Computer adds some numbers
Chapter 04: The Computer repeats a procedure
Chapter 05: The Basic Elements of computer programming …
Chapter 06: The Computer rolls the dice … a first simulation
Chapter 07: First Memory Flow Lab
Chapter 08: Memory Flow Lab2
Chapter 09: Memory Flow Lab3
Chapter 10: C++ Data Types
Chapter 11: The Computer does some Algebra with real numbers ... and Input Data Validation
Chapter 12: Pointers, Strings, your own Types, Records, Arrays, and dynamic things on the fly!
Chapter 13: The Computer files its Records
Chapter 14: The Computer reads its Files
Chapter 15: The Computer updates (edits, deletes, sorts, chops-duplicates-in) its Files
« Last Edit: September 06, 2018, 03:16:43 AM by David »

Offline David

  • Hero Member
  • *****
  • Posts: 644
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using C++ or C)
« Reply #1 on: March 01, 2009, 01:46:45 PM »
Chapter 01: The Computer prints a message


There are many free compilers, e-texts and tutorials.  Here is a popular free tutorial for C ... the backdrop for C++

http://mindview.net/CDs/ThinkingInC/beta3 

And a free DEV IDE with C/C++ compiler included at ...

http://www.bloodshed.net/

Try this now ...
http://sourceforge.net/projects/orwelldevcpp/


Now jumping right in ... since you have already spent some time with HLA, I hope, for your good foundation's sake ...


1. Install the Dev IDE and the C/C++ compiler that comes with it.
 

2. Create and go to the working directory c:\2009cpp  Note the use of rem indicates a remark or comment. No need for student to enter the rem or what comes after this here:

click start

click run

enter cmd ( i.e. type in cmd and then press the Enter key)

enter (the following lines on the command line, but not rem or what comes after):

c:  rem c: means change to the c: drive

cd \  rem cd \ means change to the root directory in the current drive

md 2009cpp  rem md 2009cpp means make a directory called 2009cpp

cd 2009cpp  rem cd 2009cpp means change to the 2009cpp directory
                                                                                     
md chapt01_print_message

cd chapt01_print_message

 
3. Using a text editor program (already installed on your computer) like notepad.exe enter this next line (on the command line):

notepad.exe  print_message.cpp

and then select yes when asked Do you want to create a new file?

Now enter these next few lines into the text editor workspace, (i.e. copy and paste the lines into the text editor workspace):


Code: [Select]
// 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 ...
}
 

4. Now save this as a file with the name print_message.cpp         

(Make sure notepad doesn't save it as print_message.cpp.txt)

Enter dir to see the files in that DIRectory.  If it does have a .txt on the end of it, then rename it by entering the command below … (note: ren means rename)

ren  print_message.cpp.txt  print_message.cpp

or               

ren  print_message.txt  *.cpp

Note: the file needs to end in .cpp to let it be compiled by the C++ compiler.

 
5. Now enter the following command on the command line to load this file into the Dev IDE ...

print_message.cpp


6. Then click on 'execute' and then on 'compile' or 'compile&run' in the IDE ...

 
7. Now run the new executable file just produced and see the output by entering this next command:

print_message.exe

or

click on 'execute' ... then 'run' from the IDE ...


Note: an other way (see below) to code, (a not so safe way, in BIG programs, where names may be re-used), is to dump all the std namespace reserved words into the program's GLOBAL scope (i.e. They can now be used anywhere in the program without having to specify the namespace name with the scoping :: operator, to be recognized by the compiler and the program.


Code: [Select]
// 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 ...
}


Another way, which limits these reserved words to just the 'scope' of the 'main function' is as below ...


Code: [Select]
// 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 ...
}


Here is a great tutorial on C++ strings ...

http://www.dreamincode.net/forums/topic/42209-c-strings/
« Last Edit: September 29, 2015, 07:46:51 AM by David »

Offline David

  • Hero Member
  • *****
  • Posts: 644
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using C++ or C)
« Reply #2 on: March 01, 2009, 02:18:30 PM »
Chapter 02: The Computer gets some input


1. (Go to the working directory)

click start

click run

enter cmd

enter (the following on the command line):

cd c:\2009cpp

md chapt02_get_input

cd chapt02_get_input

 
2. Using a text editor like notepad.exe enter this next line (on the command line):

notepad.exe  get_input.cpp (or just enter ... notepad  get_input.cpp)

and then select yes when asked Do you want to create a new file?

Now enter these lines into the text editor workspace, (i.e. copy and paste the lines into the text editor workspace):

Code: [Select]
// 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();
}
 

3. Now save this file (with the file name get_input.cpp)

 
4. Now enter this following command, on the command line, to load that file into the IDE ...

get_input.cpp

... and then compile and run the file get_input.exe


Or ... a popular/easy C++ way to get strings ...


Code: [Select]
// 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 ...
}


Notes: re. your choice of variable names ... like last_name or first_name ...

1. Use names that help document/explain what is going on there in your program ... so ... the line

string last_name; // reserves space to hold a (pointer to a) string that will hold some last name ...

2. Variable names can NOT be the same as 'key/reserved' words ...

3. Variable names must begin with a letter or _ char (NOT A NUMBER)
( but do NOT use the _ char feature for a first char ...
  use names like first_name .. or firstName
  which ever style you like ... but be consistent)

4. Variable names like max, Max, MAX, are all different ... i.e. case is significant in C++ (and C)
(but try NOT to use this potentially confusing feature)


Found the 'brief' below ... at this link:

http://elvis.rowan.edu/~kunkle/24Jan03-Page4.htm

Rules for Naming C++ Variables

    * Variable names can consist of:
          o Letters
          o Digits
          o Underscores

      Example: "num1" to store the first of 3 numbers

    * Variable names cannot start with a digit.

      Example: "3integers" is illegal

    * Variable names should not start with an underscore.

      Example: Avoid the use of variable names like "_number"

    * Variable names should consist of 31 or fewer characters to ensure portability.

    * Variable names should be descriptive of their use.

      Example: "grade" would be a good name to use for a variable that stores
      a student's test grade.

    * Variable names are case sensitive.

      Example: "x1" is not the same as "X1"

    * Keywords such as "int" and "float" cannot be used as variable names.

References: Forouzan & Gilberg, Chapter 2.3 & 2.5; Savitch, Chapter 2.1; Deitel & Deitel, Chapter 1.1

Below is a link you may like to keep for easy reference for many C++/C questions ...

http://www.cplusplus.com/
« Last Edit: March 29, 2009, 06:13:44 AM by David »

Offline David

  • Hero Member
  • *****
  • Posts: 644
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using C++ or C)
« Reply #3 on: March 01, 2009, 03:46:04 PM »
Chapter 03: The Computer adds some numbers

 

1. (Go to the working directory)

click start

click run

enter cmd

then enter (on the command line):

cd c:\2009cpp

md chapt03_add_nums

cd chapt03_add_nums

 
2. Using a text editor like notepad.exe enter this next line (on the command line):

notepad  add_nums.cpp

and then select yes when asked Do you want to create a new file?

Now enter these lines into the text editor workspace, (i.e. copy and paste the lines into the text editor workspace):

Code: [Select]
// 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();
}


3. Now save this file with the name add_nums.cpp


4. Now enter this command on the command line to load the file into the IDE ...

add_nums.cpp

... and then compile and run.
 

Offline David

  • Hero Member
  • *****
  • Posts: 644
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using C++ or C)
« Reply #4 on: March 01, 2009, 05:16:19 PM »
Chapter 04: The Computer repeats a procedure

                                                                                          
1. (Go to the working directory)

click start

click run

enter cmd

then enter (on the command line):

cd c:\2009cpp

md chapt04_repeat_proc

cd chapt04_repeat_proc

 
2. Using a text editor like notepad.exe enter this next line (on the command line):

notepad  repeat_proc.cpp

and then select yes when asked Do you want to create a new file?

Now enter these lines into the text editor workspace, (i.e. copy and paste the lines into the text editor workspace):


Code: [Select]
// 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;
    }
}


3. Now save this text file with the name repeat_proc.cpp

4. Now enter the following command on the command line to to load into the IDE ... and to compile ... producing the executable file with the name repeat_proc.exe

repeat_proc.cpp

5. Now run the file repeat_proc.exe by entering this next command (on the command line ... or run from the IDE).  Then supply suitable input and observe:

repeat_proc.exe  (or just enter:  repeat_proc)


This is an other version for you to study ... ( that demos a form of input validation ) ...


Code: [Select]
// 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;
    }
}


Or ... a little more modular ... demo's using functions ...


Code: [Select]
// 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() );
}
« Last Edit: December 13, 2009, 05:42:55 AM by David »

Offline David

  • Hero Member
  • *****
  • Posts: 644
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using C++ or C)
« Reply #5 on: March 01, 2009, 06:11:02 PM »
Chapter 05 : The Basic Elements of a program ...


So far … we have

1. executed instructions in sequence,
2. executed a block of instructions if and only if a certain condition was met using an if..else if... else structure,
3. repeatedly executed a block of instructions until a condition was met
4. labelled a block of instructions with a function name, and called for the execution of that block of instructions by using the function name as a command to execute that block, at the place where it is called from, in our program.

You may be surprised that all programs are mostly just various combinations of the above.

 
We have also learned some rudimentary house keeping:


1. We have told the computer where the program begins and where it ends:

The program starts execution inside the int main() function at the top ...

The program ends when it returns an int value from main ...

Notice the semi-colon characters that tell the compiler that we have finished an instruction, (similar to the period at the end of a sentence.)


2. We have also told the computer which (library of) functions it is to recognize ...

Code: [Select]
// 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;
}

Notice the # character. It instructs the compiler here to include the library header file.  Also notice that a semi-colon, at the end of that instruction to the compiler, is NOT used.

If you wanted to break up a long program file into sections, or store some procedure in a file to be reused later, for example, if you had the declaration/definition of say, void myDoIt(), saved in a text file in your working directory, or in the IDE include directory, with the name myDoIt.h, you could then ask the compiler to include that file like this:

#include "myDoIt.h"

You could insert this line in your .cpp file in the include section, (like thus):

Code: [Select]
#include <iostream>
#include "myDoIt.h"

Then, at compile time, the C++ compiler will insert the text of that file into the program(s) then being compiled, just as if you had copied and pasted in that text - at that location, (and then saved your thus modified someName.cpp program, before compiling.)


3. Also, we have told the computer where (and how) to place some data in memory so that it can be accessed where ever appropriate in the program, by name:

Code: [Select]
// 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();
}


4. And we have told the computer where (and how) to place some functions in memory so that they can be accessed by name, where ever appropriate in the program:

Code: [Select]
// 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();
}


For an assignment, create a suitable folder like c:\2009\chapt05_myWork … Then,  in it:


1. Using your text editor, create your version, i.e. the file bare_bones.cpp, having just the following few lines (i.e. the bare bones) shell of an C++ program.  Then compile it and run it.  Is there any output? Why or why not?

Code: [Select]
// fileName: bare_bones.cpp
#include <iostream>
using namespace std;

int main()
{
    return 0;
}


2. (a) Create the file compNamNum2.cpp to reflect your version of a C++ program that outputs the Name and the Number of some computer of your imagination. Compile and run it.  (b) Now leave off some (for example, the last) closing semi-colon in your program and try compiling it now.  Note the error message(s) and see if you can follow them to correct the error(s). (c) Make other errors, preferably, one at a time, and see if you can follow the compiler messages to fix these syntax errors.

 
3. Create the file test_showNameNumb2.cpp where you will have the program ask for a name to be input and then a number. Then display what was input and ask if they were input correctly.  If correct, quit with a message saying that they were ok.  If data was not input correctly, then ask for the data to be input again.  You may input and test individually … or input both then check if both ok.

 
4. Modify your version of 3. above, to make the file showNameNumb3.cpp using another do.. while(..) loop to ask 3 times for a name and number, while still, as in 3. above, checking each time if the data that was input was valid. Hint: int counter = 0; // 0 initial value before entering loop.  Then inside the loop ++counter;  Then at the end of the loop, test if the counter has reached 3 yet. NOTE: When adding or comparing two values they must each (should each) have the same data type ...

 
5. For (easy) bonus, how would you make your do .. while(..) structure to loop forever? (Hint: There are several possible ways, that all really boil down to the same thing.) How might one exit from this forever loop? There are simpler ways to code for a forever loop. Try for( ;; ){ ... };  NOTE! If you want to find some help on how to code something fast, just Google it.


Added reference re. 'forever loops' in C/C++ ...

http://www.dreamincode.net/forums/topic/173929-repeating-a-switch-in-case-of-a-wrong-input/page__view__findpost__p__1020657
« Last Edit: May 18, 2010, 06:18:24 AM by David »

Offline David

  • Hero Member
  • *****
  • Posts: 644
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using C++ or C)
« Reply #6 on: March 02, 2009, 01:28:49 PM »
Chapter 06: The Computer rolls the dice … a first simulation


Ok …

Here is an interactive project with a little Google research to find out about the random function in the C++ library.

1.   Create a sub folder in the \2009cpp folder with the name chapt06_randomNumber
2.   With your text editor, start a new file called guessIt.cpp and cut and paste a shell of a C++ program into it.
      Save it.
      Compile it to make sure it is good so far, (or fix it … so that it will compile with no significant error messages.)
3.   Now let’s think about the bare bones of what we want the program to do:
I.    Announce what the program is about.
II.   Ask the user to input a guess in the range 2-12.
III.  Get the computer to select randomly a number in that range.
IV.  See if the number guessed matches the total on the die that the computer rolled
V.   Report the results
VI.  Ask if user wants to try again … or quit

Ok … let's get a shell started …

Code: [Select]
// 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
}

Ok …

It compiles and runs ok so far, but did you notice that the user can enter numbers that are way out of range?
Let’s fix that this way: (We will pass the value to a function to validate it.)

Code: [Select]
// 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;
}

Ok …

Let’s plug that in and check it out so far …

Code: [Select]
// 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
}

So far … so good.

But let’s do that research on the C++ random function, (if C++ has one?) … google C++ random and here is what came up near top just now (2009-03-02) ...

http://www.cplusplus.com/reference/clibrary/cstdlib/rand.html

rand    function

int rand ( void ); // include <cstdlib>

Generate random number

Returns a pseudo-random integral number in the range 0 to RAND_MAX.

This number is generated by an algorithm that returns a sequence of apparently non-related numbers each time it is called. This algorithm uses a seed to generate the series, which should be initialized to some distinctive value using srand.

RAND_MAX is a constant defined in <cstdlib>. Its default value may vary between implementations but it is granted to be at least 32767.

A typical way to generate pseudo-random numbers in a determined range using rand is to use the modulo of the returned value by the range span and add the initial value of the range:

( value % 100 ) is in the range 0 to 99
( value % 100 + 1 ) is in the range 1 to 100
( value % 30 + 1985 ) is in the range 1985 to 2014

Notice though that this modulo operation does not generate a truly uniformly distributed random number in the span (since in most cases lower numbers are slightly more likely), but it is generally a good approximation for short spans.

Parameters ... (none)

Return Value ... An integer value between 0 and RAND_MAX.

Example

Code: [Select]
/* 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;
}

Output:

Guess the number (1 to 10): 5
The secret number is higher
Guess the number (1 to 10): 8
The secret number is lower
Guess the number (1 to 10): 7
Congratulations!

In this example, the random seed is initialized to a value representing the second in which the program is executed (time is defined in the header <ctime>). This way to initialize the seed is generally a good enough option for most (beginner programmer's) random number needs.

See also
srand   ... Initialize random number generator (functions)
http://www.cplusplus.com/reference/clibrary/cstdlib/srand.html

Now let’s see if we can plug it in and get it working in our program … (and notice some changes? / deletions? / improvements? … that were made also.)

Code: [Select]
// 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
}

Well, these functions are working ok … but let’s make some more enhancements:

Let’s add a counter to keep track of the number of games.  And suppose that you started out with so many cents, say 100, at the beginning and win the number of cents, (the value you guessed), when there is a match … but lose the number (the same number of cents) you guess for the sum of the dice if there is NO match … (Let’s use global variable’s for these to keep the design simple, ... so we won’t have to pass these values back and forth to/from the procedures or to use pass by reference syntax, since this is supposed to be a simple simulation?)

The game will be over when all your starting cents are used up, … or … if you choose to quit, (or if by some long shot, the computer loses all its cents!)

Make a final report of the success or failure. (What you started out with. How much you were up/down.  Your new total and the computers new total. The number of games played.)

Are you ready to start programming?

Code: [Select]
// 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;
}

Time to reflect ... a little ...

I've have noticed in some 'beginning' text-books ... that the text was recommended to students who had had previous practice with programming in some language ... Thus ... those books are not appropriate texts for someone who has never programmed before ... unless they are 'fleshed out at the beginning' with sufficient concepts and lots of exposure to small programs that introduce C++ key-words and concepts step by step.

With C++ ... the easy and useful things/objects like strings ... can be introduced on day two ... and the old C strings, can be dealt with later ... after you are comfortable with the much easier to use C++ strings.

Classically, for beginners, the ideal would be to build bottom up from the simple "Hello World" program ... learning to print some text on the console screen (after you have compiled and obtained an executable file from the hwxxx.cpp file that you hand to the C++ compiler to process) ... by adding one new C++ keyword/concept ... in one new program ... at a time ... and seeing what it does.

And then ... to make changes and see what that does ... And to make mistakes like leaving off a semi-colon or making a typo, (one at a time, at first) ... And seeing if you can follow the compiler's error messages to fix your program up so that it can be compiled and adjusted to give the EXACT desired output that you may want to change it to produce.

There is a lot to learn ... even how to let the compiler help you find your bugs. This is best learned at first, by starting out with a WORKING program shell. Then adding just one command or small block of commands at a time, so that you KNOW then, WHERE in the code to look, to fix it up, so that it will compile. And then to adjust/fine tune that code further ... to give the ('test') output that is EXACTLY what you want.

This all takes some time, but may be accellerated, if one has access to lots of demo code, that provide a working shell to start.

Again ... the great thing about PC's is that one can learn 'hands on'. And the rate of learning can be tremendous, if lots of well designed online demo code is quickly available to assist in seeing each new step.

The common pitfalls, that cause new students such stress in C/C++, are often poorly addressed.

1. Things like your program crashing when some non-numeric data was entered accidentally when your program was expecting numeric data.

2. Or your program NOT stopping for the next input of data because, unknown to you, there are STILL some characters, like a '\n' char in the cin stream left over from the previous data input, and NO body showed you how to 'flush' this very common and frustrating C/C++ problem away.

(The whole really easy concept of data validation, if introduced early, could so make the beginners programming experience, so much less frustrating ...and maybe even fun.)

3. And then for new programmers, the idea of calling a block of code that has been labeled with a function name ...and returning from that block ... to begin with the next command in the sequence after the place from which that block of code was called ...

4. The idea of passing in values to a function ...

5. And the idea of returning values from a function.

These all take some time and some practice before one may get a little comfortable.

One thing should be clear by now ... It took a lot of designing and work to build these computer systems ... hardware, software, Operating Sytems (OS's),  computer languages for machine code, to assembly, to HLL like C++ and HLA and Python .... THEY OBVIOUSLY did NOT in any way happen by themselves ...  Thus ... computer systems may help illustrate the absolute necessity of a Great Creator for a Great Creation ...

And so ... "In the beginning God created the heavens and the earth."

It did NOT just all happen by itself.

We all may do well to let that sink in 'real good' in the turbulent days ahead ...

Shalom,
David

P.S. For some insights about 'the turbulent days ahead' ... please continue on at the following link ...
http://sites.google.com/site/andeveryeyeshallseehim/home/he-comes

P.P.S. You may also like to see this added (cleaned up) alternative version (that does not use global variables) at:
http://developers-heaven.net/forum/index.php/topic,127.msg476.html#msg476
« Last Edit: January 26, 2010, 07:17:28 AM by David »

Offline David

  • Hero Member
  • *****
  • Posts: 644
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using C++ or C)
« Reply #7 on: March 02, 2009, 04:24:44 PM »
Chapter 07: Memory Flow Lab


1. Create (md) a sub-directory in the project folder.  Give it the name memoryFlowLab
2. Go (cd) to that new directory.
3. Using your text editor, create the following program file in that folder.  Give the program the name memoryFlowLab.cpp
4. Compile the program and run it. Study the comments and questions that are in the cpp program, as well as the questions, (and answers), that appear on the screen when you run (execute) the program.

Code: [Select]
// 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;
}
« Last Edit: March 02, 2009, 04:31:29 PM by David »

Offline David

  • Hero Member
  • *****
  • Posts: 644
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using C++ or C)
« Reply #8 on: March 02, 2009, 05:45:40 PM »
Chapter 08: Memory Flow Lab2


1. Create (md) a sub-directory in the project folder.  Give it the name memoryFlowLab2
2. Go (cd) to that new directory.
3. Using your text editor, create the following program file in that folder.  Give the program the name memoryFlowLab2.cpp
4. Compile the program and run it. Study the comments that are in the C++ program, as well as the output that appears on the screen when you run (execute) the program.

Code: [Select]
// 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;
}
« Last Edit: March 02, 2009, 08:42:58 PM by David »

Offline David

  • Hero Member
  • *****
  • Posts: 644
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using C++ or C)
« Reply #9 on: March 02, 2009, 07:32:46 PM »
Chapter 09: Memory Flow Lab3
 

1. Create (md) a sub-directory in the project folder.  Give it the name memoryFlowLab3
2. Go (cd) to that new directory.
3. Using your text editor, create the following program file in that folder.  Give the program the name memoryFlowLab3.cpp
4. Compile the program and run it. Study the comments that are in the C++ program, as well as the output that appears on the screen when you run (execute) the program.

Code: [Select]
// 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;
}
« Last Edit: March 02, 2009, 09:15:55 PM by David »

Offline David

  • Hero Member
  • *****
  • Posts: 644
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using C++ or C)
« Reply #10 on: March 03, 2009, 01:21:19 PM »
Chapter 10: C++ Data Types

 
1. Create (md) a sub-directory in the project folder.  Give it the name cppTypes
2. Go (cd) to that new directory.
3. Using your text editor, create the following program file in that folder.  Give the program the name cppTypes.cpp
4. Compile the program and run it. Study the comments that are in the .cpp program, as well as the output that appears on the screen when you run (execute) the program.


Code: [Select]
// 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()

}

see also ...

http://www.cplusplus.com/reference/clibrary/climits/
http://www.cplusplus.com/reference/clibrary/cfloat/

SHRT_MIN        Minimum value for an object of type short int                    -32768
SHRT_MAX       Maximum value for an object of type short int                     32767
USHRT_MAX     Maximum value for an object of type unsigned short int         65535
INT_MIN          Minimum value for an object of type int                             -32768 ... but may be same as LONG
INT_MAX         Maximum value for an object of type int                              32767 ... but may be like LONG below
UINT_MAX       Maximum value for an object of type unsigned int                  65535 ... but may be like ULONG below
LONG_MIN       Minimum value for an object of type long int                -2147483648
LONG_MAX      Maximum value for an object of type long int                 2147483647
ULONG_MAX    Maximum value for an object of type unsigned long int    4294967295



See also:

http://webster.cs.ucr.edu/AoA/Windows/HTML/MoreDataRepresentationa2.html#1002164

Characters

Perhaps the most important data type on a personal computer is the character data type. The term "character" refers to a human or machine readable symbol that is typically a non-numeric entity. In general, the term "character" refers to any symbol that you can normally type on a keyboard (including some symbols that may require multiple key presses to produce) or display on a video display. Many beginners often confuse the terms "character" and "alphabetic character." These terms are not the same. Punctuation symbols, numeric digits, spaces, tabs, carriage returns (enter), other control characters, and other special symbols are also characters. When this text uses the term "character" it refers to any of these characters, not just the alphabetic characters. When this text refers to alphabetic characters, it will use phrases like "alphabetic characters," "upper case characters," or "lower case characters.".

Another common problem beginners have when they first encounter the character data type is differentiating between numeric characters and numbers. The character '1' is distinct and different from the value one. The computer (generally) uses two different internal, binary, representations for numeric characters ('0', '1', ..., '9') versus the numeric values zero through nine. You must take care not to confuse the two.

Most computer systems use a one or two byte sequence to encode the various characters in binary form. Windows and Linux certainly fall into this category, using either the ASCII or Unicode encodings for characters. This section will discuss the ASCII character set and the character declaration facilities that HLA provides.


The ASCII Character Encoding

The ASCII (American Standard Code for Information Interchange) Character set maps 128 textual characters to the unsigned integer values 0..127 ($0..$7F). Internally, of course, the computer represents everything using binary numbers; so it should come as no surprise that the computer also uses binary values to represent non-numeric entities such as characters. ...
« Last Edit: April 24, 2009, 08:36:59 AM by David »

Offline David

  • Hero Member
  • *****
  • Posts: 644
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using C++ or C)
« Reply #11 on: March 03, 2009, 05:31:51 PM »
Chapter 11: The Computer does some Algebra with real numbers ... and Input Data Validation
 

1. Create (md) a sub-directory in the project folder.  Give it the name Chapt11_realMath
2. Go (cd) to that new directory.
3. Using your text editor, create the following program file in that folder.  Give the program file the name realMath.cpp
4. Compile the program and run it. Study the comments that are in the realMath.cpp program, as well as the output that appears on the screen when you run the program.


Code: [Select]
// 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
    }
}

« Last Edit: April 24, 2009, 10:23:46 AM by David »

Offline David

  • Hero Member
  • *****
  • Posts: 644
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using C++ or C)
« Reply #12 on: April 24, 2009, 10:00:00 AM »
Chapter 12: Pointers, Strings, my own Types, Records, Arrays, and dynamic things on the fly ...


1. Create (md) a sub-directory in the project folder. Give it the name Chapt12_records
2. Go (cd) to that new directory.
3. Using your text editor, create the following program file in that folder. Give the program file the name records.cpp
4. Compile the program and run it.

Study the comments that are in the cpp program, as well as the output that appears on the screen when you run the program.


Code: [Select]
#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();
}


So ... what has been happening above?

1. We defined our own type of variable and gave it the name MyContacts.
2. We further defined MyContacts to be a record of two strings.  Now since C++ strings may be implemented ** to behave
   as pointers to the (address of the) first byte in that string, and as you may recall addresses in 32 bit addressing mode
   are 4 bytes, thus each ‘pointer’ takes 4 bytes, and thus each record, storing those 2 pointers, (may) take(s) 8 bytes.
3. But there is more ... Each string was given enough memory to hold its (allocated memory) by the C++ STL
   function. A pointer (i.e. the address) to that memory was returned.
4. So here we are allocating memory on the fly ... cool eh?
5. Cool as long as we don’t run out. (The C++ STL string takes care of all this memory management for us in
   the 'background'.)
6. Note how we access the parts of the record for each element in the array with the dot operator ... for example:
   'myBook[ 0 ].theName' and 'myBook[ 0 ].thePhone' ... the [ 0 ] means the 1st element in the array ...
   .theName means ... take the first offset there in memory.  Note the '.' (dot) operator to access each named
   member in a C struct or a C++ struct or class


The following version shows some input data validation ... and passing in const values ...

Code: [Select]
#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();
}
   


** example code to see if address of 1st char in C++ string is interpreted as that whole C++ string ... ?
Code: [Select]
// 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() );
}
« Last Edit: April 30, 2012, 01:54:00 AM by David »

Offline David

  • Hero Member
  • *****
  • Posts: 644
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using C++ or C)
« Reply #13 on: April 24, 2009, 10:24:43 AM »
Chapter 13: The Computer files its Records

and

Chapter 14: The Computer reads its Files into a Record ( a C/C++ struct )


1. Create (md) a sub-directory in the project folder.  Give it the name Chapt13_fileRecords
2. Go (cd) to that new directory.
3. Using your text editor, create the following program file in that folder. Give the program file the name
    fileRecords.cpp
4. Compile the program and run it. Study the comments that are in the .cpp program, as well as the output
   that appears on the screen when you run the program.

Notice that we are starting out with the same program with which we ended in the previous chapter. For a simple start ... we will just add ... and then let the program call a procedure (a C++ void function) to file the records at the end, before exiting. Then we will add another function to read these records into an array of records, when we first run our program, i.e. it will read the records ... if there is an existing file with records to read.

Here is a simple 'pattern' of the C++ functionality we wish to add:


Code: [Select]
// 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();
}
                   

Now here is our program to file and to read files ...

Code: [Select]
// 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();
}


Note our very simple file structure ... We are writing a name on one line ... then, a phone number on the next line. When we read back, from file, via getline string input, the getline function takes care for us, of reading, and then discarding, the newline character(s) at the end of each line.


Here is a very insightful tutorial about reading C++ files ... (and the 'end of file' flag)

http://www.dreamincode.net/forums/topic/145699-eof-and-reading-text-files-c/
« Last Edit: June 01, 2010, 10:23:55 PM by David »

Offline David

  • Hero Member
  • *****
  • Posts: 644
    • View Profile
Re: BEGINNING COMPUTER PROGRAMMING (using C++ or C)
« Reply #14 on: April 24, 2009, 02:44:07 PM »
Chapter 15: The Computer reads/updates/adds to its files ...

Take a careful look here ... we are still using an array to hold each data struct/record ... but we will be moving fairly quickly to a STL vector container ... and then finally ... to a STL list container to handle easily the deletes ...

So ... you may want to take a good look at this simple pattern here with arrays ... because we will use a very similar style with vector and list containers as we do here with arrays ... (Recall ... add ... test ... fix ... add ... test ... fix ... until we are done ...)

So ...  here is a next step ... still using an array of our records/structs ...

Try it out and see how it runs ... and see all the comments in the program ...

Code: [Select]
// 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' );
}


Chapter 15 is continued on the next page ...

Continue on by clicking on the 2 on Pages: [1] 2 at the lower left corner of this page/screen ...
« Last Edit: February 06, 2010, 09:32:25 AM by David »