Desktop Programming > C/C++ & Visual C++

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

(1/4) > >>

David:
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 students beginning C or C++ ... this page is for you to get help with your beginning computer programming problems in C or C++.

Please include your code inside code tags ...

After you click on the Reply icon below, on the new page presented to you to write about your problem and submit your code ...
Click on the above # icon to ....

--- Code: ---  // your code goes here ... //
--- End code ---

insert your code between these two start and stop code tags ...[ code ] // your code goes here ... // [ /code ]  Only don't add spaces inside the tags as I did here, so that you could SEE something of what code tags look like.  The code tags will preserve the indentation of your C/C++ code.

Please include a statement of the problem given and the problem(s) you are having ... and allow some time for a reply, as this help is being offered on a trial experimental gratuitous basis.

BEFORE you click on Post/Save at the bottom of your page, please click on Preview ...

and make sure you correct any typos ...

and that the problem is stated clearly ...

using good grammar and helpful punctuation.


Shalom shalom,

David

David:
Here is an example, to follow please :) ... and to get started ...

This student problem, is to code in C, merging two arrays of integers into a 3rd array so that the 3rd array only has unique elements ... i.e. a value occurs at most once in the 3rd array of merged values ... and the values are to be entered into the first two arrays from the keyboard.

Below is an example of some working code to start ... (i.e. a working shell to get started.)


--- Code: ---/* mergeTwoArysStep1.c */

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

#include <stdio.h>

#define MAX_SIZE 5 /* keep this number small while still testing/debugging */

void printAry( const int ary[], int num )
{
    int i;
    for( i = 0; i < num; ++i )
        printf( "%d ", ary[i] );
}

int main()
{
    /* create some arrays to hold your test data and the merged unique data */
    int ary1[MAX_SIZE], ary2[MAX_SIZE], ary3[2*MAX_SIZE];
   
    int i;
    for( i = 0; i < MAX_SIZE; ++i )
    {
        printf( "For ary1, enter integer %d: ", i+1 ); fflush( stdout );
        scanf( "%d", &ary1[i] );
        printf( "For ary2, enter integer %d: ", i+1 ); fflush( stdout );
        scanf( "%d", &ary2[i] );
        ary3[i] = ary1[i];
        ary3[MAX_SIZE+i] = ary2[i];
    }
   
    while( getchar() != '\n' ) ; /* flush stdin ... */
   
    printf( "\nary1 is: " );
    printAry( ary1, MAX_SIZE );

    printf( "\nary2 is: " );
    printAry( ary2, MAX_SIZE );

    printf( "\nary3 is: " );
    printAry( ary3, 2*MAX_SIZE );

    fputs( "\nPress 'Enter' to continue/exit ... ", stdout); fflush( stdout );
    getchar(); /* keep 'Window' open until 'Enter' key is pressed ... */
    return 0;
}

--- End code ---

A very common student problem at this stage is that the code compiles and runs ... but the student can't SEE any output because the window closes so quickly upon running ... because this following line, (or equivalent coding), was left off ...


--- Code: ---while( getchar() != '\n' ) ; /* flush stdin ... */
--- End code ---

Recall that scanf, when used to get a number from keyboard, skips over any leading whitespace, gets the number (if there), but stops AND LEAVES any trailing whitespace char's (like the '\n' char), or all char's after any non-numeric char's accidently entered, in the stdin buffer ...

So then the getchar() at the end of the program, gets that first whitespace char, or non-numeric char, still left in the stdin buffer, and thus will NOT WAIT for the Enter key to be pressed before exiting your program.

So, the goal here, as a first step, is to get some working code ... and some output THAT YOU CAN SEE IS the EXACT expected output for your test input.

Then you can add/edit from this starting working code ... to move ever closer to the full functionality you desire in your final program.

Note the 3rd array here contains ALL the values in arrays 1 and 2, but that is ok for now.

Note also that if the first non-whitespace char entered is a NON numeric char, this program will crash.  A way to handle numeric input, to avoid crashes on invalid input, follows below.

David:
The version below adds validation to your integer input from the keyboard, so that your program will not crash on bad input.  Also, each array is entered separately, and will accept data up to the maximum size permitted at compile time.

This is just one way to handle this problem.  Another way, see below, might be to add all array 1 to array 3 ... then add after that, all of array 2 to array 3 ... then to transform array 3 into an array of unique elements, perhaps by way of first sorting it ...


--- Code: ---/* mergeTwoArys2.c */

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

#include <stdio.h>

#define MAX_SIZE 5 /* keep small while testing/debugging ... */

int more()/* defaults to 'true'/'yes'/'1' ... unless 'n' or 'N' entered ... */
{
    int c, reply;
    fputs( "More (y/n) ? ", stdout ); fflush( stdout );
    reply = c = getchar();
    while( c != '\n' ) c = getchar(); /* 'flush' stdin buffer ...  */
    if( reply == 'n' || reply == 'N' ) return 0;
    /* else ... */
    return 1;
}

/* returns the entered array ('by reference') and the size of the array entered,
   size can be in range 0..max */
int enterAry( const char prompt[], int ary[], int max )
{
    int i = 0, numGoodVals;
    printf( "%s (max size %d)\n", prompt, max ); fflush( stdout );
    do
    {
        printf( "enter integer %d: ", i+1 ); fflush( stdout );
        numGoodVals = scanf( "%d", &ary[i] );
        while( getchar() != '\n' ) ; /* flush stdin ... */
        if( numGoodVals != 1 )
        {
            printf( "Please enter only integers ...\n" );
            continue; /* jump to test at end of do..while loop right NOW! */
        }
        /* else ... */
        ++i;
        if( i == max ) break;
    }while( more() );

    return i; /* the number of int's entered ... 'i' is in range 0..max */
}

void printAry( const int ary[], int num )
{
    int i;
    for( i = 0; i < num; ++i )
        printf( "%d ", ary[i] );
}


int exist( const int ary[], int size, int val )
{
    int i;
    for( i = 0; i < size; ++i )
        if( ary[i] == val ) return 1;

    return 0;
}


int main()
{
    int ary1[MAX_SIZE], ary2[MAX_SIZE], ary3[2*MAX_SIZE],
        i, size1, size2, size3;
   
    size1 = enterAry( "Enter ary1 ...", ary1, MAX_SIZE );
    size2 = enterAry( "Enter ary2 ...", ary2, MAX_SIZE );
   
    printf( "\nary1 is: " ); printAry( ary1, size1 );
   
    printf( "\nary2 is: " ); printAry( ary2, size2 );
   
    size3 = 0;
    for( i = 0; i < size1; ++i )
    {
        if( !exist(ary3, size3, ary1[i]) )
        {
            ary3[size3] = ary1[i];
            ++ size3;
        }
    }

    for( i = 0; i < size2; ++i )
    {
        if( !exist(ary3, size3, ary2[i]) )
        {
            ary3[size3] = ary2[i];
            ++ size3;
        }
    }

    printf( "\nary3 is: " ); printAry( ary3, size3 );
   
    fputs( "\nPress 'Enter' to continue/exit ... ", stdout); fflush( stdout );
    getchar(); /* keep 'Window' open until 'Enter' key is pressed ... */
    return 0;
}

--- End code ---

Here is that other way that was suggested that you might proceed ... solving this problem by merging two arrays into a new array of sorted unique elements ...


--- Code: ---/* mergeTwoArysStep2_a.c */

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

#include <stdio.h>

#define SIZE 5

void printAry( const int ary[], int num )
{
    int i;
    for( i = 0; i < num; ++i )
        printf( "%d ", ary[i] );
}

void bubblesort( int ary[], int size )
{
    int j, swap, tmp;
    do
    {
        swap = 0; // if array is sorted ... then DONE after the next pass
        // only have to check, each loop, up to to size-1 places
        for( j = 1; j < size; ++j )
        {
            if( ary[j-1] > ary[j] ) // swap value at j-1 with value at j
            {
                tmp = ary[j];
                ary[j] = ary[j-1];
                ary[j-1] = tmp;
                swap = 1;
            }
        }
        --size;
    }while( swap );
}

int getUnique( int ary[], int size )
{
    int i = 0, j =1;
    for( ; j < size ; ++j )
    {
        if( ary[i] != ary[j] ) if( ++i != j ) ary[i] = ary[j];
    }
    return i+1; // return updated size, now of unique elements
}



int main()
{
    int i, unique, ary1[SIZE], ary2[SIZE], ary3[2*SIZE];
   
    for( i = 0; i < SIZE; ++i )
    {
        printf( "For ary1, enter integer %d: ", i+1 ); fflush( stdout );
        scanf( "%d", &ary1[i] );
        printf( "For ary2, enter integer %d: ", i+1 ); fflush( stdout );
        scanf( "%d", &ary2[i] );
        ary3[i] = ary1[i];
        ary3[SIZE+i] = ary2[i];
    }
    while( getchar() != '\n' ) ; /* flush stdin ... */
   
    printf( "\nary1 is: " );
    printAry( ary1, SIZE );
   
    printf( "\nary2 is: " );
    printAry( ary2, SIZE );
   
    printf( "\nary3 is: " );
    printAry( ary3, 2*SIZE );
   
    bubblesort( ary3, 2*SIZE );
    printf( "\nary3 sorted is: " );
    printAry( ary3, 2*SIZE );

    unique = getUnique( ary3, 2*SIZE );
    printf( "\nunique ary3 size is %d and ary3 is: ", unique );
    printAry( ary3, unique );

    fputs( "\nPress 'Enter' to continue/exit ... ", stdout); fflush( stdout );
    getchar(); /* keep 'Window' open until 'Enter' key is pressed ... */
    return 0;
}

--- End code ---

David:
This version demos using dynamic arrays ... sort (just a simple bubble sort here) ... and unique functions ...


--- Code: ---/* mergeTwoArysStep3.c */ /* using dynamic arrays, sort and unique functions */

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

#include <stdio.h>
#include <stdlib.h>

int more()/* defaults to 'true'/'yes'/'1' ... unless 'n' or 'N' entered ... */
{
    int c, reply;
    fputs( "More (y/n) ? ", stdout ); fflush( stdout );
    reply = c = getchar();
    while( c != '\n' ) c = getchar(); /* 'flush' stdin buffer ...  */
    if( reply == 'n' || reply == 'N' ) return 0;
    /* else ... */
    return 1;
}

int getValidInt( const char prompt[] )
{
    for( ; ; ) /* an example of a C/C++ forever loop ... until 'return' */
    {
        int numGood, testInt;
        fputs( prompt, stdout ); fflush( stdout );
        numGood = fscanf( stdin, "%d", &testInt );
        while( getchar() != '\n' ); /* 'flush' stdin ... as we go ... */
        if( numGood == 1 ) return testInt;
        /* else ... */
        puts( "Invalid input! Integers only please ..." );
    }
}

/* get memory to hold an array of size int's .. and return pointer to memory */
int* getIntAryMemory( int size )
{
    int* ary = malloc( sizeof(int)*size );
    if( ary == NULL )
    {
        fprintf( stderr,
                 "malloc failed in 'getIntAryMemory' for size = %d\n", size );
        fputs( "Press 'Enter' to continue/exit ... ", stderr );
        getchar();
        exit(1);
    }
    else return ary; // returns pointer to new array
}

/* Note:
   any unused array memory in function below is NOT accessable after exiting
   the function unless the 'max' value is returned, (NOTE: 'size' returned here)
*/
/* returns filled new array and the size of the new array entered ... */
int enterAry( const char prompt[], int** ary ) /* passing in pointer to pointer */
{
    int i = 0;
    int max = getValidInt( "Enter max size for this array of integers: " );
    *ary = getIntAryMemory( max ); /* de-reference address to get to pointer */
    do
    {
        printf( "Enter integer %d: ", i+1 );
        (*ary)[i++] = getValidInt( "" );
        if( i == max )
        {
            printf( "You have reached the maximum size of %d elements "
                    "for this array.\n", max );
            break;
        }
    }while( more() );

    return i; /* i hold the number of int's entered ... i is in range 0..max */
}



void printAry( const int ary[], int num )
{
    int i;
    for( i = 0; i < num; ++i )
        printf( "%d ", ary[i] );
}

void bubblesort( int ary[], int size )
{
    int j, swap, tmp;
    do
    {
        swap = 0; /* if array is sorted ... then DONE after the next pass */
        /* only have to check, each loop, up to to size-1 places */
        for( j = 1; j < size; ++j )
        {
            if( ary[j-1] > ary[j] ) /* swap value at j-1 with value at j */
            {
                tmp = ary[j];
                ary[j] = ary[j-1];
                ary[j-1] = tmp;
                swap = 1;
            }
        }
        --size;
    }while( swap );
}

int getUnique( int ary[], int size )
{
    int i = 0, j = 1;
    for( ; j < size ; ++j )
    {
        if( ary[i] != ary[j] ) if( ++i != j ) ary[i] = ary[j];
    }
    return i+1; // return updated size, now of unique elements
}



int main()
{
    /* Note: below ... ary1, ary2, ary3 are pointers to int,
       i.e. variables to hold the address of an int,
       or the address to the first int in a block (an array) of int's */
    int *ary1, *ary2, *ary3, i, size1, size2, size3, uniqueSize;

    size1 = enterAry( "Enter ary1 ...", &ary1 ); /* passing in a 'reference' */
    putchar( '\n' );
    size2 = enterAry( "Enter ary2 ...", &ary2 ); /* i.e. pass in pointer address */
   
    printf( "\nary1 is: " ); printAry( ary1, size1 );
    printf( "\nary2 is: " ); printAry( ary2, size2 );
   
    size3 = size1 + size2;
    ary3 = getIntAryMemory( size3 ); /* get memory to hold array 3 ... */
   
    /* copy ary1 into first part of ary3 */
    for( i = 0; i < size1; ++i )
        ary3[i] = ary1[i];
    /* copy ary2 into last part of ary3 */
    for( i = 0; i < size2; ++i )
        ary3[size1+i] = ary2[i];
       
    printf( "\nary3 is: " );
    printAry( ary3, size3 );
   
    bubblesort( ary3, size3 );
    printf( "\nary3 sorted is: " );
    printAry( ary3, size3 );

    uniqueSize = getUnique( ary3, size3 );
    printf( "\nunique ary3 size is %d and unique ary3 is ", uniqueSize );
    printAry( ary3, uniqueSize );
   
    /* free all dynamic memory when done with it ...*/
    free( ary3 );
    free( ary2 );
    free( ary1 );

    fputs( "\nPress 'Enter' to continue/exit ... ", stdout); fflush( stdout );
    getchar(); /* keep 'Window' open until 'Enter' key is pressed ... */
    return 0;
}

--- End code ---

David:
This next version is an upgrade of the previous version that used dynamic arrays ...  Here we are using a C vector (Cvec) structure which is really just a fancied up and re-usable dynamic array structure ... that tracks the size, the cap (capacity), if it isSorted ... and the Cvec is expandable, via push_back and reserve functions, to as much memory that is available in your PC.  It also provides several ready to use functions like merge sort, insertion sort, find, erase, and unique - which is mainly what we want here.  Cvec is an emulation in C of the STL C++ vector container, that is so very useful.  With a little practice, you may find that Cvec is a fairly frendly C emulation that you will want to use to hold your data ... int's, doubles, dynamic C strings, struct's, etc ...

The following code uses the two files that follow ... "CvecOfInt.h" and "Cvec.h"

Make sure these are in the same directory/folder as your program file ... "mergeTwoCvecOfInt.c"  ... before you compile the program in C.



--- Code: ---/* mergeTwoCvecOfInt.c */  /* 2016-10-09 */


/* using CvecOfInt.h that emulates some of the C++ STL vector */

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


#define myType double /* not needed here if using default #define myType int */

#include "CvecOfInt.h" /* changed to CvecOfDouble by above pre-define of myType */
/*
    "CvecOfInt.h" also includes <stdio.h>, <stdlib.h>, <string.h> and myAssert(..)
    and also includes the file "Cvec.h"  ...
*/

int more()/* defaults to 'true'/'yes'/'1' ... unless 'n' or 'N' entered ... */
{
    int c, reply;
    fputs( "More (y/n) ? ", stdout ); fflush( stdout );
    reply = c = getchar();
    while( c != '\n' ) c = getchar(); /* 'flush' stdin buffer ...  */
    if( reply == 'n' || reply == 'N' ) return 0;
    /* else ... */
    return 1;
}

void enterCvec( const char prompt[], Cvec* cv )
{
    int i = 0, numGoodVals;
    Rec r;
    puts( prompt ); fflush( stdout );
    do
    {
        printf( "enter number %d: ", i+1 ); fflush( stdout );
        numGoodVals = scanf( "%lf", &r.val );
        while( getchar() != '\n' ) ; /* flush stdin ... */
        if( numGoodVals != 1 )
        {
            printf( "Please enter only integers ...\n" );
            continue;
        }
        ++i;
        push_backCvec( cv, &r );
    }while( more() );
}

void printCvec( Cvec* cv )
{
    int i;
    for( i = 0; i < cv->size; ++i )
        printf( "%.2f ", cv->ary[i].val );
    printf( "cap = %d, size = %d\n", cv->cap, cv->size );
}

/*
int exist( Cvec* cv, myType val )
{
    int i;
    for( i = 0; i < cv->size; ++i )
    {
        if( cv->ary[i].val == val ) return 1;
    }
    return 0;
}
*/



int main()
{
    int i;
    myType testVal;
    Cvec cv1, cv2, cv3;
    initCvec( &cv1 ); /* NOTE: MUST initial before using for Cvec to work ... */
    initCvec( &cv2 );
    initCvec( &cv3 );
   
    enterCvec( "Enter Cvec1 ...", &cv1 ); /* Note: passing a 'reference' ... */
    enterCvec( "\nEnter Cvec2 ...", &cv2 );

   
    /* method ONE ... adding ONLY elements, NOT already present, to new cv3 */
   
    for( i = 0; i < cv1.size; ++i )
    {
        /* if( !exist( &cv3, cv1.ary[i].val) ) */
        if( findCvec( &cv3, cv1.ary[i].val) == -1 )
        {
            push_backCvec( &cv3, &cv1.ary[i] );
        }
    }

    for( i = 0; i < cv2.size; ++i )
    {
        /* if( !exist( &cv3, cv2.ary[i].val) ) */
        if( findCvec( &cv3, cv2.ary[i].val ) == -1 )
        {
            push_backCvec( &cv3, &cv2.ary[i] );
        }
    }

    printf( "\ncv1 is: " ); printCvec( &cv1 );
    printf( "cv2 is: " ); printCvec( &cv2 );
    printf( "cv3 is: " ); printCvec( &cv3 );
    msortCvec( &cv3 );
    printf( "\nAfter msort( &cv3 ) ...\n" );
    printf( "cv3 is: " );printCvec( &cv3 );

   
    /* method TWO ... append cv2 to cv1, then sort cv1 and get unique cv1 */
   
    puts( "\nTesting uniqueCvec ... but first, cv2 appended to cv1:" );
    /*
    for( i = 0; i < cv2.size; ++i )
    {
        push_backCvec( &cv1, &cv2.ary[i] );
        printf( "cv1.cap = %d, sv1.size = %d\n", cv1.cap, cv1.size );
    }
    */
    reserveCvec( &cv1, cv1.size + cv2.size ); /* get just enough memory ... */
    for( i = 0; i < cv2.size; ++i )
    {
        cv1.ary[cv1.size ++] = cv2.ary[i]; /* increment size AFTER assignment */
        printf( "cv1.cap = %d, cv1.size = %d\n", cv1.cap, cv1.size );
    }
    puts( "After appending cv2 to cv1 ..." );
    printf( "cv1 is: " ); printCvec( &cv1 );
   
    testVal = cv1.ary[cv1.size-1].val; /* get copy of last val for future use */

    puts( "Testing supplied isortCvec( &cv1 ) ...\n"
          "(NOT really needed here because uniqueCvec will call msort if !isSorted)" );
    isortCvec( &cv1 );
    printf( "After isortCvec( &cv1 ) ...\n" );
    printf( "cv1 is: " ); printCvec( &cv1 );
   
    printf( "\nTesting find %.2f and erase ...\n", testVal );
    i = findCvec( &cv1, testVal );
    if( i != -1 ) eraseCvec( &cv1, i );
    printf( "cv1 is: " ); printCvec( &cv1 );
   
   
    uniqueCvec( &cv1 );
    puts( "After unique ... " );
    printf( "cv1 is: " ); printCvec( &cv1 );

    clearCvec( &cv3 );
    clearCvec( &cv2 );
    clearCvec( &cv1 );
   
    fputs( "\nPress 'Enter' to continue/exit ... ", stdout); fflush( stdout );
    getchar(); /* keep 'Window' open until 'Enter' key is pressed ... */
    return 0;
}
--- End code ---

Navigation

[0] Message Index

[#] Next page

Go to full version