Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - David

Pages: 1 2 [3] 4 5
31
C/C++ & Visual C++ / C SOME UTILITY functions ...
« on: May 27, 2013, 01:27:36 AM »
This space is reserved for code and links to code for C utility functions ...

After I have collected several C snippets here ...  I hope to make an index with links on this front page.

But for now, please find these little snippets of code below,  (perhaps in related usage groupings of code, on the following pages.)




You may also like to see:  C++ SOME UTILITY functions ...

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


Update 2015-04-08: 

SEE the next link for several newly improved STUDENT take in type utilities  ...
with out of bounds error handling ...
(Some VERY HANDY student utilities.)

http://developers-heaven.net/forum/index.php/topic,2608.msg3158.html#msg3158


1.  /* example of a way to fix fgets TWO sometimes very annoying problems   */
char* fixedFgets( char* str, size_t bufSize, FILE* fin );

2.  /* example of a way to trim leading and trailing ws ... */
char* stripWS( char* s );

3.  /* example of an expedient way in C to handle string input from keyboard operator ...
    especially, if design calls to repeat input until string is of 'acceptable length' */
char* takeInStr( const char* msg, char* buf, unsigned bufLen, unsigned maxStrLen );

4.  /* an example of a common design request ... to Caps on first letters */
char* toCapsOnFirstLets( char* str );

5.  /* a simple student way to handle numeric input ...
   so program won't crash on bad input */
int takeInInt( const char* msg, int myMin, int myMax );

6.  /* loop until user takes in a valid int ... after prompt(s) ...  */
int takeInValidInt( const char prompt[] );

7.  /* a handy utility for many C student coding problems ... */
char takeInChar( const char* msg );

8.  int more(); /* defaults to 'true'/'yes'/'1' ... unless 'n' or 'N' entered */

9.  /* since using 'static' buf inside, memory persists ... so can return address */
char* takeInStaticString( const char* msg, unsigned max_len );

10. /* accepts only positive (i.e. >= 0) valid int range of values ... */
int takeInValidPosIntViaStaticString( const char* prompt, int high );

11. /*  returns a valid int in range INT_MIN..INT_MAX  */
int takeInValidMinMaxIntViaStaticString( const char* prompt, int myMin, int myMax );

...

And more added below ... like binary search, an iterative and also a recursive example, date and time and valid date and valid dob and days between two dates and ...


Code: [Select]
/* returns 'int' value if in range '0'..'9' else returns -1 if NOT a digit */

int getDigit( char c )
{
    if ( c < '0' || c > '9' ) return -1;
    return c - '0';
}

/*
    Note: int( c ), where c is a char in the range '0'..'9'
    would return integers in the range 48..57
    ... but getDigit( c ) returns integers in the range 0..9
*/


Code: [Select]
/* returns int value if in range '0'..'9' else returns -1 if not a number */

int isNum( char c )
{
    if ( c < '0' || c > '9' ) return -1;
    return c - '0';
}



1.  Six Fast Steps to Programming in C

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


2.  CvecOfInt.h, CvecOfString.h, Cvec.h, Cvec_func's.h (with FUNCTION POINTERS)

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


3.  Cvec_func's.h example programs ... using FUNCTION POINTERS to facilitate reuse

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


4. ClistOfInt.h, ClistOfString.h, Clist.h, Clist_func's.h (with FUNCTION POINTERS)

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


5.  Clist_func's.h example programs ... using FUNCTION POINTERS to facilitate reuse

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


6.  split.h ... a C emulation of the Python spilt function to parse a string ...

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


7.  Binary Search Tree template class in C ++ and Simple C Version

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


8.  Beyond Beginning Computer Programming in C ...

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


9.  Send in your C++ or C student coding problem, with code inside code tags (#)

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


10. Free coding help for beginners in C or C++

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


11. Clist Insertion Sort Tutorial ... and also see a recursive merge sort of a list

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


12. First steps ... via example programs in C++ and C ...

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


13. New thread especially for students of C and C++

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


14. BEGINNING COMPUTER PROGRAMMING (using C++ or C)

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

32
HLA / BEGINNING COMPUTER PROGRAMMING WITH HLA (High Level Assembly)
« on: May 17, 2013, 10:18:33 AM »
BEGINNING COMPUTER PROGRAMMING

 
(Using a Try it and See it approach)

                                                                                                                         
(AND ... a Computer Student's/Teacher's DREAM Introductory Computer Language - HLA)


Update: 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/andeveryeyeshallseehim/home/he-comes
http://developers-heaven.net/forum/index.php/topic,2587.0.html


You may also want to see ...

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

BEGINNING COMPUTER PROGRAMMING (using HLA and Python 3.1 and C++) 


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

Six Fast Steps to Programming in High Level Assembly (HLA)

 
 
Introduction:

 

To facilitate the solid insights provided in learning about computing by some exposure to Assembly Language, but also to provide a friendly and facile start for new programmers, HLA provides all the facility and power of Assembly Language, but with a user friendly syntax, yet offers many of the elegant structures of an HLL (High Level Language) like Pascal or C or even the OOP of a language like C++.  And so, going on to C, or C++, or any other modern HLL, will be more readily enabled, and with some real appreciation of what’s going on under the hood and inside the machine.

 

The author has successfully taught Computer Programming at a Canadian grade 7/8 Junior High and 9 to 12 High School level when PCs first became available using varied approaches, including using a personally authored simulated SIMPLE SIMON compiler running on a PC.   But his final approach, after which this course is being patterned, was the most fun, and also the most successful, for both students ... and teacher.

 

Please enjoy and profit from your work. Don't be afraid to make changes and see what happens.  Now dig in ... You may be surprised how much you will learn.

 

Shalom shalom,

David W. Zavitz

Toronto, Ontario, CANADA

dwzavitz@gmail.com

 
For arrangements to use this text beyond individual personal use, please contact the author at the above e-mail.

© (C) 2007-08-17

 

Acknowledgements:

This course and text would not be possible without the very gifted insights, teaching experiences, and programming skills of Randall Hyde,

http://en.wikipedia.org/wiki/Randall_Hyde

the Author, Creator, and so far, the Sustainer of HLA. I also would like to acknowledge the tremendous encouragement given by my youngest son Matthew, who's recent Engineering need to know a little C++, and then Assembly ... provided the incentive for a little more then that, from dad, (which led to HLA and now this attempt to benefit beginning computer students in general.)  Also, I would like to thank my students at Scarborough Christian High School, who besides being very promising young ladies and gentlemen, provided exemplary feedback as we went along into some not yet fully charted territory.

 

 
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 … and low level example(s)
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: HLA 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
Chapter 16: The Computer … vast OS’s … and the garbage collects?  (Operating Systems ... what is DOS?)
Chapter 17: The Computer delivers daily Manna ... (gui Canadien ... eh?)
Chapter 18: OOP ... goes the computer?
Chapter 19: OOP 2
Chapter 20: Shaping Moving OOP with HLA   ... a CLASS ACT ! (revised 2013-05-24)

33
C/C++ & Visual C++ / 6 Fast Steps to a C++ template class List
« on: May 08, 2013, 08:21:38 PM »


This section is designed to help new C++ students 'to see something of' ...

the progression in coding ...

from a simple struct Node, 

that has a data element and a pointer to the next Node element ...

to code for a functioning template class list

with iterators to traverse the list and access the data in a Node ...


Please see the comments in each of the 6 programming steps below.

In the 5th and 6th steps the code for the List class is in its own .h file

(these .h files follow the respective test programs, for programming steps 5 and 6 ... )


You may also like to see these steps ...
http://developers-heaven.net/forum/index.php/topic,2629.0.html


OK ... here is step one ...

Code: [Select]
// List_step1.cpp //  // 2013-05-08 //

// design a struct to hold data and a 'next' address i.e. a link to 'next' Node
// here, at step 1, we will just be holding, for the data, an int ...
// NOTE how C++ facilites, via a constructor, assigning initial values ...

#include <iostream>

using namespace std;

struct Node
{
    int data;
    Node* next;

    // ctor ... handles both cases of default ctor and value passed ctor ...
    // if call Node myNode; in your program, default value for int data is 0
    // if call Node myNode(7); in your program, default value for int data is 7
    // Note that the value assigned to next is NULL in both of the above cases
    Node( int dt = 0 ) : data(dt), next(NULL) {}

};

void print( const Node* cur )
{
    cout << cur->data;
}



// NOTE below that head is a pointer to Node
// AND updated by being passed in (and back) by C++ reference style passing
void push_back( Node*& head, int n )
{
Node* newNode = new Node( n );
Node* cur = head;

    if( cur ) // not first node
    {
        while( cur )
        {
            if( cur->next == NULL )
            {
                cur->next = newNode;
                return;
            }
            else cur = cur->next;
        }
    }
    else head = newNode;
}

//delete specific item ...
void deleteItem( Node*& head, int item )
{
    Node* cur = head; // get copy
    Node* prev = NULL;


    while( cur )
    {
        if( cur->data == item ) break;
        prev = cur;
        cur = cur->next;
    }

    // test end conditions ...

    if( cur ) // was found
    {
        if( prev ) // was not first node, so prev and cur exist
        {
            prev->next = cur->next; // skip over cur ...
            delete cur;
        }
        else // was first node
        {
            head = head->next;
            delete cur;
        }

    }
    else cout << "\nNot found ...\n";
}

void printAll( const Node* cur )
{
    if( !cur )
    {
        cout << "\nThe list is empty ... so can't print anything ...\n";
        return;
    }

    while( cur )
    {
        print( cur );
        cout << " ";
        cur = cur->next;
    }
    cout << endl;
}

void clean( Node*& cur ) // updated head to NULL when done
{
    while( cur )
    {
        Node* delNode = cur;
        cur = cur->next;
        delete delNode;
    }
}



int main()
{

    // NOTE!  'head' MUST be initialled to NULL for push_back etc to work ... //
    Node* head = NULL;

    push_back( head, 10 );
    push_back( head, 30 );
    push_back( head, 20 );
    push_back( head, 40 );

    printAll( head );

    cout << "\ndeleting 20 ... \n";
    deleteItem( head, 20 );
    printAll( head );

    cout << "\ndeleting 10 ... \n";
    deleteItem( head, 10 );
    printAll( head );

    cout << "\nclean list ... \n";
    clean( head );
    printAll( head );

    cout << "\nPress 'Enter' to continue/exit ... " << flush;
    cin.get();
}

34



Here is a little introduction to coding for a binary search tree in C and C++

Enjoy :)


At first, let's look at some simpler C code re. a 'first go' at a Binary Search Tree ...
(Note: the previous error in the C version, of the  ... 'remove value from the BST' function, is now fixed, as of 2014-11-05)

Below, please find a little test program ... followed by the .h include file that is being tested' by this demo test program ...

Code: [Select]
/* test_binarySearchTree_c.h.c*/ /* 2014-11-02 */

 /* presuming ? negative numbers are stored in memory using 2's complement ? */
#define MIN_INT (1 << (sizeof(int)*8 - 1))
#define MAX_INT -(MIN_INT + 1)

#define startWithAryValues 1
#define RAN_ARY_SIZE 25

#include "binarySearchTree_c.h" /* includes <stdio.h>, <stdlib.h> */

#include <time.h> /* re. srand( time(0) ) */


const char* MENU = "\n 1.  Add to the tree"
"\n 2.  Find maxDepth of tree"
"\n 3.  printInOrder"
"\n 4.  printInPreOrder"
"\n 5.  printInPostOrder"
"\n 6.  Delete a node"
"\n 7.  Delete all"
"\n 8.  Delete a value"
"\n 9.  Find a value"
"\n 0.  Exit"
"\n\nEnter your choice: ";


void transfer( Node**, const int ary[], int size );

int getValidInt( const char* msg );

void testDeleteAllInOrderInserted()
{
    int ary[RAN_ARY_SIZE] = { 0 } ;
const int sizeAry = RAN_ARY_SIZE;

Node* root = NULL;
int i, size = 0;

srand( time(0) ) ;

for( i = 0; i < sizeAry; ++i )
{
        ary[i] = rand() % sizeAry;
        if( !find( root, ary[i]) ) ++size;
        insert( &root, ary[i] );
    }
       
    puts( "printInOrder ... " );
    printInOrder( root );
    printf("with size = %d", size );

    for( i = 0; i < sizeAry; ++i )
    {
        if( find( root, ary[i] ) ) --size;
        delVal( &root, ary[i] );
        printf( "\n\nAfter attempt at deleting %d, size is %d, "
                "getCount is %d, maxDepth is %d\n",
                ary[i], size, getCount(root), maxDepth(root) );
        printInOrder( root );
    }
   
    printf("\n\nPress 'Enter' to continue ..." );
    while( getchar() != '\n' ) ;
}


int main()
{
#if startWithAryValues
const int ary[] = { 30, 10, 40, 20, 50,
      11, 5, -5, 44, 66,
77, 33, 22, 99, -7 };
const int sizeAry = sizeof( ary ) / sizeof(int);
int i;
#endif

int choice, numGood, value;

Node* root = NULL;
int size = 0;

#if startWithAryValues
int loop = 3;

printf( "testDeleteAllInOrderInserted() ... \n" );
testDeleteAllInOrderInserted();
top:
size = sizeAry/loop;
transfer( &root, ary, size  );
printf( "\nThe maxDepth of tree from root is: %d", maxDepth( root ) );
printf( "\nprintInPreOrder: " );
printInPreOrder( root );
printf( "\nprintInOrder: " );
printInOrder( root );
printf( "\nThe size of tree is: %d\n", size );
printf( "The getCount from root is: %d\n", getCount( root ) );
for( i = 1; i <= size; ++i )
{
NodePos np;
initNodePos( &np );
getKthNode( root, &np, i );
printf( "\nThe maxDepth of tree from position %d is: %d", i,
  maxDepth( np.cur ) );
printf( "\nThe getCount from position %d is: %d", i,
getCount( np.cur ) );
}
fputs( "\n\nPress 'Enter' to continue ... ", stdout ); fflush( stdout );
while( getchar() != '\n' );

if( --loop > 0 ) goto top;

#endif

printf( "\n\nMIN_INT = %d, MAX_INT = %d\n\n", MIN_INT, MAX_INT );
do
{
printf( MENU ); fflush( stdout );
choice = -1;
scanf( "%d", &choice );
while( getchar() != '\n' );

switch( choice )
{
case 1:
printf("Enter a value: ");
numGood = scanf( "%d", &value );
while( getchar() != '\n' );
if( numGood == 1 )
{
insert( &root, value );
++size;
printf( "\nThe maxDepth of tree is: %d", maxDepth( root ) );
printf( "\nprintInOrder: " );
printInOrder( root );
printf( "\nThe size of tree is: %d\n", size );
}

else printf( "\nBad entry NOT inserted ...\n" );
break;
case 2:
printf( "\nThe maxDepth of tree is: %d", maxDepth( root ) );
break;
case 3:
printf( "\nprintInOrder: " );
printInOrder( root );
printf( "\ngetCount = %d", getCount( root ) );
printf( ", getCountInOrder = %d", getCountInOrder( root ) );
break;
case 4:
printf( "\nprintInPreOrder: " );
printInPreOrder( root );
printf( "\ngetCount = %d", getCount( root ) );
printf( ", getCountInOrder = %d", getCountInOrder( root ) );
break;
case 5:
printf( "\nprintInPostOrder: " );
printInPostOrder( root );
printf( "\ngetCount = %d", getCount( root ) );
printf( ", getCountInOrder = %d", getCountInOrder( root ) );
break;
case 6:
if( root )
{
del( &root );
printf( "\nOne node has been deleted ....\n" );
--size;
printf( "\nThe size of tree now is: %d",size );
}
else printf( "\nTree was empty ....\n" );
break;
case 7:
{
int n = 0;
while( root )
{
del( &root );
++n;
--size;
}
printf( "\nThe size of tree now is: %d",size  );
printf( "\n%d nodes were deleted ... \n", n );
break;
}
case 8:
{
int delValue = getValidInt( "Enter value to delete: " );
if( find( root, delValue ) )
{
                delVal( &root, delValue );
                printf( "\n%d was deleted ok ... ", delValue );
--size;
printf( "\nThe size of tree is: %d",size );
}
else
printf( "\n%d was NOT found, so NOT deleted...", delValue );

}
break;
case 9:
{
int findValue = getValidInt( "Enter value to find: " );
if( find( root, findValue ) )
printf( "\n%d was found ok ...", findValue );
else
printf( "\n%d was NOT found ...", findValue );
}
break;
case 0: /* exit on 0 ... */
{
int count = 0;
count = delAll( &root );
printf( "\n%d nodes were deleted ...\n", count );
/*
int n = 0;
while( root )
{
del( &root );
++n;
--size;
}
printf( "\nThe size of tree now is: %d",size  );
printf( "\n%d nodes were deleted ... \n", n );
break;
*/
}
break;
default:
printf( "\nInvalid choice ... \n" );
}
putchar( '\n' );
}
while( choice != 0 );

fputs( "\nPress 'Enter' to continue ... ", stdout ); fflush( stdout );
while( getchar() != '\n' );
return 0;
}

35
These space is reserved for example solutions to common Student Type programming problems ...

Here, the goal is to see how one might code student type solutions in C++ code, compared to C code, compared to Python 3 code ...

(and to compare the processing speeds where time would be significant.)

Let's start with a very common C++ Student Grades program where the data for each program is input from a file, we will call ...

grades.txt

structured like this:
Code: [Select]
// example of file structure ...
/*
4 7
Sam : Smith-Jones : 10 : 52 : 99 : 70 : 90  : 88  : 77
Julie  :  Anders Johnston : 80 : 52 : 33 : 70 : 90 : 44 : 99
Zorman Storman : Davies : 0 : 52
Omar Gomar : Davies : 100 : 100 : 100 : 100 : 100 : 100 : 100
*/

Here is a first go ... using a struct that seems a suitable match to the file structure ...

i.e. each struct holds each line of data, First Name, Last Name and up to 7 integer scores, each out of 100 max

BUT NOTE: the first line in the data file holds two integers separated by 'white space'.  The first integer lets the program know how many lines of student data follow.  The 2nd integer lets the program know the max number of scores to be stored in memory for each student.

Also note: we are using the STL vector to hold our student data struct's, and a library sort to sort by names and average grade.

A slightly advanced feature here would be using static variables in the student struct ...

1. to store (one time only) the max number of student scores to be handled for each student record
2. to store (one time only) the max length of all the student names, to 'make pretty the alignment' of the output

... and a vector of integers inside each struct, to hold the grades for each student data struct

Also using functions (methods) in the struct that pertain to processing the data stored in each student struct

Also, note our coded compare functions passed to the library sort function, to specify how to do each desired sort, here by descending average mark and also by ascending student last name, first name.

Code: [Select]
// gradesCpp.cpp // 2013-02-03 //

#include <string>
#include <fstream>
#include <sstream> // re. istringstream obj's to parse line
#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm> // re. sort ...

using namespace std;

const string FNAME = "grades.txt";
// example of file structure ...
/*
4 7
Sam : Smith-Jones : 10 : 52 : 99 : 70 : 90  : 88  : 77
Julie  :  Anders Johnston : 80 : 52 : 33 : 70 : 90 : 44 : 99
Zorman Storman : Davies : 0 : 52
Omar Gomar : Davies : 100 : 100 : 100 : 100 : 100 : 100 : 100
*/


struct Student
{
    string fname, lname;
    static int max_len;
    static int num_tests;
    double avg;
    vector< int > grades;
   
    Student() // default constructor ...
    {
        avg = 0;
        grades.reserve( num_tests );
    }
   
    void show()
    {
        cout << left << setw(max_len+5) << setfill('.')
             << (lname + ", " + fname) << " ";
       
        cout << setfill(' ') << right;
        for( unsigned i = 0; i < grades.size(); ++ i )
        {
            cout << setw(3) << grades[i] << ' ';
        }
        cout << " Average = " << setprecision(1) << fixed << setw(5)
             << avg << endl;
    }
   
    void cal_set_avg()
    {
        //avg = 0; // set by (default) constructor above //
        unsigned i;
        for( i = 0; i < grades.size(); ++ i )
        {
            avg += grades[i];
        }
        if( i ) avg /= num_tests;
    }
} ;

// initial static variables used in above struct here ...
int Student::max_len = 0;
int Student::num_tests = 0;


// these next compare functions are used by sort algorithm
bool cmpAvg( const Student& a, const Student& b )
{
    return a.avg > b.avg;
}
bool cmpName( const Student& a, const Student& b )
{
    if( a.lname == b.lname ) return a.fname < b.fname;
    return a.lname < b.lname;
}


void rstrip( string& s )
{
    int len = s.size();
    while( len && s[--len] == ' ' );
    s.erase(len+1);
}
void lstrip( string& s )
{
    int len = s.size(), count = 0;
    while( len && s[count] == ' ' ) --len, ++count;
    s.erase( 0, count );
}
void strip( string& s )
{
    int len = s.size(), count = 0;
    while( len && s[--len] == ' ' );
    s.erase(len+1);
    while( len && s[count] == ' ' ) --len, ++count;
    s.erase( 0, count );
}

void fillFromFile( ifstream& fin, vector< Student >& v )
{
    cout << "File dump ..." << endl;

    int numStuds;
    fin >> numStuds >> Student::num_tests;
    cout << numStuds << ' ' << Student::num_tests << endl;

    string line;
    getline( fin, line ); // get to end of line ...

    v.reserve( numStuds ); // reserve dynamic memory for numStuds Students
    while( getline( fin, line ) )
    {
        cout << line << endl;
       
        // get fname and lname ('stripped' of end spaces) ...
        istringstream iss( line );
        Student s;
        getline( iss, s.fname, ':' );
        rstrip( s.fname );
        getline( iss, s.lname, ':' );
        strip( s.lname );

        int lenl = s.lname.size();
        int lenf = s.fname.size();
        if( lenl+lenf > Student::max_len )
            Student::max_len = lenl+lenf; // update max_len

        // get all grades for this student record ...
        string tmp;
        while( getline( iss, tmp, ':' ) )
        {
            // convert string tmp to int g ...
            istringstream issg( tmp );
            int g;
            issg >> g;
            s.grades.push_back( g ); // append this 'g' to this Student's grades
        }
        s.cal_set_avg(); // calculate and set this student average

        // ok ... append this Student record ...
        v.push_back( s );
    }
}




int main()
{
    vector< Student > studs; // create empty vector to hold 'Student' objects
   
    ifstream fin( FNAME.c_str() ); // recall must use 'C type' of string here
    if( fin )
    {
        fillFromFile( fin, studs );
        cout << "\nVector dump ..." << endl;
        unsigned i;
        for( i = 0; i < studs.size(); ++i ) studs[i].show();

        sort( studs.begin(), studs.end(), cmpName );
       
        cout << "\nSorted by name... " << endl;
        for( i = 0; i < studs.size(); ++i ) studs[i].show();
       
        sort( studs.begin(), studs.end(), cmpAvg );
       
        cout << "\nSorted by avg... " << endl;
        for( i = 0; i < studs.size(); ++i ) studs[i].show();
       
        fin.close();
    }
   
    cout << "\nPress 'Enter' to continue/exit ... " << flush;
    string line;
    getline( cin, line );
}

36
HLA / Demo Programs linked from Beginning Calculus
« on: January 14, 2013, 12:56:16 AM »
Below, please find the Python Demo Programs linked to here, from the new thread ...

Beginning Calculus



To go to Beginning Calculus, click here ...

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

To go to a Beginner's Level introduction to the Python version 3 programming language ...

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


This first demo is an 'updated version' of Archimedes method to calculate the value for the constant pi

Select/Copy the following program, coded in the Python computer language, and paste that code into a Text Editor like Notepad ... then 'SaveAs' that file with file name my_piArchimedes.py

Making sure, that you have a 3.x version of the freely available Python Interpreter installed on your PC, then, you can 'click on' ... i.e. 'run' that .py file you just saved.

Note: Python program file names end with .py


Code: [Select]
# my_piArchimedes.py # this ver. 2013-01-20 #

# This Python program needs Python version 3 (or newer version)
# installed on your PC ... to run ok

header1 = \
'''A demo program in 'Beginning Calculus' by dwzavitz

   Find perimeter/2 of inscribed regular polygon for circle radius = 1 unit
   using here an ... 'Updated Archimedes Method' ...
   that cal's sin(t/2) from sin(t) as the number of sides double each loop
   Uses sin(t/2)  = sqrt( (1 - sqrt(1 - (sin(t))^2) ) / 2 ) ... (see below)

  for regular inscribed polygon ... (for 'UNIT CIRCLE')
   _
  |_|_r=1, n=4, t/2 = 45 deg's, sin(t/2) = 1/sqrt(2), pi = 4/sqrt(2) = 2.824
   _
  / \_r=1, n=6, t/2 = 30 deg's, sin(t/2) = 0.5, s = 1, pi = n*(0.5)  = 3
  \_/
'''

header2 = \
'''Recall:
    e^(i*2*t) = cos(2*t) + i*sin(2*t)
    e^(i*2*t) = e^(i*t)^2 =  (cos(t) + i*sin(t))^2
              = (cos(t))^2 - (sin(t))^2) + i*2*sin(t)cos(t)
             
And taking 'non-i' parts to be equal ...
    cos(2*t)  = (cos(t))^2 - (sin(t))^2)

So  cos(2*t)  = 1 - 2*(sin(t))^2  ... Recall (sin(x))^2 + (cos(x))^2 = 1
So  sin(t)    = sqrt( (1 - cos(2*t) ) / 2 )
And sin(t/2)  = sqrt( (1 - cos(t) ) / 2 )
But since   ... ...        cos(t) = sqrt(1 - (sin(t))^2)
Now sin(t/2)  = sqrt( (1 - sqrt(1 - (sin(t))^2) ) / 2 )
'''

from math import * # make pi (and all math library) available in global namespace #

# above '*' char indicates to import all math functions, etc...
# and so now ... don't need 'math.xxx' math namespace name at front of 'xxxdef Perimeter( n, sin_th ):


def halfPerimeter( n, sin_th ): ## Note: (n/2 - 2*sin_th) = n * sin_th ##
    return n * sin_th


print( header1 )
input( "Press 'Enter' to continue ... " )

print( header2 )
input( "Press 'Enter' to continue ... " )

print( "Loop#    Sides sin(th/2)             " + \
       "Half Perimeter -> Area ('Unit Circle')" )   

#n = 4 ## n is number of sides to start (of inscribed regular polygon) ##
n = 6  ## Note: 6 sides was Archimedes starting number ##
#sin_th =  2**0.5/2  # start value: 4 sides and t = 90, t/2 = 45 deg's
sin_th = 0.5  # start value: 6 sides and t = 60, t/2 = 30 ...


P = 0
count = 0
while True: # loop forever until break condition below is realized #
    count += 1
    P_old = P
    P = halfPerimeter( n, sin_th )
    if count % 5 == 1:
        print( '{:2d} {:11,d} {:.15e} {:.16f}'.format(count,n,sin_th, P) )

    if P - P_old < 10**(-16): # i.e. when reach limit of 'float precision'
        break

    # double the number of sides to get ready for next loop
    n = 2*n

    # now update the sine of the next 1/2 angle when sides doubled

    #sin(t/2)  = sqrt( (1 - sqrt(1 - (sin(t))^2) ) / 2 )
    #sin_th = sqrt( (1 - sqrt(1-sin_th**2) / 2 ) #updating to sin(th/2) here#

    ## MUCH better sig dig result in PC if use this form of above ##
    ## by multiplying top and bottom of fraction by sqrt( (1+sqrt(1-sin_th**2)) ) ##
    sin_th = sin_th / 2**0.5 /sqrt( 1 + sqrt( 1- sin_th**2 ) )


print() # print a blank line ...

print( '%.16f' % pi, '<- pi (the actual value, rounded to 16 decimal places)' )
print( '%.16f %.16f <- P_old' % (P_old, P_old/pi) )
print( '%.16f %.16f <- P' % (P, P/pi) )
print( '%.16f <- (P - P_old) compared to 10**-16 = %.16f' % (P - P_old, 10**-16) )

input( "\nPress 'Enter' to continue/exit ... " )

# program output ... when run ...
'''
Press 'Enter' to continue ...
Loop#    Sides sin(th/2)             Half Perimeter -> Area ('Unit Circle')
 1           6 5.000000000000000e-01 3.0000000000000000
 6         192 1.636173162648678e-02 3.1414524722854611
11       6,144 5.113269070136972e-04 3.1415925166921559
16     196,608 1.597896653979543e-05 3.1415926534561005
21   6,291,456 4.993427043898358e-07 3.1415926535896590
26 201,326,592 1.560445951218302e-08 3.1415926535897896

3.1415926535897931 <- pi (the actual value, rounded to 16 decimal places)
3.1415926535897896 0.9999999999999989 <- P_old
3.1415926535897896 0.9999999999999989 <- P
0.0000000000000000 <- (P - P_old) compared to 10**-16 = 0.0000000000000001

Press 'Enter' to continue/exit ...   
'''


This next demo finds perimeter/2 of BOTH inscribed AND exscribed regular polygons ... for a circle with radius = 1 unit
(using here an ... 'Updated Archimedes  ***SQUEEZE***  Method')

Code: [Select]
# my_piArchimedes2.py # this ver. 2013-01-20 #

# This Python program needs Python version 3 (or newer version)
# installed on your PC ... to run ok


header1 = \
'''A demo program in 'Beginning Calculus' by dwzavitz

   Find perimeter/2 of inscribed regular polygon for circle radius = 1 unit

   AND perimeter/2 of EXscribed regular polygon ...
   
   using here an ... 'Updated Archimedes  ***SQUEEZE***  Method' ...
   
   that cal's sin(t/2) from sin(t) as the number of sides double each loop
   Uses sin(t/2) = sin(t)/2^0.5/sqrt( 1+sqrt(1-(sin(t))^2) ) ... (see below)
   And  tan(t/2)  =  tan(t) / (sqrt(1+(tan(t))^2)) + 1) ... (see below)

  for regular inscribed polygon ... (for 'UNIT CIRCLE')
   _
  |_|_r=1, n=4, t/2 = 45 deg's, sin(t/2) = 1/sqrt(2), pi = 4/sqrt(2) = 2.824...
   _
  / \_r=1, n=6, t/2 = 30 deg's, sin(t/2) = 0.5, s = 1, pi = n*(0.5)  = 3
  \_/ for EXscribed hexagon tan(t/2) = 1/sqrt(3),   pi  =  n/sqrt(3) = 3.464...
'''

header2 = \
'''Recall:

    e^(i*2*t) = cos(2*t) + i*sin(2*t)
    e^(i*2*t) = e^(i*t)^2 =  (cos(t) + i*sin(t))^2
              = (cos(t))^2 - (sin(t))^2) + i*2*sin(t)cos(t)
             
And taking 'non-i' parts to be equal ...
    cos(2*t)  = (cos(t))^2 - (sin(t))^2)

So  cos(2*t)  = 1 - 2*(sin(t))^2  ... Recall (sin(x))^2 + (cos(x))^2 = 1
So  sin(t)    = sqrt( (1 - cos(2*t) ) / 2 )
And sin(t/2)  = sqrt( (1 - cos(t) ) / 2 )
But since   ... ...        cos(t) = sqrt(1 - (sin(t))^2)

(So for inscribed regular polygon ...)
    sin(t/2)  = sqrt( (1 - sqrt(1 - (sin(t))^2) ) / 2 )

(And for excribed regular polygon ...)
    tan(t) = 2*tan(t/2) / ( 1 - (tan(t/2))^2 ) ... implies
    c   =   2*x / (1-x^2)  ...substituting in c = tan(t), x = tan(t/2) implies
    x = ( sqrt(1+c^c) - 1 ) / c
      = c / ( sqrt(1+c^2) +1 )  ...  implies  ...
    tan(t/2)  =  tan(t) / (sqrt(1+(tan(t))^2)) + 1)
'''

# make pi, sqrt (and all math library) available in global namespace #
from math import *

# above '*' char indicates to import all math functions, etc...
# and so now ... don't need 'math.xxx' math namespace name at front of 'xxxdef Perimeter( n, sin_th ):


def halfPerimeter( n, sin_th ): ## Note: (n/2 - 2*sin_th) = n * sin_th ##
    return n * sin_th


print( header1 )
input( "Press 'Enter' to continue ... " )

print( header2 )
input( "Press 'Enter' to continue ... " )
print()

print( "Loop#    Sides sin(th/2) / tan(th/2) " + \
       "Half Perimeter -> Area ('Unit Circle')" )   

#n = 4 ## n is number of sides to start (of inscribed regular polygon) ##
n = 6  ## Note: 6 sides was Archimedes starting number ##
#sin_th =  2**0.5/2  # start value: 4 sides and t = 90, t/2 = 45 deg's
sin_th = 0.5  # start value: 6 sides and t = 60, t/2 = 30 ...

#tan_th = 1 # for starting with exscribed square #
tan_th = 3**(-0.5) # for starting exscribed hexagon #

P = 0
count = 0
while True: # loop forever until break condition below is realized #
    count += 1
    P_old = P
    P = halfPerimeter( n, sin_th )
    Ptan = tan_th * n
    if count % 5 == 1:
        print( '{:2d} {:11,d} {:.15e} {:.16f}'.format(count,n,sin_th, P) )
        print( '{:2d} {:11,d} {:.15e} {:.16f}'.format(count,n,tan_th, Ptan) )
        print()

    if P - P_old < 10**(-16): # i.e. when reach limit of 'float precision'
        break

    # double the number of sides to get ready for next loop
    n = 2*n

    # now update the sine of the next 1/2 angle when sides doubled

    #sin(t/2)  = sqrt( (1 - sqrt(1 - (sin(t))^2) ) / 2 )
    #sin_th = sqrt( (1 - sqrt(1-sin_th**2) / 2 ) #updating to sin(th/2) here#

    ## MUCH better sig dig result in PC if use this form of above ##
    ## by multiplying top and bottom of fraction by sqrt( (1+sqrt(1-sin_th**2)) ) ##
    sin_th = sin_th / 2**0.5 /sqrt( 1 + sqrt( 1- sin_th**2 ) )

    tan_th = tan_th / (sqrt(1+tan_th**2) + 1)


#print() # print a blank line ...

print( '{:.16f} <- average of inscribed and exscribed ...'.format( (P+Ptan)/2 ) )
print( '%.16f' % pi, '<- pi (the actual value, rounded to 16 decimal places)' )


input( "\nPress 'Enter' to continue/exit ... " )

# program output ... when run ...
'''
Press 'Enter' to continue ...

Loop#    Sides sin(th/2) / tan(th/2) Half Perimeter -> Area ('Unit Circle')
 1           6 5.000000000000000e-01 3.0000000000000000
 1           6 5.773502691896257e-01 3.4641016151377544

 6         192 1.636173162648678e-02 3.1414524722854611
 6         192 1.636392213531158e-02 3.1418730499798242

11       6,144 5.113269070136972e-04 3.1415925166921559
11       6,144 5.113269738582516e-04 3.1415929273850978

16     196,608 1.597896653979543e-05 3.1415926534561005
16     196,608 1.597896654183539e-05 3.1415926538571730

21   6,291,456 4.993427043898358e-07 3.1415926535896590
21   6,291,456 4.993427043898989e-07 3.1415926535900560

26 201,326,592 1.560445951218302e-08 3.1415926535897896
26 201,326,592 1.560445951218305e-08 3.1415926535897962

3.1415926535897931 <- average of inscribed and exscribed ...
3.1415926535897931 <- pi (the actual value, rounded to 16 decimal places)

Press 'Enter' to continue/exit ...   
'''


This next Python code, takes good advantage of Pythons built in unlimited-long integers, to find pi to up 100,000 decimal places ...

Enjoy ...

Code: [Select]
# my_pi100_000places.py # this ver. 2013-01-11 #

# This file to be run under Python ver. 3 #

header = \
'''A demo program in 'Beginning Calculus' by dwzavitz
to find pi up to 100,000 decimal places
'''


# acotx = 1/x - 1/3x**3 + 1/5x**5 - 1/7x**7 + ... #
def acot( x, unity ):
    ssum = xpower = unity // x
    n = 3
    sign = -1
    count = 0
    while 1:
        xpower = xpower // (x*x)
        term = xpower // n
        if not term:
            break
        ssum += sign*term
        sign = -sign
        n += 2
        count += 1
        '''
        if count == 100000:
            print( "count = ", count )
            break
        '''

    print( "count = {:,d}".format( count ) )
    #input( "\nPress 'Enter' to continue ... " )
    return ssum

def mypi( digits ):
    unity = 10**( digits + 10 )
    # PI/4 <=  4*ACOT5 - ACOT239 #
    return 4 * ( 4 * acot( 5, unity ) - acot(239, unity) ) // 10**10



print( header )

done = False
while not done:
    s = 'Num of xxx decimal places to find in pi = 3.xxx (20 to 100000): '
    try:
        dig = int(input( s ))
        done = True
        if dig > 100000:
            done = False
            raise
        elif dig >= 30000:
            done = False
            print('{:,d}'.format(dig),"could take several seconds ... ",end = '')
            if input( "Ok (y/n) ? " ) == 'y' :
                done = True
        if dig < 20:
            dig = 20
            print( "Doing min of 20 decimal places ..." )
    except:
        print( "Invalid ... integer input <= 100,000 only please ... " )
       

import datetime
t1 = datetime.datetime.now()
tostr = str(mypi(dig)) # call mypi and convert num to str ...

print( "len(tostr)", '{:,d}'.format( len(tostr) ) )

import sys
outSave = sys.stdout
fout = open( "PI.txt", "w" )
sys.stdout = fout

print( "mypi(", dig, ")=\n", tostr[:1] + '.', sep = '' )
count = 0
for c in tostr[1:]:
    count += 1
    print( c, sep='', end='' )
    if count == 100:
        print()
        count = 0
#print()
#print( '3.\n' + '1234567890'*(dig//10) )

sys.stdout = outSave
fout.close()

t2 = datetime.datetime.now()

print( "Processing time was (time2 - time1) =", t2-t1 )

import os
os.system( 'notepad ' +  'PI.txt' )

#input( "\nPress 'Enter' to continue/exit ... " )

37
Ask the Author / Beginning Calculus ...
« on: January 06, 2013, 02:18:56 AM »
This new thread is to help prepare students for ...

Beginning Calculus


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/andeveryeyeshallseehim/home/he-comes
(See e-mail link near bottom of first page)
http://developers-heaven.net/forum/index.php?topic=2587.0

(Note to Computer Programming Students:
Many computer programming problems require a good grasp of Calculus.  As the pages on this topic of Beginning Calculus are developed, I hope to link to several demo computer programs that require some knowledge of Calculus.)


The goal here is:

In an as simple/straightforward way as possible, and using a 'step by step build' ... to get a good foundation/grasp of Calculus ...

so as to give a 'head-start' for serious students that need to pass Calculus and then want to use it with understanding.


We will try to make good use of many existing useful Calculus 'texts' already up on the web ...

and a top-down/bottom-up 'Modular Computer Programming' style here  ...

in our attempt to avoid the too common modern science fallacy of 'circular reasoning'.

One example of this fallacy in circular reasoning, an example that needs to be actively exposed, goes something like this:

If you ask an (evolutionary) geologist, how to know that certain (sedimentary) rocks, (rocks we now know, from lab tests, are laid down by fast moving flood water, when it slows, as per 'Noah's Flood') ... if they are of a certain age ... you may be told that 'the type of fossils in that rock tells its age.'

So off you go to the (evolutionary) paleontologist and ask to know the age of those fossils, and you are told: 'The geologist has supplied me with the date of that rock.'

So ... the (evolutionary) presumption of LONG ages is 'presumed true' from the start ... here ... a fallacy.

Euclid's proofs are a 'step by step' build that are a worthy classic in logic, used by Archimedes and Newton ... and were taught even when I did my High School Geometry, all the way up to Ontario grade 13, ending June '66.

Enjoy ...

The 'top-down' goes like this ...

We will 'name and describe' some major modules right at the start, which we need to 'call' as we progress in 'running' our 'program' ... but we also must ensure that each module (and sub-module) is 'correct' and 'well built' ...

From the 'bottom up' ...

We will ensure the we build each module and sub module from appropriate 'true primitives' of our 'machine programming language', before our program is 'finished' and we expect it to run at all, let along, correctly. 


Firstly: Pre-Calculus ...


Review of basic Math, Geometry, Algebra
   
Note: e^x means 'e to the exponent x', A*e means 'A times e'

Recall 'Bedmas'  ... so exponent is calculated first ... then multiply by constant value 'A'

( So you will 'know' how to evaluate an expression like A * e^x )

'Bedmas' is a mnemonic that means first do work inside brackets, then do exponent, then do division and/or multiplication in the order they occur, then do addition and/or subtraction in the order they occur ... All these are 'binary operations' ... Input a, b ... then doing 'binary op' ... output c


Number types:


Natural counting numbers (positive integers)


Discovery of 'zero' ... (extends natural numbers to include 0)


Discovery of negative integers ... extends 'whole' number line to 'left'
(Now we can solve any equation like y = x + b, and have y, x and b ALL be (just) integers)


Discovery of rational numbers a/b, (extends base number set to include decimal fractions, with a, b in set of all integers and b != 0)
(Now we can solve any equation like y = m*x + b and have y, m, x and b ALL be (just) 'rationals')
Recall 'trick' to find a and b in rational q= a/b = 0.123123etc...

1000 * q = 123.123123...
            q = 000.123123...

Now subtract ...
So    999 * q = 123
and            q = 123/999
Thus can find integers a and b and thus we show that any repeating decimal is a rational number. 


Note!!!

Can you see now, how we are moving from discrete counts of quanta, to a continuum?

You will want to note that between any two different rational numbers, a, b with a < b, no matter how close together they might be, we can always insert the one rational, (a+b)/2, or the 9 rationals a + k*(b-a)/10 where k takes values 1 to 9 ...  And between each of these we can keep on inserting, and so on ...

We will see that Calculus helps us to find ways to evaluate, to as many decimal places of precision as desired, quantities that are 'real' ... but may NOT be 'rational' ... i.e. NOT 'ratio' of two integers!  (We already know about some such numbers like square root of 3, for example, or pi.  You may have learned an algorithm to find the square root of any decimal fraction, to as many places of decimal precision as you like, but do you know a method, like Archimedes did, over 2200 years ago, to find pi to as much precision as desired?)

http://itech.fgcu.edu/faculty/clindsey/mhf4404/Archimedes/Archimedes.html

See link to modern computer program that uses an Updated Archimedes Method of finding pi ...

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


Discovery/extension to the 'real continuum' ... i.e. the 'complete' number line to include numbers that are non repeating decimals like pi, e, sqrt(2), etc. 

Note: you may be required to prove some 'real' ... like sqrt(2) ... is not a 'rational' on an exam.
 
An often used method here is *proof by contradiction*
So firstly, assume 'true' and that for some integers a, b ... sqrt(2) = a/b with NO common factors
(i.e. fraction is in 'lowest terms'), then square each side and 2*b^2 = a^2 ... which implies that a^2 is 'even' ... which implies that a is 'even' (since an odd times an odd is odd) ... So ... now can re-write a as 2*c ... So substituting '2*c' in the place of 'a' ... (2*c)^2 = 4*c^2 = 2*b^2 ... And thus ... 2*c^2 = b^2 ... Which implies that b^2 and then b are even.   

So we see 'here' that both a and b must 'then' be even.   But this contradicts that a/b was in lowest terms with NO common denominator (like 2 here).  So we conclude that sqrt(2) is NOT a rational number. 

To show that a number like e is not a rational, we could show that it is a non-repeating infinite decimal sequence ... by looking at the infinite series expansion for e below:

e = 1 + 1/1! + 1/2! + 1/3! + 1/4! + ...

(Note: n! means 'n factorial' and n! = 1*2*3* .... *n
Can you see that n! becomes ever much larger as n grows larger?)

... and see that adding in the next term, in a never ending series of ever increasingly SMALL decimal bits ... ensures the next decimals in the sequence have no repeating pattern, since the new factor in the ever increasing factorial, that we next divide by, will keep adding new re-scrambled smaller bits .... 'all the way' ... out to infinity ...


Discovery/extension to 'complete' 2-Dimensional Plane via 2D vectors or z = r*e^(i*t) = r*(cos(t) + i*sin(t)) and i has the value sqrt(-1)

Above begs question(s) of what is(are) ...
e,
cos(t),
sin(t)

...


Hint:

Think of music, like a violin string vibrating, think of the the alternating current induced into an electrical circuit by a microphone near by, think of the radio wave vibrations that fill our skies, think of nerve pulse electrical activity coursing though you right now, as you read this, think of the waves on the lake as a fish jumps up and breaks through the surface ... and dives back down into the deep ...  Ah ... we are emersed in so much beautiful and intricate sine wave and exponential activity ... Don't you think?



What I am seeing myself ... and from some recent research of well seasoned Calculus Professors ... that what is especially needed as a necessary Pre-Calculus preparation ... is a good grounding in Algebra and Problem Solving with close attention to excellent skill in 'details manipulation' of even fairly complex algebra ... so as to get the correct result in the end ... and to 'know' that your answer is correct 100 % of the time, (or nearly most of the time.)

The reality to me seems ... that although the math needed in ones routine practice will soon enough become 'routine' ... the 'bar' to even get to 'practice' ... often seems 'pretty high'. 


More to follow ...


P.S.

You may be interested in what motivated Newton in his 'discovery and pursuit of the tools of calculus' ...

"The greatest Scientist of all time, Sir Isaac Newton, was also a great student of the Bible. In fact, his motivation to grind telescope lens, to better track the planets positions in the sky, to study and to discover the laws of gravity, motion and the laws of calculus that allowed him to predict, with great precision, where the planets would be in the sky, back in Bible times and into the future to our days … was … because he wanted to see, if he was part of that generation that would still be living when the Lord Jesus, the Anointed Holy One of Israel, would return.  However Newton came to realize, that that time was ahead, even for this present generation.  First Israel had to be become a nation again (in 1948), and then Jerusalem had to come back to Israel (in 1967), in order for all the trouble that was predicted to occur with all the nations being troubled over Jerusalem … and then for Jesus to return, to save his people that remain, just outside Jerusalem, at the same spot He ascended into heaven about 2000 years ago."


The above 'excerpt' was taken from ...

http://developers-heaven.net/forum/index.php?topic=2587.msg2918#msg2918


P.P.S.

An other perspective from MIT ... 'The Big Picture of Calculus'

http://www.youtube.com/watch?v=UcWsDwg1XwM


Jumping in to see a very common example of applied calculus ...

http://www.dummies.com/how-to/content/how-to-analyze-position-velocity-and-acceleration-.html

http://www.mathcentre.ac.uk/resources/uploaded/mc-web-mech1-10-2009.pdf

http://www.youtube.com/watch?v=d-_eqgj5-K8


On the next page, please *NOTE THIS VERY AMAZING AND VERY USEFUL FORMULA*:

Euler showed that e^(i*pi) + 1 = 0
(Recall that i is defined as sqrt(-1) ... thus i^2 = -1 and i^4 = 1)


Also, please note this typo error, on next page here corrected
Implies ... d(C)/dr = d(pi*r)/dr = 2*pi ( where here we use notation dC/dr instead of notation C' ) <wrong version>
Implies ... d(C)/dr = d(2*pi*r)/dr = 2*pi ( where here we use notation dC/dr instead of notation C' ) <corrected version>

38
This space is designated to hold a library of HLA vector and HLA list functions ... similar to the Cvec/Cvec2 and Clist/Clist2 library of functions available here...

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


For some example programs that demo the use of these HLA vector and list containers with their push_back, (and list push_front, and vector reserve) ... and merge sort, insert sort, find, erase, and unique functions ... see this next link ...

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

The first set of vector and list functions, permit just one type of vector or list in a program.  These pairs of include files are named:


The first pair is:

"vector_func's.hhf"
"vector.hhf"

If you include file "vector_func's.hhf" to get access to the sort, etc... functions, that file FIRSTLY includes file "vector.hhf", which firstly includes file "stdlib.hhf"




The next pair is:

"sllist_func's.hhf"
"sllist.hhf"


If you include file "sllist_func's.hhf" to get access to the sort, etc... functions, that file FIRSTLY includes file "sllist.hhf", which firstly includes file "stdlib.hhf"



Note: see the vector2/sllist2 .hhf files at the bottom also ... linked here ...

http://developers-heaven.net/forum/index.php?topic=2600.msg2978#msg2978

39
HLA / Six Fast Steps to Programming in High Level Assembly (HLA) ...
« on: August 07, 2012, 05:35:22 AM »
  ~~16~
Six Fast Steps to Programming in High Level Assembly (HLA)

This series of programs and comments is a continuation of the series Six Fast Steps to Programming in C ... and ... Six Fast Steps to Programming in C++

Update!  Update: please see this next link:

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


FREE homework help NOW available via e-mail ... (or in person if in Toronto Ontario Canada region.)


The following fast paced tutorial may be of interest to new students of High Level Assembly (HLA) ...


Also now includes examples of using HLA strings with readLine, (available to you now by including my file "readLine.hhf" ... please see link to file "readLine.hhf" below), to read in dynamic HLA strings of ANY length, (length limited only by available memory).  This will add 2 more example programs, example 7. and example 8. to the 1. to 6. example HLA programs that follow.

Link for 7.
A simple example of my HLA type Vec container ... using an HLA Vec of HLA strings ...
http://developers-heaven.net/forum/index.php?topic=2599.msg2961#msg2961

Link for 8.
Using an HLA SLList type container of HLA strings ... (also demo's using 'split' line of text into a SLList of 'words')
http://developers-heaven.net/forum/index.php?topic=2599.msg2962#msg2962


Note: when you have exhausted these following pages, you may like to see vector2.hhf and list2.hhf (and func's .hhf files also) at the following link:

vector 2 link ...
http://developers-heaven.net/forum/index.php?topic=2600.0

list 2 link ...
http://developers-heaven.net/forum/index.php?topic=2600.0


The first part of this tutorial consists of a series of 6 example programs that students may like to have for reference and to use as a working 'shell' from which to start a project.

1. The first program is just a most basic 'shell' that assembles, and when run, asks the user to press 'Enter' to continue/exit ...

2. The next program illustrates how to get valid numeric input in a loop and how to ask for more at the end of a repeat ... until type HLA loop that calls a function 'more()' at the end of the loop

3. The next program demo's a way to get and validate user input using a FUNCTION  ... (a type of HLA procedure - one that returns a value in a register - commonly the 32 bit EAX register) ... to get valid input.

4. The next three programs progress from inputting numbers into an ARRAY that has the size fixed at compile time ... to using a vector ... and then a list container ... to hold as many numbers as the user wishes (limited only by available memory). They also illustrate how to SORT, FIND, or ERASE elements from the respective containers.

Note: you will need to have the appropriate pair of the following custom helper files:  vector.hhf, vector_func's.hhf ... or ... sllist.hhf and sllist_func's.hhf in the same folder as the programs '5.' and '6.' that use them, to assemble the programs '5'. and '6.' that use vector_func's.hhf and sllist_func's.hhf ... Please note that a link to these 4 helper files is provided below.

Note also, that all the numeric input example programs here, find the (integer) sum and the (floating point) average value ... of the numbers input.  Please note also the use of the FPU to handle floating point numbers.  Following are links to help with using the FPU and floating point numbers (and all things HLA) ...

http://216.92.238.133/Webster/www.artofasm.com/Windows/HTML/AoATOC.html

http://216.92.238.133/Webster/www.artofasm.com/Windows/HTML/RealArithmetic.html#998833

Please use this next link to access all things 'HLA" ...

http://216.92.238.133/Webster/

You may also like to see the SLOWER PACED beginning steps at this next link to  ...

BEGINNING COMPUTER PROGRAMMING USING HLA

https://docs.google.com/document/pub?id=1axLRopTi6Qb7ky_Er-IokvtkuneJMYqZAow8Ldas2t0


Or look here for some other programming links, etc ...

http://secureservices.ca

A student goal (and reward) here may be simply expressed like this ...

After the student has understood these examples, that student may then readily handle ... IN HLA ... many common beginner student type data processing problems ... with much of the same ease of using the C++ STL vector and list containers and the C++ STL support functions.

40
C/C++ & Visual C++ / Beyond Beginning Computer Programming in C ...
« on: April 02, 2012, 02:15:52 AM »


These following pages will be about a way to use void pointers and function pointers in C  ... to demonstrate how they might be used together to emulate/provide the functionality in C of the C++ vector and list containers.

Previously, (see the following links),

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

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

using Cvec.h and Clist.h and function pointers, but NOT void pointers, we provided this functionality, but it was some-what limited ... limited to just one type of vector and one type of list per program ... for example ... we could not have in the same program, a vector of doubles and also a vector of an other type ... we needed to make one a list and the other a vector container.  Also, we could not have a vector of vector ... or a list of list ... only allowed then, (in the same program), was a vector of list ... or a list of vector.

But with the added use of the void pointers below, we can now accommodate, in the same program, as many types of vectors and/or lists as needed, just like in C++ ... also you now can code for a vector of vector ... or a list of list ... just like in C++

Firstly, take a look at the new Cvec2.h file and the new Cvec2_func's.h file ... also the slightly augmented files readLine.h and readWord.h, with an added function now with prototype:  char* newMem( int bytes );

Code: [Select]
/* Cvec2.h */  /* this version 2015-06-15 */

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

/*
    TO USE ... you will need to define / typedef (struct) some record structure
    for example:  typedef a struct/node/element/record as Rec ...
    and define freeVrec( void* r ); ... so can call freeVrec( cv->ary +i*cv->elen );
    SEE EXAMPLES at bottom ...
*/
                           
#ifndef dwCvec2_H
#define dwCvec2_H

#ifndef debug_dwCvec2_H
#define debug_dwCvec2_H 0   /* set debug default to 'off' ...*/
#endif

#ifndef dwREADLINE_H
#include "readLine.h" /* includes stdio.h, stdlib.h, string.h, ctype.h, etc */
#endif

/* #include <stdlib.h> // re. realloc */
/* #include <string.h> // re. memcopy */

/* re-set this starting num of rec's to minimize realloc's */
#ifndef VEC_CHUNK_SIZE
#define VEC_CHUNK_SIZE 8
#endif

typedef struct myCvec
{
    void* ary;
    int elen;
    int size;
    int cap;
} Cvec;

void initCvec( Cvec* cv, int el_size )
{
    cv->ary = NULL;
    cv->elen = el_size;
    cv->cap  = cv->size = 0;
}

void clearCvec( Cvec* cv, void (*freeVrec) (void* el) )
{
    if( cv->size )
    {
        int i;
        for( i = cv->size-1; i >= 0; --i )
            freeVrec(  (char*)cv->ary + i * cv->elen  );
#if debug_dwCvec2_H
        printf( "Inside clearCvec at free( cv->ary ) = %p\n",  cv->ary );
#endif
        free( cv->ary );
        initCvec( cv, cv->elen );
    }
}


/* new array to hold 2x's records ... copies old to new */
void enlargeCvec( Cvec* cv )
{
    void* tmp;
    if( cv->cap ) cv->cap += cv->cap; /* double capacity ... */
    else cv->cap = VEC_CHUNK_SIZE; /* set initial capacity */
    tmp = realloc( cv->ary, cv->cap * cv->elen );
    if( tmp == NULL )
    {
        myAssert( 0, "Error: realloc failed in enlargeCvec..." );
    }
    /* else ... */
    cv->ary = tmp; /* update the base address of cv->ary */
}


void reserveCvec( Cvec* cv, int newCap )
{
    if( newCap > cv->cap )
    {
        void* tmp;
        cv->cap = newCap;
        tmp = realloc( cv->ary, cv->cap * cv->elen );
        if( tmp == NULL )
        {
            myAssert( 0, "Error: realloc failed in reserveCvec..." );
        }
        /* else ... */
        cv->ary = tmp; /* update the base address of cv->ary */
    }
}

void push_backCvec( Cvec* cv, void* el )
{
    if( cv->size == cv->cap ) enlargeCvec( cv );
    /* now add in new Rec ... */
    memcpy( ((char*)cv->ary + cv->size*cv->elen), el, cv->elen );
    ++ cv->size;
}

#endif

/*

typedef struct myStudent
{
    char* name;
    int id;
} Student ;


void freeStudent( void* el )
{
    Student* p = (Student*) el;
    free( p->name );
}

typedef struct myStudent2
{
    char* fname;
    char* lname;
    int id;
} Student2 ;


void freeStudent2( void* el )
{
    Student2* p = (Student2*) el;
    free( p->lname );
    free( p->fname );
}


void showStudent( const Student* s )
{
    printf( "%s %d", s->name, s->id );
}
void showCvec( const Cvec* s )
{
    int i;
    for( i = 0; i < s->size; ++i )
        { showRec( (Student*)s->ary + i ); putchar( '\n' ); }
}

void showStudent2( const Student2* s )
{
    printf( "%s, %s :: %d", s->lname, s->fname, s->id );
}
void showCvec2( const Cvec* s )
{
    int i;
    for( i = 0; i < s->size; ++i )
        { showStudent2( (Student2*)s->ary + i ); putchar( '\n' ); }
}

*/


And now the file Cvec2_func's.h ...

Code: [Select]
/* Cvec2_func's.h */  /* 2015-06-15 */

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

/*
    this ver:   using function pointers ...
                msortCvec, isortCvec, isSortedCvec, UniqueCvec,
                isUniqueCvec, findCvec, eraseCvec (i.e. find/erase Rec)
*/

#ifndef dwCvec2_funcs_H
#define dwCvec2_funcs_H

#ifndef dwCvec2_H
#include "Cvec2.h"
#endif

void mergeCvec( Cvec* cv, int bot, int top, Cvec* tmp,
                int (*myCmp) (const void* a, const void* b) )
{
    int mid = (bot+top)/2;
    int sz = top - bot + 1;   /* size of the range to be merged */
    int j = 0;                /* next open index in tmp */
    int h1 = bot;             /* next index to consider in the 1st half */
    int h2 = mid + 1;         /* next index to consider in the 2nd half */

    /* while indexes h1 and h2 are not past their ends ... */
    while( h1 <= mid && h2 <= top )
    {   /* move the smaller element into the tmp vec next ... */
        if( myCmp( ((char*)cv->ary + h1*cv->elen), ((char*)cv->ary + h2*cv->elen) ) <= 0  )
            memcpy( ((char*)tmp->ary + cv->elen*j++), ((char*)cv->ary + cv->elen*h1++), cv->elen );
            /* tmp->ary[j++] = cv->ary[h1++]; */
        else
            memcpy( ((char*)tmp->ary + cv->elen*j++), ((char*)cv->ary + cv->elen*h2++), cv->elen );
            /* tmp->ary[j++] = cv->ary[h2++]; */
    }
    /* Note: only one, at most, of the two 'while's' below is executed ... */
    while( h1 <= mid ) /* copy any remaining entries (1st half) */
        memcpy( ((char*)tmp->ary + cv->elen*j++), ((char*)cv->ary + cv->elen*h1++), cv->elen );
        /* tmp->ary[j++] = cv->ary[h1++]; */
    while( h2 <= top ) /* copy any remaining entries (2nd half) */
        memcpy( ((char*)tmp->ary + cv->elen*j++), ((char*)cv->ary + cv->elen*h2++), cv->elen );
        /* tmp->ary[j++] = cv->ary[h2++]; */

    for( j = 0; j < sz; ++j ) /* copy back sorted tmp vec... */
        memcpy( ((char*)cv->ary +(bot+j)*cv->elen), ((char*)tmp->ary + j*cv->elen), cv->elen );
        /* cv->ary[bot+j] = tmp->ary[j]; */
}
void my_msortCvec( Cvec* cv, int bot, int top, Cvec* tmp,
               int (*myCmp) (const void* a, const void* b) )
{
    if( bot == top ) return;
    else
    {
        int mid = ( bot + top ) / 2;
        my_msortCvec( cv, bot, mid, tmp, myCmp );   /* sort the first ... */
        my_msortCvec( cv, mid+1, top, tmp, myCmp ); /* and the second half */
        mergeCvec( cv, bot, top, tmp, myCmp );      /* now merge 2 sorted chunks */
    }
}
/* *NOTE* Calling msortCvec sets the returned by ref Cvec to *** isSorted *** */
void msortCvec( Cvec* cv, int (*myCmp) (const void* a, const void* b) )
{
    if( cv->size > 1 )
    {
        Cvec tmp;
        initCvec( &tmp, cv->elen );
        reserveCvec( &tmp, cv->size ); /* Note: resets cap, BUT size still 0 */
        my_msortCvec( cv, 0, cv->size-1, &tmp, myCmp );
        free( tmp.ary ); /* only free ary mem that held copies of pointers */
    }
}


void isortCvec( Cvec* cv, int (*myCmp) (const void* a, const void* b) )
{
    int i, j;
    void* cmp = (void*) newMem( cv->elen );
    for( i = 1; i < cv->size; ++i ) /* start with an array of just the first 2 elements (if exists) */
    {
        memcpy( cmp, ((char*)cv->ary + i*cv->elen), cv->elen ); /* get copy of this new cmp pointer on each outer loop ... */
        j = i-1; /* get index of element just to the left of the above 'cmp' to start comparisons */
        while( j >= 0 && myCmp(cmp, ((char*)cv->ary+cv->elen*j)) < 0 )
        {
            memcpy( ((char*)cv->ary + cv->elen*(j+1)), ((char*)cv->ary + cv->elen*j), cv->elen ); /* copy pointer 'up' ... */
            --j; /* decrement j in preparation for next inner loop ... */
        }
        memcpy( ((char*)cv->ary + cv->elen*(j+1)), cmp, cv->elen ); /* insert pointer at index j+1 (since j was decremented above) */
    }
    free( cmp );
} /* size hasn't changed ... */


int isSortedCvec( Cvec* cv, int (*myCmp) (const void* a, const void* b) )
{
    int size = cv->size;
    while( --size )
        if( myCmp( ((char*)cv->ary + cv->elen*(size)), ((char*)cv->ary + cv->elen*(size-1)) )
            < 0 ) return 0;
    return 1;
}


void uniqueCvec( Cvec* cv, int (*myCmp) (const void* a, const void* b),
                 void (*freeVrec) (void* el) )
{
    int i = 0, j = 1;
    if( !isSortedCvec( cv, myCmp ) )
        msortCvec( cv, myCmp ); /* first make sure, name-sorted order by case */

    for( ; j < cv->size ; ++j )
    {
        if( myCmp( ((char*)cv->ary + cv->elen*i), ((char*)cv->ary + cv->elen*j) ) != 0 )
        {
            ++i;
            if( i != j ) memcpy( ((char*)cv->ary + cv->elen*i), ((char*)cv->ary + cv->elen*j),
                                  cv->elen );
        }
        else freeVrec( (char*)cv->ary + cv->elen*j );
    }

    cv->size = ++i;
}
int isUniqueCvec( Cvec* cv, int (*myCmp) (const void* a, const void* b) )
{
    int i;
    if( !isSortedCvec( cv, myCmp ) )
        msortCvec( cv, myCmp );

    for( i = cv->size-1; i > 0; --i )
        if( myCmp( ((char*)cv->ary + cv->elen*i), ((char*)cv->ary + cv->elen*(i-1)) ) == 0 )
            return 0;
    /* else ... */
    return 1;
}

/* returns index if string present, else -1 */
int findCvec( Cvec* cv, const void* rec, int (*myCmp) (const void* a, const void* b) )
{
    int i;
    for( i = 0; i < cv->size; ++i )
        if( myCmp( ((char*)cv->ary + cv->elen*i), rec ) == 0 ) return i;
    /* else if reach here ... */
    return -1;
}

/* if int index valid, erases element there */
void eraseCvec( Cvec* cv, int index, void (*freeVrec) (void* el) )
{
    /* int i; */
    if( index < 0 || index >= cv->size )
        { printf( "\nERROR! Index %d out of range 0..%d\n", index, cv->size-1 );
          return; }

    freeVrec( (char*)cv->ary + cv->elen*index ); /* needed here for dynamic memory types */

    /* copy each (set of pointers above) down one index */
    /* for( i = index; i < cv->size-1; ++i ) */
        /* memcpy(&cv->ary[i], &cv->ary[i+1], sizeof(Rec)); */
    if( index < cv->size-1 )
        memcpy( ((char*)cv->ary + cv->elen*index), ((char*)cv->ary + cv->elen*(index+1)),
                (cv->size-1-index)*cv->elen);

    /* now update size and return (by reference, since address passed in) */
    -- cv->size;
}

#endif


Now the new readLine.h

See this link for latest version:

http://developers-heaven.net/forum/index.php/topic,2580.msg2864.html#msg2864

41
Update: FREE homework help NOW available ...

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

You may also like to see these pages:
http://developers-heaven.net/forum/index.php/topic,2628.0.html
(go to Ask the Author/FAKE NEWS)

http://developers-heaven.net/forum/index.php/topic,2631.0.html
(go to Ask the Author/Breakfast ... it's time to feed at Jesus Feet ...)

http://developers-heaven.net/forum/index.php/topic,2634.0.html
(go to Ask the Author/Poems and writings to encourage)


I've been thinking recently about developing a free Beginning Bible Study/Getting to know the Heavenly Author series ... to put up on the web and to link it to my Beginning Computer Programming links ... and this seems more important each day ... as the day of the return of Yeshua/Jesus draws near.


This is the 'gist' of the start ...


How does one get to know the will of God (for their life) ?

1. Firstly, one needs to get to know God, and that will take some time ... with Him ... and seeing how wise He is ... how graciously wonderful is His gift of an assured salvation by faith in Yeshua/Jesus ... and how good His advice/laws/commands really are ... by personally experiencing the results of doing what He says ... or the devastation that comes by contravening His Laws that govern all His creation.

0. But, even before that, one needs to see that all the Creation points to an awesome and faithful Creator ... who, in the beginning, created the heaven and the earth ... and made us in such a way that we can and need to know our Creator ... and so then ... will know His amazing Love and gift of an assured eternal salvation in Yeshua/Jesus...  real life ... and love ... and purpose ... even for all eternity ahead.

2. Thus, our Creator has provided a very available written record of His acts in History, and a sure guide of things to come ... in The Book of Books, (like no other book), the Holy Bible ...and the Bible provides many instances of His general will .... and specific will for our lives ... and as He promised, He has preserved His Word for us, and will preserve it forever ... just as God has promised to preserve forever the ones who receive His Gift of Salvation, Yeshua/Jesus ... and believe His Word.

3. Also, as Yeshua/Jesus promised, the Holy Spirit of God has come ... and will forever abide with/in and teach anyone who really wants to know, so as TO DO, the will of God. Note these encouraging words of Jesus recorded in Luke 11:13 If ye then, being evil, know how to give good gifts unto your children: how much more shall your heavenly Father give the Holy Spirit to them that ask him?  ... and further explained in Acts 5:32 ... And we are his witnesses of these things; and so is also the Holy Ghost, whom God hath given to them that obey him.


Just a start ... your comments and questions are welcome.

Shalom shalom,

David
--
dwzavitz@gmail.com

42
Update:

you can contact me via this link ...

https://sites.google.com/site/andeveryeyeshallseehim/

(my/editor gmail link is on the 2nd page)



An other very common student request ...

Note the almost exact same code used for this program as for the vector program here ....
http://developers-heaven.net/forum/index.php/topic,2585.0.html
but with 'vector' changed to 'list' and ... #include <algorithm> is NOT needed here for a sort function, as the C++ library list ... comes with a list sort function built in ... Note this sort has just a slightly different sort function call for list.

The vector used ...

sort( v.begin(), v.end(), compareFunc );

but list just needs ...

lst.sort( compareFunc );

Code: [Select]
// Student_list.cpp //  // this version 2015-06-23 //

// A simple example of processing Student records ...
// using a C++ STL list container to hold each 'Student' object
// See MENU below to see what this program does ...

// Note:
// * this program allows only unique student id's for each record
// * this program is set to update its file, (if there were any changes),
//   before quitting

#include <iostream>
#include <iomanip> // re. setw(widthValue) stream manipulator
#include <fstream> // re. ostream, ofstream, ifstream objects
#include <sstream> // re. ostringstream object
#include <string>
#include <list>
#include <cctype>  // re. tolower/toupper for case insensitive comparison

// Globals ...

const char* THIS_TERM = "fall.txt"; // file name for this term's records
const std::string MENU= "\n"
                        "  1. V iew all records in memory at present\n"
                        "  2. A dd a new student name and id\n"
                        "  3. S ort student records\n"
                        "  4. E dit/E rase a student record\n"
                        "  5. L oad in student records from file\n"
                        "  6. U pdate file with records currently in memory\n"
                        "  7. e X it program\n\n"
                        "Your choice (1..7) : ";

class Student
{
public:
    // constructors ...
    Student() {} // default ctor ...
    Student( const std::string& nam, const std::string& num ) : name( nam ), id( num ) {}

    // setters ...
    void set_name( const std::string& nam ){ name = nam; }
    void set_id( const std::string& num ) { id = num; }

    // getters ...
    std::string get_name() const { return name; }
    std::string get_id() const { return id; }
private:
    std::string name, // add any needed info here, just like in a C/C++ 'struct'
                id;
           
    // Note: this name comparison is case insensitive ...
    friend bool compare_nocaseName( const Student&, const Student& );
    friend bool compare_id( const Student& a, const Student& b );

    friend std::ostream& operator << ( std::ostream& os, const Student& s )
    { return os << s.name << ", " << s.id; }
} ;


// friends defined here ... //
bool compare_id( const Student& a, const Student& b )
{ return a.id < b.id; }

// this name comparison (friend function) is NOT case sensitive ...
bool compare_nocaseName( const Student& a, const Student& b )
{
    size_t i = 0, lenNameA = a.name.length(), lenNameB = b.name.length();

    while( i < lenNameA && i < lenNameB
                        && tolower(a.name[i]) == tolower(b.name[i]) )
           ++i ;

    // ok ... now check end conditions ...
    if( i < lenNameA )
    {
        if( i < lenNameB ) return tolower(a.name[i]) < tolower(b.name[i]) ;
        else return false; // since i == lenNameB
    }

    // if reach here ...  i == lenNameA ... so check ...
    if( i < lenNameB ) return true; // since i == lenNameA

    // else we have  i == lenNameA   &&   i == lenNameB  ... so names equal
    return a.id < b.id;
}



// functions used by main to process a list of Student records

int takeInStr( const std::string& msg );
void pauseForEnter();

// returns a valid iterator if ID is used already ... otherwise returns 'end()'
std::list< Student >::iterator existID( std::list< Student >& term, const std::string& ID );

// adds Student records to end of list of Student records ... 'term'
// gets input from keyboard ...
int newStud( std::list< Student >& term );

// shows (to console screen) all student records in list container ... 'term'
void viewStuds( const std::list< Student >& term );

// file all records in memory ... create/overwrite file with name 'THIS_TERM'
int fileStuds( const std::list< Student >& term );

// reads in all Student records from file 'THIS_TERM' ... if it exists
// returns -1 if no file exists; else returns the number of records read
int readStuds( std::list< Student >& term );

// returns 'true' if a record was edited or erased; otherwise returns false
bool editStud( std::list< Student > &term );



int main() ////////////////////////// BEGIN MAIN ///////////////////////////////
{
    using namespace std;
   
    // create a 'fall list' to hold student names and ids for the 'Fall Term'
    // also holds number of records, via 'fall.size()'
    list < Student > fall;

    // now get all records from file ... if it exists ?
    int count = readStuds( fall );
    if( count >= 0 )
        cout << count << " student record(s) read into memory ..." << endl;
    else
        cout <<"(The file will be created when some student records exist.)"
             <<endl;
    bool changes = false; // set file 'update flag' to initial value ...

    for( ;; ) // loop forever ... until break ...
    {
        int reply = takeInStr( MENU );
        if( reply == '1' || reply == 'V' ) // View ...
            viewStuds( fall );
        else if( reply == '2' || reply == 'A' ) // Add ... from keyboard
        {
            int numStuds = newStud( fall );
            cout << endl << numStuds << " student record(s) added ..."
                 << " The total number of student records now is "
                 << fall.size() << endl;
            if( numStuds ) // if >0 added ... update bool variable changes
                changes = true;
        }
        else if( reply == '3' || reply == 'S' ) // Sort ... but DON'T update
                                                // 'changes' unless 'data filed'
        {
            reply = takeInStr( "\nSort by id or name  (i/n) ? " );
            if( reply == 'I' )
            {
                fall.sort(compare_id); // using case sensitive id's to sort ...
                cout << "Now sorted in memory by id. ";
            }
            else if( reply == 'N' )
            {
                fall.sort(compare_nocaseName); // using case insensitive names
                cout << "Now sorted in memory by name. ";
            }
            else
            {
                cout << "Ok ... no new sort done here ...\n";
                continue;
            }

            reply = takeInStr( "Update file (y/n) ? " );
            if( reply == 'Y' )
            {
                fileStuds( fall );
                changes = false;
                cout << "File updated ...\n";
            }
            else cout << "File NOT updated ...\n";
        }
        else if( reply == '4' || reply == 'E' )
        {
            if( editStud( fall ) )
                changes = true;
        }
        else if( reply == '5' || reply == 'L' ) // Load/Read file into memory ...
        {
            int condition = readStuds( fall );
            if(  condition >= 0 )
            {
                cout << "\nThere were " << condition
                     << " student records read into memory from file." << endl;
                changes = false;
            }
        }
        else if( reply == '6' || reply == 'U' ) // Update file from memory ...
        {
            if( !changes )
                cout << "\nNo changes to file ..." << endl;
            else
            {
                reply = takeInStr( "Are you sure you want to update"
                                  " the file (y/n) ? " );
                if( reply == 'Y' )
                {
                    if( fileStuds( fall ) != (int)fall.size() )
                        cout << "\nUNEXPECTED ERROR! NOT all records were filed!"
                             << "\nTry again ... If Error persits call IT."
                             << endl;
                    else
                    {
                        changes = false;// update file flag ...
                        cout << "File write operation confirmed." << endl;
                    }
                }
            }
        }
        else if( reply == '7' || reply == 'X' ) // eXit main show MENU/loop ...
        {   // and ...
            if( changes ) // then ...
            {
                reply = takeInStr( "Are you sure you want to update"
                                  " the file (y/n) ? " );
                if( reply == 'Y' )
                {
                    static int trys = 0;
                    if( fileStuds( fall ) != (int)fall.size() )
                    {
                        cout << "\nUNEXPECTED ERROR! NOT all records were filed!"
                             << "\nTry again ... If Error persits call IT."
                             << endl;
                        ++trys;
                        if( trys < 2 ) continue;
                    }
                    else
                    {
                        changes = false;// update file flag ...
                        cout << "File write operation confirmed." << endl;
                    }
                }
            }
            break; // and do exit program routine ...
        }
        else
        {
            cout << "\nChoice NOT implemented yet ...\n";
        } // end of if( reply == ? ) 'switch' structure ...

    } // end of main 'forever loop' ...


    // debug exit routine ...

    ifstream ftest( THIS_TERM );  // recall 'THIS_TERM' is a Global variable
    if( !ftest )
    {
        cout << "\nError attempting to open file " << THIS_TERM << " ...\n";
        pauseForEnter();
    }
    else // if reach here ...
    {
        ftest.close(); // first close file found ok above ...
        // then ... proceed ... to open the file in a system text editor ...
        // if you have a Win OS ... show structure of file
        if( 'Y' == takeInStr( "Show in notepad {y/n) ? " ) )
        {
            string tmpSee = "notepad ";
            tmpSee += THIS_TERM;
            system( tmpSee.c_str() );
        }
    }

} ///////////////////////////////// END MAIN ///////////////////////////////////


int takeInStr( const std::string& msg )
{
    std::cout << msg << std::flush;
    int reply = toupper( std::cin.get() );
    std::cin.sync();
    return reply;
}
void pauseForEnter()
{
    takeInStr( "\nPress 'Enter' to continue ... " );
}

// returns a valid iterator if ID is used already ... otherwise returns 'end()'
std::list< Student >::iterator existID( std::list< Student >& term, const std::string& ID )
{
    std::list < Student > :: iterator it;
    for( it = term.begin(); it != term.end(); ++it )
        if( it->get_id() == ID ) return it;
    // else ...
    return it; // returns term.end() ...
}

// adds Student records to end of list of Student records ... 'term'
// gets input from keyboard ...
int newStud( std::list< Student >& term )
{
    std::cout << "\nEnter an empty record to exit this 'Input Loop' ..." << std::endl;
    int count = 0;
    std::string nam, num;
    for( ;; ) // loop forever until break ...
    {
        std::cout << "\nID   : ";
        getline( std::cin, num );
        if( existID( term, num ) != term.end() )
        {
            std::cout << "\nThat 'id' " << num << " already exits ... " << std::endl;
            continue; // from the top of the forever loop right now
        }
        std::cout << "Name : ";
        getline( std::cin, nam );
        if( nam == "" || num == "")
            break;

        int reply = takeInStr( "Add or Redo (a/r) ? " );
        if( reply != 'A' )
        {
            std::cout << "Aborted ..." << std::endl;
            continue;
        }

        // ok ... create and add this record to the end of the list ...
        term.push_back( Student( nam, num ));
        ++count;
        std::cout << "Added " << count << " ..." << std::endl;
    }
    return count; // i.e. the count of added new students ...
}

// shows (to console screen) all student records in list container ... 'term'
void viewStuds( const std::list< Student >& term )
{
    std::list < Student > :: const_iterator it;
    int i = 0;
    std::cout << std::endl; // leading blank line ...
    for( it = term.begin(); it != term.end(); ++it )
    {
        std::ostringstream oss;
        oss << "list(" << std::setw(3) << std::setfill('0') << ++i << "):  " << *it;
        std::cout << std::left << std::setw(39) /*<< setfill(' ')*/ << oss.str();
        if( i % 2 == 0 ) std::cout << std::endl; // print 2 per line ...
    }
    if( i % 2 == 1 ) std::cout << std::endl; // if only a half line ... go to a new line
}

// file all records in memory ... create/overwrite file with name 'THIS_TERM'
int fileStuds( const std::list< Student >& term )
{
    std::ofstream fout( THIS_TERM );  // recall 'THIS_TERM' is a Global variable
    if( !fout )
    {
        std::cout << "\nError attempting to open file " << THIS_TERM << std::endl;
        return -1;    // report error condition ...
    }

    // else ...
    std::list < Student > :: const_iterator it;
    int i = 0;
    for( it = term.begin(); it != term.end(); ++it, ++i )
        fout << it->get_name() << "," << it->get_id() << std::endl;

    fout.close();

    if( i == (int)term.size() )
        std::cout << "\nAll " << i << " records filed ok." << std::endl;
    else
        std::cout << "\nOnly " << i << " of " << term.size()
                  << " records were written ..." << std::endl;

    return i; // report success ... i.e. report count of records filed
}

// reads in all Student records from file 'THIS_TERM' ... if it exists
// returns -1 if no file exists; else returns the number of records read
int readStuds( std::list< Student >& term )
{
    std::ifstream fin( THIS_TERM ); // recall THIS_TERM is a Global variable
    if ( !fin )
    {
        std::cout << "Error attempting to open file " << THIS_TERM
                  << " ... Perhaps it dosen't exist yet?" << std::endl;
        return -1;          // report error condition ...
    }

    // else ... check existing term.size() first before re-setting?
    if( term.size() ) // i.e. if not == 0 ...
    {
        std::cout << "\nDo you want over-write the " << term.size();
        int reply = takeInStr( " records in memory (y/n) ? " );
        if( reply != 'Y' )
        {
            std::cout << "Aborted ... " << std::flush;
            return 0;
        }
        // if reach here ...
        std::cout << "Ok ... will over-write the " << term.size()
                  << " records in memory ... " << std::flush;
    }

    // if reach here ...
    term.clear(); // set to empty list
    std::string nam, num;
    int i;
    for( i = 0; getline( fin, nam, ',' ); ++i ) // get 1st string (up to ',')
    {
        getline( fin, num, '\n' ); // then get rest of line (up to '\n')
        term.push_back( Student(nam, num) ); // construct and add new Student
    }
    fin.close();
    return i; // report success? ... i.e. return the record count ...
}

// returns 'true' if a record was edited or erased; otherwise returns false
bool editStud( std::list< Student > &term )
{
    std::cout << "\nNote: just enter an empty record to exit this 'Edit/Erase Function'"
              << "\nOk ... now enter the ID of the student record to edit : " << std::flush;
    std::string idStr, nam;
    getline( std::cin, idStr );

    std::list< Student >::iterator i, index;
    i =  existID( term, idStr );
    if( i == term.end() )
    {
        std::cout << "This '" << idStr << "' does not exist." << std::endl;
        return false;
    }

    // else ... show ... and ask if ok to edit ...
    std::cout << "Name : " << i->get_name() << std::endl
              << "ID   : " << i->get_id() << std::endl;

    int reply = takeInStr( "Abort or Edit/Erase (a/e) ? " );
    if( reply != 'E' )
    {
        std::cout << "Aborted ... " << std::endl;
        return false;
    }

    reply = takeInStr( "\nDo you want to erase this record (y/n) ? " );
    if( reply == 'Y' )
    {
        term.erase( i );
        std::cout << "Erased ...\n";
        return true;
    }


    // else ... ok ... so will edit id ... then name

    std::cout << "\nOk ... will edit ... Recall ...\n"
              << "Just enter an 'empty string' to abort/exit this edit ... "
              << "\nEnter NEW ID   : ";
    getline( std::cin, idStr );
    index = existID( term, idStr );
    if( index != term.end() && index != i ) // exclude 'i' so can edit 'i'
    {
        std::cout << "\nThe ID '" << idStr << "' already exits ... " << std::endl;
        return false; // exit to menu now ...
    }

    // ok ... get new name ...

    std::cout << "Enter NEW Name : ";
    getline( std::cin, nam );
    if( nam == "" || idStr == "" )
    {
        std::cout << "Aborted ..." << std::endl;
        return false;
    }

    reply = takeInStr( "Ok or Redo (o/r) ? " );
    if( reply != 'O' ) // cap 'O' ... as in Ok
    {
        std::cout << "Aborted ..." << std::endl;
        return false;
    }

    // ok ... so ... go ahead and edit
    i->set_name( nam );
    i->set_id( idStr );
    std::cout << "Edited ..." << std::endl;
    return true;
}

43
Update:

you can contact me via this link ...

https://sites.google.com/site/andeveryeyeshallseehim/

(my/editor gmail link is on the 2nd page)



A very common student request ... demo's ...

                    1. V iew all records in memory at present
                    2. A dd a new student name and id
                    3. S ort student records
                    4. E dit/E rase a student record
                    5. L oad in student records from file
                    6. U pdate file with records currently in memory
                    7. e X it program

Code: [Select]
// Student_vector.cpp // this version 2011-07-29 //

// A simple example of processing Student records ...
// using a C++ STL vector container to hold each 'Student' object
// See MENU below to see what this program does ...

// Note:
// * this program allows only unique student id's for each record
// * this program is set to update its file, (if there were any changes),
//   before quitting

#include <iostream>
#include <iomanip> // re. setw(widthValue) stream manipulator
#include <fstream> // re. ostream, ofstream, ifstream objects
#include <sstream> // re. ostringstream object
#include <string>
#include <vector>
#include <algorithm>
#include <cctype>  // re. tolower/toupper for case insensitive comparison

// Globals ...
using namespace std;
const char THIS_TERM[] = "fall.txt"; // file name for this term's records
const string MENU = "\n"
                    "  1. V iew all records in memory at present\n"
                    "  2. A dd a new student name and id\n"
                    "  3. S ort student records\n"
                    "  4. E dit/E rase a student record\n"
                    "  5. L oad in student records from file\n"
                    "  6. U pdate file with records currently in memory\n"
                    "  7. e X it program\n\n"
                    "Your choice (1..7) : ";

class Student
{
public:
    // Note: this name comparison is case insensitive ...
    friend bool compare_nocaseName( const Student&, const Student& );
    friend bool compare_id( const Student& a, const Student& b ) ;

    friend ostream& operator << ( ostream& os, const Student& s )
    { return os << s.name << ", " << s.id; }

    // constructors ...
    Student() {} // default ctor ...
    Student( string nam, string num ) : name( nam ), id( num ) {}

    // setters ...
    void set_name( string nam ){ name = nam; }
    void set_id( string num ) { id = num; }

    // getters ...
    string get_name() const { return name; }
    string get_id() const { return id; }
private:
    string name, // add any needed info here, just like in a C/C++ 'struct'
           id;
};


bool compare_id( const Student& a, const Student& b )
{ return a.id < b.id; }

// this name comparison (friend function) is NOT case sensitive ...
bool compare_nocaseName( const Student& a, const Student& b )
{
    size_t i = 0, lenNameA = a.name.length(), lenNameB = b.name.length();

    while( i < lenNameA && i < lenNameB
                        && tolower(a.name[i]) == tolower(b.name[i]) )
           ++i ;

    // ok ... now check end conditions ...
    if( i < lenNameA )
    {
        if( i < lenNameB ) return tolower(a.name[i]) < tolower(b.name[i]) ;
        else return false; // since i == lenNameB
    }

    // if reach here ...  i == lenNameA ... so check ...
    if( i < lenNameB ) return true; // since i == lenNameA

    // else we have  i == lenNameA   &&   i == lenNameB  ... so names equal
    return a.id < b.id;
}



// functions used by main to process a vector of Student records

int getReply( const string& msg );
void pauseForEnter();

// returns a valid iterator if ID is used already ... otherwise returns 'end()'
vector< Student >::iterator existID( vector< Student >& term, const string& ID );

// adds Student records to end of vector of Student records ... 'term'
// gets input from keyboard ...
int newStud( vector< Student >& term );

// shows (to console screen) all student records in vector container ... 'term'
void viewStuds( const vector< Student >& term );

// file all records in memory ... create/overwrite file with name 'THIS_TERM'
int fileStuds( const vector< Student >& term );

// reads in all Student records from file 'THIS_TERM' ... if it exists
// returns -1 if no file exists; else returns the number of records read
int readStuds( vector< Student >& term );

// returns 'true' if a record was edited or erased; otherwise returns false
bool editStud( vector< Student > &term );



int main() ////////////////////////// BEGIN MAIN ///////////////////////////////
{
    // create a 'fall vector' to hold student names and ids for the 'Fall Term'
    // also holds number of records, via 'fall.size()'
    vector < Student > fall;

    // now get all records from file ... if it exists ?
    int count = readStuds( fall );
    if( count >= 0 )
        cout << count << " student record(s) read into memory ..." << endl;
    else
        cout <<"(The file will be created when some student records exist.)"
             <<endl;
    bool changes = false; // set file 'update flag' to initial value ...

    for( ;; ) // loop forever ... until break ...
    {
        int reply = getReply( MENU );
        if( reply == '1' || reply == 'V' ) // View ...
            viewStuds( fall );
        else if( reply == '2' || reply == 'A' ) // Add ... from keyboard
        {
            int numStuds = newStud( fall );
            cout << endl << numStuds << " student record(s) added ..."
                 << " The total number of student records now is "
                 << fall.size() << endl;
            if( numStuds ) // if >0 added ... update bool variable changes
                changes = true;
        }
        else if( reply == '3' || reply == 'S' ) // Sort ... but DON'T update
                                                // 'changes' unless 'data filed'
        {
            reply = getReply( "\nSort by id or name  (i/n) ? " );
            if( reply == 'I' )
            {
                // using case sensitive id's to sort ...
                sort( fall.begin(), fall.end(), compare_id) ;
                cout << "Now sorted in memory by id. ";
            }
            else if( reply == 'N' )
            {
                // using case insensitive names ...
                sort(fall.begin(), fall.end(), compare_nocaseName);
                cout << "Now sorted in memory by name. ";
            }
            else
            {
                cout << "Ok ... no new sort done here ...\n";
                continue;
            }

            reply = getReply( "Update file (y/n) ? " );
            if( reply == 'Y' )
            {
                fileStuds( fall );
                changes = false;
                cout << "File updated ...\n";
            }
            else cout << "File NOT updated ...\n";
        }
        else if( reply == '4' || reply == 'E' )
        {
            if( editStud( fall ) )
                changes = true;
        }
        else if( reply == '5' || reply == 'L' ) // Load/Read file into memory ...
        {
            int condition = readStuds( fall );
            if(  condition >= 0 )
            {
                cout << "\nThere were " << condition
                     << " student records read into memory from file." << endl;
                changes = false;
            }
        }
        else if( reply == '6' || reply == 'U' ) // Update file from memory ...
        {
            if( !changes )
                cout << "\nNo changes to file ..." << endl;
            else
            {
                reply = getReply( "Are you sure you want to update"
                                  " the file (y/n) ? " );
                if( reply == 'Y' )
                {
                    if( fileStuds( fall ) != (int)fall.size() )
                        cout << "\nUNEXPECTED ERROR! NOT all records were filed!"
                             << "\nTry again ... If Error persits call IT."
                             << endl;
                    else
                    {
                        changes = false;// update file flag ...
                        cout << "File write operation confirmed." << endl;
                    }
                }
            }
        }
        else if( reply == '7' || reply == 'X' ) // eXit main show MENU/loop ...
        {   // and ...
            if( changes ) // then ...
            {
                reply = getReply( "Are you sure you want to update"
                                  " the file (y/n) ? " );
                if( reply == 'Y' )
                {
                    static int trys = 0;
                    if( fileStuds( fall ) != (int)fall.size() )
                    {
                        cout << "\nUNEXPECTED ERROR! NOT all records were filed!"
                             << "\nTry again ... If Error persits call IT."
                             << endl;
                        ++trys;
                        if( trys < 2 ) continue;
                    }
                    else
                    {
                        changes = false;// update file flag ...
                        cout << "File write operation confirmed." << endl;
                    }
                }
            }
            break; // and do exit program routine ...
        }
        else
        {
            cout << "\nChoice NOT implemented yet ...\n";
        } // end of if( reply == ? ) 'switch' structure ...

    } // end of main 'forever loop' ...


    // debug exit routine ...

    ifstream ftest( THIS_TERM );  // recall 'THIS_TERM' is a Global variable
    if( !ftest )
    {
        cout << "\nError attempting to open file " << THIS_TERM << " ...\n";
        pauseForEnter();
    }
    else // if reach here ...
    {
        ftest.close(); // first close file found ok above ...
        // then ... proceed ... to open the file in a system text editor ...
        // if you have a Win OS ... show structure of file
        if( 'Y' == getReply( "Show in notepad {y/n) ? " ) )
        {
            string tmpSee = "notepad ";
            tmpSee += THIS_TERM;
            system( tmpSee.c_str() );
        }
    }

} ///////////////////////////////// END MAIN ///////////////////////////////////


int getReply( const string& msg )
{
    cout << msg << flush;
    int reply = toupper( cin.get() );
    cin.sync();
    return reply;
}
void pauseForEnter()
{
    getReply( "\nPress 'Enter' to continue ... " );
}

// returns a valid iterator if ID is used already ... otherwise returns 'end()'
vector< Student >::iterator existID( vector< Student >& term, const string& ID )
{
    vector < Student > :: iterator it;
    for( it = term.begin(); it != term.end(); ++it )
        if( it->get_id() == ID ) return it;
    // else ...
    return it; // returns term.end() ...
}

// adds Student records to end of vector of Student records ... 'term'
// gets input from keyboard ...
int newStud( vector< Student >& term )
{
    cout << "\nEnter an empty record to exit this 'Input Loop' ..." << endl;
    int count = 0;
    string nam, num;
    for( ;; ) // loop forever until break ...
    {
        cout << "\nID   : ";
        getline( cin, num );
        if( existID( term, num ) != term.end() )
        {
            cout << "\nThat 'id' " << num << " already exits ... " << endl;
            continue; // from the top of the forever loop right now
        }
        cout << "Name : ";
        getline( cin, nam );
        if( nam == "" || num == "")
            break;

        int reply = getReply( "Add or Redo (a/r) ? " );
        if( reply != 'A' )
        {
            cout << "Aborted ..." << endl;
            continue;
        }

        // ok ... create and add this record to the end of the vector ...
        term.push_back( Student( nam, num ));
        ++count;
        cout << "Added " << count << " ..." << endl;
    }
    return count; // i.e. the count of added new students ...
}

// shows (to console screen) all student records in vector container ... 'term'
void viewStuds( const vector< Student >& term )
{
    vector < Student > :: const_iterator it;
    int i = 0;
    cout << endl; // leading blank line ...
    for( it = term.begin(); it != term.end(); ++it )
    {
        ostringstream oss;
        oss << "vector(" << setw(3) << setfill('0') << ++i << "):  " << *it;
        cout << left << setw(39) /*<< setfill(' ')*/ << oss.str();
        if( i % 2 == 0 ) cout << endl; // print 2 per line ...
    }
    if( i % 2 == 1 ) cout << endl; // if only a half line ... go to a new line
}

// file all records in memory ... create/overwrite file with name 'THIS_TERM'
int fileStuds( const vector< Student >& term )
{
    ofstream fout( THIS_TERM );  // recall 'THIS_TERM' is a Global variable
    if( !fout )
    {
        cout << "\nError attempting to open file " << THIS_TERM << endl;
        return -1;    // report error condition ...
    }

    // else ...
    vector < Student > :: const_iterator it;
    int i = 0;
    for( it = term.begin(); it != term.end(); ++it, ++i )
        fout << it->get_name() << "," << it->get_id() << endl;

    fout.close();

    if( i == (int)term.size() )
        cout << "\nAll " << i << " records filed ok." << endl;
    else
        cout << "\nOnly " << i << " of " << term.size()
             << " records were written ..." << endl;

    return i; // report success ... i.e. report count of records filed
}

// reads in all Student records from file 'THIS_TERM' ... if it exists
// returns -1 if no file exists; else returns the number of records read
int readStuds( vector< Student >& term )
{
    ifstream fin( THIS_TERM ); // recall THIS_TERM is a Global variable
    if ( !fin )
    {
        cout << "Error attempting to open file " << THIS_TERM
             << " ... Perhaps it dosen't exist yet?" << endl;
        return -1;          // report error condition ...
    }

    // else ... check existing term.size() first before re-setting?
    if( term.size() ) // i.e. if not == 0 ...
    {
        cout << "\nDo you want over-write the " << term.size();
        int reply = getReply( " records in memory (y/n) ? " );
        if( reply != 'Y' )
        {
            cout << "Aborted ... " << flush;
            return 0;
        }
        // if reach here ...
        cout << "Ok ... will over-write the " << term.size()
             << " records in memory ... " << flush;
    }

    // if reach here ...
    term.clear(); // set to empty vector
    string nam, num;
    int i;
    for( i = 0; getline( fin, nam, ',' ); ++i ) // get 1st string (up to ',')
    {
        getline( fin, num, '\n' ); // then get rest of line (up to '\n')
        term.push_back( Student(nam, num) ); // construct and add new Student
    }
    fin.close();
    return i; // report success? ... i.e. return the record count ...
}

// returns 'true' if a record was edited or erased; otherwise returns false
bool editStud( vector< Student > &term )
{
    cout << "\nNote: just enter an empty record to exit this 'Edit/Erase Function'"
         << "\nOk ... now enter the ID of the student record to edit : "
         << flush;
    string idStr, nam;
    getline( cin, idStr );

    vector< Student >::iterator i, index;
    i =  existID( term, idStr );
    if( i == term.end() )
    {
        cout << "This '" << idStr << "' does not exist." << endl;
        return false;
    }

    // else ... show ... and ask if ok to edit ...
    cout << "Name : " << i->get_name() << endl
         << "ID   : " << i->get_id() << endl;

    int reply = getReply( "Abort or Edit/Erase (a/e) ? " );
    if( reply != 'E' )
    {
        cout << "Aborted ... " << endl;
        return false;
    }

    reply = getReply( "\nDo you want to erase this record (y/n) ? " );
    if( reply == 'Y' )
    {
        term.erase( i );
        cout << "Erased ...\n";
        return true;
    }


    // else ... ok ... so will edit id ... then name

    cout << "\nOk ... will edit ... Recall ...\n"
         << "Just enter an 'empty string' to abort/exit this edit ... "
         << "\nEnter NEW ID   : ";
    getline( cin, idStr );
    index = existID( term, idStr );
    if( index != term.end() && index != i ) // exclude 'i' so can edit 'i'
    {
        cout << "\nThe ID '" << idStr << "' already exits ... " << endl;
        return false; // exit to menu now ...
    }

    // ok ... get new name ...

    cout << "Enter NEW Name : ";
    getline( cin, nam );
    if( nam == "" || idStr == "" )
    {
        cout << "Aborted ..." << endl;
        return false;
    }

    reply = getReply( "Ok or Redo (o/r) ? " );
    if( reply != 'O' ) // cap 'O' ... as in Ok
    {
        cout << "Aborted ..." << endl;
        return false;
    }

    // ok ... so ... go ahead and edit
    i->set_name( nam );
    i->set_id( idStr );
    cout << "Edited ..." << endl;
    return true;
}

44
This C function let's you readily split a C string into a Clist of words (tokens - dynamic C strings), using your supplied DELIMITS string ...

Links to some example programs that demo the use of split.h ... follow ...

Code: [Select]
/* split.h */  /* this version: 2016-10-09 */


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


#ifndef dwSPLIT_H
#define dwSPLIT_H

#ifndef DELIMITS
#define DELIMITS  " \t"
#endif

#define NUM_DLMTS  sizeof(DELIMITS) -1


/* adds readLine.h which adds stdio.h, stdlib.h, string.h, myAssert, newCopy */
#include "ClistOfString.h" /* also adds "Clist.h" */

#ifndef PUSH_CLIST
#define PUSH_CLIST  push_backClist
#endif


void split( Clist* lst, const char* p1 )
{
    const char* p2;
    Node ml; /* ml is really a ... node/element/record in a Node ... */
    for( ; ; ) /* loop forever ... until break */
    {
        while( *p1 != 0 && strchr(DELIMITS, *p1) ) ++p1;
        if( *p1 == 0 ) break; /* i.e. if empty or all delimits */

        p2 = p1+1;
        while( *p2 != 0 && !strchr(DELIMITS, *p2) ) ++p2;
        ml.str = newsubstr( p1, 0, p2-p1 );
        PUSH_CLIST( lst, &ml ); /* default is push_backClist */
        p1 = p2;
    }
}


#endif


45
Update:  please see this next link:

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

you can contact me via this link ...

https://sites.google.com/site/andeveryeyeshallseehim/

(my/editor gmail link is on the 2nd page)


Ok ... here are some example programs that use the new FUNCTION POINTERS in Clist_func's.h ...

You can download a zipped file of all the (OLD) Clist.h files you need below at this next link ...
http://www.4shared.com/account/dir/eXSprBq0/_online.html#dir=104184790

The first example demos a Clist of Rec's (a struct with 3 dynamic memory C string data items) ...
Look here for a C++ STL list version ... to compare ...
http://developers-heaven.net/forum/index.php/topic,2583.msg2890.html#msg2890

Code: [Select]
/* employeeRec's_msortClist_func's.h.c */  /* this version: 2016-10-13 */


/*
    in the following:
        a List is a Node ( struct),
        a pList (i.e. List*) holds the address of a Node
        a Clist is the struct hold ing addresses of 'start' & 'end' Nodes, etc.
        a Clist* holds the address of the struct Clist
*/

/* 'C++ list emulation' using a C Clist struct ... (see demo MENU below) */


#include "takeInLIne.h" /* also includes readLine.h, stdio.h, stdlib.h, string.h and defines
                         functions myAssert and newCopy. etc...  */

#define FILENAME "employeeRecords.txt"

#define MENU      " 1. Enter a new record. \n" \
                  " 2. Retrieve a record by name (ignore case). \n" \
                  " 3. Retrieve a record by phone number. \n" \
                  " 4. Show all records. \n" \
                  " 5. Insert sort all records by name (ignore case). \n" \
                  " 6. Insert sort all records by phone number. \n" \
                  " 7. Chop exact duplicates from records (use case). \n" \
                  " 8. Edit/Delete a record. \n" \
                  " 9. Write new file of sorted unique records. \n" \
                  "10. Exit \n"
#define PROMPT    "Enter a number in range 1 to 10 : "


typedef struct employeeRec
{
    char* name;     /* since CStrings are '\0' terminated ... can get strlen */
    char* address;  /* ditto above ... */
    char* phone;    /* 3 digit area-code  +  7 digits  +  '\0'  at end */
    struct employeeRec* next;
} Node ;

typedef Node* pNode;

void clearNode( pNode r )
{
    free( r->phone );
    free( r->address );
    free( r->name );
}


/* Now can ... */
#include "Clist.h"

/* and then can ...*/
#include "Clist_func's.h"


void show( const pNode r )
{
    char phFormated[] = "(###) ###-####";
    char* p = phFormated;
    char* s = r->phone;
    for( ; *p && *s; ++p ) if( *p == '#' ) { *p = *s; ++s; }
    printf
    (
        "%-22s  %-30s  %s\n",
        r->name, r->address, phFormated
    );
}
void showAll( const Clist* list )
{
    int i = 0;
    pNode p = list->start;
    for( ; p != NULL; p = p->next )
    {
        printf("<%03d> ", ++i);
        show( p );
        if( i % 5 == 0 && i != list->size ) putchar('\n');
    }
    printf( "\nEmployee records on file = %d\n\n", list->size );
}

/* ignore case compare function ... */
int strcmpIgnoreCase( const char* s1, const char* s2 )
{
    for( ; *s1 != 0 && *s2 != 0; ++s1, ++s2 )
    {
        if( tolower(*s1) != tolower(*s2) ) break;
    }
    /* ok ... check the end conditions ... */
    return tolower(*s1) - tolower(*s2);
}
int cmpIgnoreCase( const pNode x, const pNode y )
{
    int compare1 = strcmpIgnoreCase( x->name, y->name ); /* first compare names */
    if( compare1 == 0 ) /* if the same ... */
    {
        int compare2 = strcmpIgnoreCase( x->address, y->address ); /* then address */
        if( compare2 == 0 ) /* if the same ... */
            return strcmp( x->phone, y->phone ); /* then phone number ... */
        /* else ...*/
        return compare2; /* use addresses after all  ... */
    }
    /* else ... */
    return compare1; /* use names afer all ... since names were NOT the same */
}
int cmpPhone( const pNode x, const pNode y )
{
    int compare1 = strcmp( x->phone, y->phone ); /* first compare phones */
    if( compare1 == 0 ) /* if the same ... */
    {
        int compare2 = strcmp( x->name, y->name ); /* then names */
        if( compare2 == 0 ) /* if the same ... */
            return strcmp( x->phone, y->phone ); /* then adress ... */
        /* else ...*/
        return compare2; /* use names after all  ... */
    }
    /* else ... */
    return compare1; /* use phones afer all ... since were NOT the same */
}
int cmp( const pNode x, const pNode y )
{
    int compare1 = strcmp( x->name, y->name ); /* first compare names */
    if( compare1 == 0 ) /* if the same ... */
    {
        int compare2 = strcmp( x->address, y->address ); /* then address */
        if( compare2 == 0 ) /* if the same ... */
            return strcmp( x->phone, y->phone ); /* then phone number ... */
        /* else ...*/
        return compare2; /* use addresses after all  ... */
    }
    /* else ... */
    return compare1; /* use names afer all ... since names were NOT the same */
}


/* with these, an address is passed, so NO copy made and/or original updated */
void readFile( Clist* );
int showMenuExecuteChoice( Clist* );
int isValidPhoneNum( const char* );
pNode getNameIgnoreCase( Clist*, const char* );
pNode getNumber( Clist*, const char* );
void takeInNewRec( pNode );
void takeInRecAndFile( Clist* );
void writeSortedUnique( Clist* );
void editDel( Clist* );
void edit( Clist*, pNode );
void del( Clist*, pNode );




int main() /* ************* MAIN BEGINS ***************** */
{
    int choice;
    Clist cl;
    initClist( &cl ); /* passing the address of cl so object gets updated */
    readFile( &cl );  /* passing the address of cl so object gets updated */
    if( cl.size == 0 )
        printf
        (
            "File %s will be created after data has been entered.\n",
            FILENAME
        );
    /* else showAll( &cl ); //// passing address to avoid making another copy */
   
    printf( "Now cl.start = 0x%p ... cl.size = %d\n\n", (void*)cl.start, cl.size );
   
    do
    {
        showAll( &cl ); /* passing address to avoid making another copy */
        choice = showMenuExecuteChoice( &cl ); /* passing address ... */
        putchar( '\n' );
    }
    while( choice != 10 ); /* i.e. exit on choice of 10 ...  */
   
    clearClist( &cl ); /* free all dynamic memory when done with it ... */
   
    printf( "\nNow cl.start = 0x%p ... cl.size = %d\n", (void*)cl.start, cl.size );

    /* if using windows ... can do this ... especially while debugging ... */
    system( "notepad " FILENAME );
    return 0;
} /* ***************** MAIN ENDS ************************ */



void readFile( Clist* list )
{
    FILE* fp = fopen(FILENAME, "r");
    if( fp )
    {
        Node d;
        while
        (
            (d.name = readLine(fp)) &&
            (d.address = readLine(fp)) &&
            (d.phone = readLine(fp))
        )
        {
            push_frontClist( list, &d );
        }
        fclose( fp );
    }
    else
        printf( "File %s NOT found ...\n", FILENAME );
}


int showMenuExecuteChoice( Clist* list )
{
    int num;
    char* tmp = NULL;

    fputs( MENU, stdout );
    num = takeInIntMinMax( PROMPT, 1, 10 );

    if( num == 1 ) takeInRecAndFile( list );
    else if( num == 2 )
    {
        pNode pd = NULL;
        fputs( "Enter the name to find: ", stdout );
        tmp = readLine(stdin);
        if( (pd = getNameIgnoreCase( list, tmp )) == NULL )
            printf( "%s not found.\n", tmp );
        else
            show( pd );
        free( tmp );
    }
    else if( num == 3 )
    {
        pNode pd;
        fputs( "Enter the number to find: ", stdout );
        tmp = readLine(stdin);
        if( (pd = getNumber( list, tmp )) == NULL )
            printf( "%s not found.\n", tmp );
        else
            show( pd );
        free( tmp );
    }
    /* else if( num == 4 ) showAll( list ); */
    else if( num == 5 ) isortClist( list, cmpIgnoreCase );
    else if( num == 6 ) isortClist( list, cmpPhone );
    else if( num == 7 ) uniqueClist( list, cmp );
    else if( num == 8 ) editDel ( list );
    else if( num == 9 ) writeSortedUnique( list );
    /* else is 10 ... so will exit ... */
   
    return num;
}

/* validates that 10 char's are present and all are numeric ... */
int isValidPhoneNum( const char* ph )
{
    if( strlen(ph) != 10 ) return 0;
    for( ; *ph != 0; ++ph )
        if( *ph < '0' || *ph >'9' ) return 0;
    return 1;
}

/* returns index ... if found ... otherwise , returns -1 if NOT found */
pNode getNameIgnoreCase( Clist* Clist, const char* nameStr )
{
    pNode pr = Clist->start;
    for( ; pr != NULL; pr = pr->next )
        if( strcmpIgnoreCase(pr->name, nameStr) == 0 ) return pr;
    return NULL;
}

pNode getNumber( Clist* Clist, const char* numStr )
{
    pNode pr = Clist->start;
    for( ; pr != NULL; pr = pr->next )
        if( strcmp(pr->phone, numStr) == 0 ) return pr;
    return NULL;

}

void takeInNewRec( pNode r )
{
    r->name = strToTitleCase(takeInLine( "Enter name: " ));
    r->address = strToTitleCase(takeInLine( "Enter address: " ));
    for( ; ; )
    {
        r->phone = takeInLine( "Enter telephone: "  );
        if( isValidPhoneNum(r->phone) ) return;
        /* else ... */
        fputs( "Only 10 digit number valid here ... ", stdout );
        free( r->phone );
    }
}

void takeInRecAndFile( Clist* list )
{
    Node d;
    takeInNewRec( &d );
 
    /* Now we have good data ... so file and add to vector if ok ?  */
    if( tolower(takeInChar( "Ok ... (y/n) ? " )) == 'y' )
    {
        FILE* pFile = fopen( FILENAME, "a" );
        myAssert( (pFile != NULL), "Error: " FILENAME " not opened." );
       
        fprintf( pFile, "%s\n",  d.name );
        fprintf( pFile, "%s\n", d.address );
        fprintf( pFile, "%s\n", d.phone );
       
        push_backClist( list, &d );
        fclose( pFile );
        printf( "Information has been filed in file %s.\n", FILENAME );
    }
    else
    {
        puts( "Aborted ..." );
        clearNode( &d );
    }
}

void writeSortedUnique( Clist* list )
{
    pNode pd;
    int i = 0;
    FILE* fp = fopen( "SU" FILENAME, "w" ); /* compiler concat's these TEXTs */
    myAssert( (fp != NULL), "Error: file SU" FILENAME " failed to open." );
   
    /* ok ... file is open ... so write all rec's to file ..*/
   
    /* first ... make sure sorted and unique */
    uniqueClist( list, cmp );
    for( pd = list->start; pd != NULL; pd = pd->next )
    {
        fprintf( fp, "<%03d> ", ++i );
        fprintf( fp, "%-24s ", pd->name );
        fprintf( fp, "%-32s ", pd->address );
        fprintf( fp, "%s\n", pd->phone );
        if( i % 5 == 0 ) fputs( "\n", fp );
    }
    fclose( fp ); /* flushes buffer ... so all written to file now ... */
    printf( "\n%d records filed in file SU%s list size %d\n\n",
            i, FILENAME,  list->size );
   
    /* and if have Windows OS ... can do this ... */
    system( "notepad SU" FILENAME ); /*compiler concat's text at compile time*/
}

void editDel( Clist* list )
{
    for( ; ; )
    {
        pNode pd;
        char* tmp;
        int reply = tolower(takeInChar( "Find by Name/Phone/Abort (n/p/a) ? " ));
        if( reply == 'n' )
        {
            fputs( "Enter the name to find: ", stdout );
            tmp = readLine(stdin);
            if( (pd = getNameIgnoreCase( list, tmp )) == NULL )
                printf( "%s not found.\n", tmp );
            else
            {
                show( pd );
                reply = tolower(takeInChar( "Edit/Delete/Abort (e/d/a) ? " ));
                if( reply == 'e' ) edit( list, pd );
                else if( reply == 'd' ) del( list, pd );
                else if( reply == 'a' )
                {
                    puts( "Ok, edit/delete aborted ..." );
                    free( tmp );
                    break;
                }
            }
            free( tmp );
        }
        else if( reply == 'p' )
        {
            fputs( "Enter the number to find: ", stdout );
            tmp = readLine(stdin);
            if( (pd = getNumber( list, tmp )) == NULL )
                printf( "%s not found.\n", tmp );
            else
            {
                show( pd );
                reply = tolower(takeInChar( "Edit/Delete/Abort (e/d/a) ? " ));
                if( reply == 'e' ) edit( list, pd );
                else if( reply == 'd' ) del( list, pd );
                else if( reply == 'a' )
                {
                    puts( "Ok, edit/delete aborted ..." );
                    free( tmp );
                    break;
                }
            }
            free( tmp );
        }
        else if( reply == 'a' )
        {
            puts( "Ok, edit/delete aborted ..." );
            break;
        }
        else fputs( "Only n/p/a are valid ... ", stdout );
    }
}

void edit( Clist* list, pNode pd )
{
    Node d;
    for( ; ; )
    {
        takeInNewRec( &d );
       
        /* ok ... we have some new data ... */
        if( tolower(takeInChar( "Ok ... (y/n) ? " )) == 'y' )
        {
            /* then edit ... but first free old ...  */
            clearNode( pd );

            pd->name = d.name;
            pd->address = d.address;
            pd->phone = d.phone;

            list->isSorted = 0;
            break;
        }
        else
        {
            puts( "Aborted ..." );
            clearNode( &d );
            break;
        }
    }
}

void del( Clist* list, pNode pd )
{
    for( ; ; )
    {
        int reply = tolower(takeInChar( "Really delete/abort (d/a) ? " ));
        if( reply == 'a' )
        {
            puts( "Delete aborted ..." );
            break;
        }
        else if( reply == 'd' )
        {
            eraseClist( list, pd );
            break;
        }
        /* else ... */
        fputs( "Enter 'd' and WILL delete ... or 'a' to abort ... \n", stdout );
    }
}

You will also need these 3 files before you compile the above ...

readLine.h   
http://developers-heaven.net/forum/index.php/topic,2580.msg2864.html#msg2864

Clist.h
http://developers-heaven.net/forum/index.php/topic,2582.msg2877.html#msg2877

Clist_func's.h   
http://developers-heaven.net/forum/index.php/topic,2582.msg2883.html#msg2883

You may also like to see this ...
http://www.dreamincode.net/forums/topic/248797-phonebook-in-c-questions/page__view__findpost__p__1446935

Pages: 1 2 [3] 4 5