hi

so this project requires an input of U, M, or D and as many as you like of them (i think, might be only up to 100 based on charUMD[100] array in code) also, you have to end it with # in order to indicate the end. i am trying to say that if you dont include #, then program should cout the error message Error: String Does Not End With '#'! as seen in if statement in main. however, it gives me unhandled exception error because of "out of range". how can i fix this?

#include <iostream>
#include <string>
#include <vector>

using namespace std;

int length;

char UMD[100];
char value;
int i = 0;
string list;

void swap(char s[], int i, int j)
{
    char x, y;
    x = s[i];
    y = s[j];
    s[j] = x;
    s[i] = y;
}

void sort(char s[])
{
    for (int c = 0; c < (i - 1); c++)
    {
        for (int d = 0; d < i - c - 1; d++)
        {
            if (UMD[d] <= UMD[d + 1]) /* For decreasing order use < */
            {
                swap(UMD, d, (d + 1));
            }
        }
    }
}

int main()
{
    cout << "TYPE U, M, or D for the array" << endl;
    cout << "Type any other letter to stop adding!" << endl;

    cin >> list;
    int o = 0;
    while (list[o] != 0)
    {
        i++;
        o++;
    }

    int p = 0;
    while ((list.at(p)) != '#')
    {
        UMD[p] = list.at(p); p++;
    }

    if (UMD[o] != '#'){ cout << "Error: String Does Not End With '#'!" << endl; system("pause"); exit(0); }//<------IF UMD[o] is not '#', then it should display this message! However it does not work for '#' IDK WHY!

    for (int z = 0; z<p; z++)
    {
        if (list.at(z) != 'U'&&list.at(z) != 'M'&&list.at(z) != 'D')
        {
            cout << "Error: character other than U, M, or D provided" << endl; system("pause"); exit(0);
            cout << list.at(z);
        }
    }

    sort(UMD);
    cout << endl;
    cout << "Here is the sorted version of the array" << endl;
    for (int z = 0; z<i; z++)
    {
        cout << UMD[z];
    }

    system("pause");
    return 0;
}

swap()
is C++ built-in function

Comments
o its supposed be SWAP, but it still runs either way, just that i need to fix the problem i mentioned in my first post

even after changing it to SWAP, its still giving same error if i dont include #. i waant it to output "error!....." instead of the unhadled exception.

Since using C++, why not use C++ string and gain the ease of its use ?

Try something like this:

#include <iostream>
#include <string>

using namespace std;


void my_swap( char& a, char& b )
{
    char tmp = a;
    a = b;
    b = tmp;
}

// passed in string is validated to already contain '#' ....
void bubble_sort( string& s )
{
    bool swap;
    size_t size = s.find( '#' );
    do
    {
        swap = false;
        for( size_t d = 1; d < size; ++d )
        {
            if( s[d-1] > s[d] ) // For decreasing order use < //
            {
                my_swap( s[d-1], s[d] );
                swap = true;
            }
        }
        --size;
    }
    while( swap );
}



int main()
{
    string str;
    for( ; ; ) // loop forver until break ...
    {
        cout << "Enter a string to be sorted "
             << "up to the '#' char position in the string: \n";

        getline( cin, str );


        size_t i = str.find( '#' );
        if( i != string::npos ) break;

        // if reach here ...
        cout << "\nYour string needs to have a '#' char in it ... \n";
    }


    bubble_sort(str);

    cout << "Here is 'str' sorted up to '#' ...\n";
    cout << str << endl;

    cout << "\nPress 'Enter' to continue/exit ... " << flush;
    string dummy;
    getline( cin, dummy );
    return 0;
}
Comments
great code, but its a bit far from what i need. this code sorts almost any string, which is great! but it sorts it in alphabet i noticed and includes # at end of sort, which cant be there. more below...

@David W So the program is excellent for any string needed to be sorted in ALPHABETICAl order, however, my project requires on letters of U, M, and D and say you put 'em in MDDMU#, it will be UMMDD. thats how its supposed to be. and without # at end like my original code. is there a way to fix the original a bit easier instead of changing things? like for instance i moved the if stateent before the p=....loop, and it worked, however, if i put in UMDD# or anything basically like MUDDM#, even with # it said error, # is missing. which isnt supposed be the case. i am gonna try adding in some aspects from the code you provided me with and thinking about how it correlates etc..., but i replied now in case i hit a dead end and i wouldnt have to wait for more reply after i hit that dead end tomorrow lol.

If you only accept ... U, M, and D

Then you should validate your input to only accept that ...

or if lower case ... to change lower umd to UPPER UMD

at the input stage ... including validating that the string ENDS witha # (or has a # somewhere ... if it is also permitted to NOT be at the end)

Then ... pass that validated string to the sort function
and output ONLY the sorted char's up to the # char

project requires on letters of U, M, and D and say you put 'em in MDDMU#, it will be UMMDD. thats how its supposed to be. and without # at end like my original code.

Edited 2 Years Ago by David W

from my original code, i already do make sure that its not another characters, in main() ...

for (int z = 0; z<p; z++)
    {
        if (list.at(z) != 'U'&&list.at(z) != 'M'&&list.at(z) != 'D')
        {
            cout << "Error: character other than U, M, or D provided" << endl; system("pause"); exit(0);
            cout << list.at(z);
        }
    }

also, your code seems to focus on a line of string, mine uses (supposed to) array, which is making it hard to use the size function with. i can only use list. not s or UMD.

we have to use the SWAP function like the one you see; involving i and j, as in ith and jth terms.

Try this ... (to get started) ...

#include <iostream>
#include <string>
#include <cctype> // re. toupper...

using namespace std;

const string VALID_CHARS = "DMU";


void my_swap( char& a, char& b )
{
    char tmp = a;
    a = b;
    b = tmp;
}

// passed in string is validated to already contain '#' ....
void bubble_sort( string& s )
{
    bool swap;
    size_t size = s.find( '#' );
    do
    {
        swap = false;
        for( size_t d = 1; d < size; ++d )
        {
            if( s[d-1] > s[d] ) // For decreasing order use < //
            {
                my_swap( s[d-1], s[d] );
                swap = true;
            }
        }
        --size;
    }
    while( swap );
}


bool isValid( const string& s, size_t size, const string& validChars )
{
    for( size_t i = 0; i < size; ++ i )
    {
        if( validChars.find( toupper(s[i]) ) == string::npos )
            return false;
    }
    // if reach here ...
    return true;
}


int main()
{
    string str;
    for( ; ; ) // loop forver until break ...
    {
        cout << "Enter a string to be sorted "
             << "up to the '#' char position in the string: \n";

        getline( cin, str );


        size_t i = str.find( '#' );
        if( i != string::npos )
        {
            if( isValid( str, i, VALID_CHARS ) ) break;
            // else ...
            cout << "Only " << VALID_CHARS
                 << " are valid here ... \n";
        }

        // else ... if reach here ...
        cout << "\nYour string needs to have a '#' char in it ... \n";
    }


    bubble_sort(str);

    cout << "Here is 'str' sorted up to '#' ...\n";
    cout << str << endl;

    cout << "\nPress 'Enter' to continue/exit ... " << flush;
    string dummy;
    getline( cin, dummy );
    return 0;
}

And ...

#include <iostream>
#include <string>
#include <cctype> // re. toupper...

using namespace std;

const string VALID_CHARS = "DMU";


void my_swap( string& s, int i, int j )
{
    char tmp = s[i];
    s[i] = s[j];
    s[j] = tmp;
}

// passed in string is validated to already contain '#' ....
void bubble_sort( string& s )
{
    bool swap;
    size_t size = s.find( '#' );
    do
    {
        swap = false;
        for( size_t d = 1; d < size; ++d )
        {
            if( s[d-1] > s[d] ) // For decreasing order use < //
            {
                my_swap( s, d-1, d );
                swap = true;
            }
        }
        --size;
    }
    while( swap );
}

// check if char's up to size are all valid ...
bool isValid( const string& s, size_t size, const string& validChars )
{
    for( size_t i = 0; i < size; ++ i )
    {
        if( validChars.find( toupper(s[i]) ) == string::npos )
            return false;
    }
    // if reach here ...
    return true;
}


int main()
{
    string str;
    for( ; ; ) // loop forver until break ...
    {
        cout << "Enter a string to be sorted "
             << "up to the '#' char position in the string: \n";

        getline( cin, str );


        size_t i = str.find( '#' );
        if( i != string::npos )
        {
            if( isValid( str, i, VALID_CHARS ) ) break;
            // else ...
            cout << "Only " << VALID_CHARS
                 << " are valid here ... \n";
        }

        // else ... if reach here ...
        cout << "\nYour string needs to have a '#' char in it ... \n";
    }


    bubble_sort(str);

    cout << "Here is 'str' sorted up to '#' ...\n";
    cout << str << endl;

    cout << "Here is sorted 'str' up to (BEFORE) the '#' char ... \n";
    cout << str.erase( str.find( '#' ) ) << '\n';

    cout << "\nPress 'Enter' to continue/exit ... " << flush;
    string dummy;
    getline( cin, dummy );
    return 0;
}

Edited 2 Years Ago by David W: added comments

thank you, i noticed this limited the characters. but didnt remove the # when it sorts. also, what if i want the user to only be able to use # at end? my professor points a lot of details, and i have a feeling this is gonna be one of them. the program simply runs fine with it and outputs like this #UMD#. also like this #umd or #UMMDU, ...it seems like its only recognizing as long as it has #, which contradicts the instructions "with # at the end" or "up to #". once this is demostrated i can try to figure out how to implement it in my orginal code.

Are you saying the input can be

EITHER

1) "with # at the end" // only dmu are valid here

or

2) "up to #" ... ignore rest // only dmu valid upto #

?

Edited 2 Years Ago by David W: fixed typo

Isn't that what the 2nd example on the above page does?
(Did you see it there?
I added it later than the first edit.)

yes, ya i saw after you editted it seemed. however, it still takes in # whereever i put it. it must only be accepted at last, yet it takes any where #. so i input in #UMDUD#, it outputs same thing out->#DDMUU# and as for the before the # option for cout, it outputs nothing.

Edited 2 Years Ago by catastrophe2

Attachments daniweb_test_images.png 21.28 KB

So ... are you saying that #uumdudmm#sfgvdfgsdf
is valid input ?

Or ... only that #uumdudmm# is to accepted ?

in which (2nd) case is the output to be

ddmmmuuu

?

Please provide examples of ALL valid input
And the corresponding expected output

Edited 2 Years Ago by David W

no, the only vaid input is UMD(or whatever many of them desired in any order)and one # at the end.

Try this ...

#include <iostream>
#include <string>
#include <cctype> // re. toupper...

using namespace std;

const string VALID_CHARS = "DMU";


void my_swap( string& s, int i, int j )
{
    char tmp = s[i];
    s[i] = s[j];
    s[j] = tmp;
}

// passed in string is ALREADY validated to contain a '#' char at END

// sorts ONLY up to the '#' char at the end ...
// i.e. '#' is left in the end position
void bubble_sort( string& s )
{
    bool swap;
    int size = s.size() -1 ; // leave end '#' in place ...
    do
    {
        swap = false;
        for( int d = 1; d < size ; ++d )
        {
            if( s[d-1] > s[d] ) // For decreasing order use < //
            {
                my_swap( s, d-1, d );
                swap = true;
            }
        }
        --size;
    }
    while( swap );
}

// no need to check the last char, which we already know is a '#' char
// by the time we call this function ...
bool isValid( const string& s, const string& validChars )
{
    for( size_t i = 0; i < s.size()-1; ++ i )
    {
        if( validChars.find( toupper(s[i]) ) == string::npos )
            return false;
    }
    // if reach here ...
    return true;
}


int main()
{
    string str;
    for( ; ; ) // loop forver until break ...
    {
        cout << "Enter a string to be sorted "
             << "up to the '#' char position in the string: \n";

        getline( cin, str );


        size_t i = str.find( '#' );

        // if first '#' char exists as LAST char ...
        if( i != string::npos   &&   i == str.size() - 1 )
        {
            if( isValid( str, VALID_CHARS ) ) break;
            // else ...
            cout << "Only " << VALID_CHARS
                 << " are valid here ... \n";
        }

        // else ... if reach here ...
        cout << "\nYour string needs to have a '#' char at the end.\n";
    }


    bubble_sort(str);

    cout << "Here is 'str' sorted  ... including the terminal '#' ...\n";
    cout << str << endl;

    cout << "Here is sorted 'str' up to (BEFORE) the '#' end char ... \n";
    cout << str.erase( str.size()-1 ) << '\n';

    cout << "\nPress 'Enter' to continue/exit ... " << flush;
    string dummy;
    getline( cin, dummy );
    return 0;
}

See edited version

Edited 2 Years Ago by David W

A+ man! now it works as intended :D

thnx so much. its like 5 in the morning for me now xD and am sick. ill tend to the project more tomorrow and try fix array. just before i go for now, what hints can you give me replacing new codes from your successful version to my original array type version? in other words, how should i go by changing your string based DMU code to my array based UMD code (DMU and UMD dont matter here, just for distinction)?

again i appreciate all the effort you put through this, this definitely helps!

Hey ... it's 4:53 here now ... also

I was just going to leave McD's wi-fi when some over-drunk kids crashed on to my table ... and I noticed you were still working :)

Edited 2 Years Ago by David W

McD's is a local abbreviation for McDonalds

As a first step in your conversion to using a C string (array of char's with a terminal '\0' char) ...
you could take in ... using the C++ string ...
then ... at some point ... call cppStr.c_str() to convert to a const C string (i.e copy over to a buffer) ...

Edited 2 Years Ago by David W

Some ideas re. new function calls (slight revisions)

#include <iostream>
#include <string>

#include <cstring> // re. strlen, strchr
#include <cctype> // re. toupper..

const char VALID_CHARS[] = "DMU";

const int BUF_SIZE = 1024;

void my_swap( char* s, int i, int j );


// passed in string is ALREADY validated to contain a '#' char at END

// sorts ONLY up to the '#' char at the end ...
// i.e. '#' is left in the end position
void bubble_sort( char* s )
{
    bool swap;
    int size = strlen(s) - 1;
    do
    {
        swap = false;
        for( int d = 1; d < size ; ++d )

        /// ...
}

// no need to check the last char, which we already know is a '#' char
// by the time we call this function ...
bool isValid( const char* s, const char* validChars )
{
    for( size_t i = 0; i < strlen(s) - 1; ++ i )
    {
        if( !strchr(validChars, toupper(s[i])) )
            return false;
    }
    // if reach here ...
    return true;
}


// etc ...

Edited 2 Years Ago by David W

This article has been dead for over six months. Start a new discussion instead.