0

I know the compiler is old but our school is dumb in that sense and it is out of my control. So is there no way to fix my code?

0

Here is an example ... (that instead of using C++ string, includes its own class String ... the same class String that I supplied you the link to ... above.)

Note: the sort would be faster (more efficent) if the vector, after input of a line (String) held (at input) Items (stuct) ... formed then, instead of formed from strings ... while sorting, in the compare function.

// 2_test_sortAlpahNum.cpp // // 2014-03-04 //

// tests out class String etc... //

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


// for 'quick/cheap' test ... use these includes below ... //

#include "base_string.cpp"
#include "string.cpp"

//#include "case.cpp" // NOT used here
//#include "reverse.cpp"  // NOT used here

////////////////////

#include <iostream>
#include <fstream>
//#include <sstream> // not used here now with this class String ...
//#include <string> // using above class String

#include <vector>  // NEED STL vector ... (OR some STD like, vector class included)

#include <algorithm> // Need STL re. sort
#include <ctype.h>    // re. isdigit, isalpha, tolower // Modern C++ uses <cctype> //
#include <stdlib.h>  // re. atoi // Modern C++ uses <cstdlib> //

using namespace std; // Modern C++ has and uses namespace //



typedef vector< String > VecStr; // Note: using STL vector BUT above class String

// takes in whole line ... returns int value of 1st char ... or zero
int takeInChar( const String& msg ) // In C/C++ char's have int values ...
{
    cout << msg << flush;
    String reply;
    getline( cin, reply );
    if( reply.size() )
        return reply[0];
    // else ...
    return 0;
}
bool more()
{
    if( tolower( takeInChar( "\nMore (y/n) ? " )) == 'n' )
        return false;
    // else ...
    return true;
}

// does NOT handle empty string  case here ...
bool isAllDigit( const String& s )
{
    for( int i = s.size()-1; i >= 0; -- i )
    {
        if( !isdigit(s[i]) ) return false;
    }
    return true;
}
// does NOT handle empty string  case here ...
bool isAllAlpha( const String& s )
{
    for( int i = s.size()-1; i >= 0; -- i )
    {
        if( !isalpha(s[i]) ) return false;
    }
    return true;
}

// *DOES* handle empty string  case  ... *HERE*
bool isValid( const String& s )
{
    int pos = s.size();
    if( !pos )
    {
        cout << "\nEmpty string.  ";
        return false;
    }

    if( isAllDigit(s) ) return true; // passes ... all digits
    if( isAllAlpha(s) ) return true; // passes ... all alpha

     --pos; // get last index in string ...

    // count back from end to pos before any terminal int
    while( pos >= 0 && isdigit( s[pos] )) --pos;


    if( s.size() - pos == 1 ) // then EXPECTED digits at end FAILS!
    {
        cout << "Expected trailing 'all digits' not found.  ";
        return false;
    }

    if( isAllAlpha( s.substr( 0, pos+1 ))) return true;

    // else ... if reach here ...
    cout << "Expected leading 'all alpha' char's not found.  ";
    return false;
}

// valid line entry only ...
// 1. a valid int (only one valid int on line)
// 2. a string (no embedded digits 0..9)
// 3. a string (as in 2.) immediately followed by one valid int
void loadFromUser( VecStr& vs )
{
    cout << "Valid input here is:\n"
         << "1. a valid integer (only one valid int on line ... or\n"
         << "2. a string (no embedded digits 0..9) ... or\n"
         << "3. a string (as in 2.) "
         << "immediately followed by one valid integer.\n\n";
    do
    {
        String line;
        cout << "Enter next line like one of following "
             << "( 1, 31, b1, a21, c3, 22, ... ): " << flush;
        getline( cin, line );
        if( isValid( line ) )
            vs.push_back( line );
        else
             cout << "\nInvalid input ... please try again ...\n";
    }
    while( more() );
}

void print( const VecStr& vs )
{
    for( size_t i = 0; i < vs.size(); ++i ) cout << vs[i] << endl;
}

void pause( const char* msg )
{
    cout << msg << flush;
    while( cin.get()  != '\n' ) ;
}

int toInt( const String& s )
{
    return atoi( &s[0] );
}

struct Item
{
    String s;
    int val;
} ;

bool myCmp( const String& a, const String& b )
{
    Item a_itm, b_itm;

    char c;
    String tmp;
    const char* p = &a[0];

    while( *p )
    {
        c = *p;
        if( isdigit(c) ) tmp += c;
        else a_itm.s += c;
        ++p;
    }
    a_itm.val = toInt( tmp );

    tmp.clear();

    p = &b[0];
    while( *p )
    {
        c = *p;
        if( isdigit(c) ) tmp += c;
        else b_itm.s += c;
        ++p;
    }
    b_itm.val = toInt( tmp );

    if( a_itm.s == b_itm.s ) return a_itm.val < b_itm.val;
    return a_itm.s < b_itm.s;
}



int main()
{
    VecStr vs; // construct empty vector ...

    loadFromUser( vs ); // get a vector of strings to test

    cout << "Before sorting ... \n";
    print( vs );

    sort( vs.begin(), vs.end(), myCmp );
    cout << "\nAfter sorting ... \n";
    print( vs );


    pause( "Press 'Enter' to continue/exit ... " );
}

Edited by David W: added content

0

Hi, still need some help to make it work.

so here is my code:

#ifndef RP_STRINGS_H_INC
#define RP_STRINGS_H_INC

short rpstrcmp(const char Str1[], const char Str2[], bool skipSpaces = false,
bool skipPunctuation = false);

#endif


#include <iostream>
//#include <cstring>
#include <iomanip>
#include "rpstrings.h"

using namespace std;

int main ()
{

    char Str1[200], Str2[200];
    short result;

    cout << "Please enter the first string:" << endl;
    cin.getline(Str1, 200);

    cout << "Please enter the second string:" << endl;
    cin.getline(Str2, 200);

    //cerr<<"\nReceived '"<<Str1<<"' and '"<<Str2<<"'\n";

    cout << "Skipping nothing...\n";
    result = rpstrcmp(Str1, Str2);

    if (result > 0)
    {
       cout << "First string is greater than second string" << endl;
    }

    else if (result == 0)
    {
       cout << "First string is equal to second string" << endl;
    }

    else 
    {
       cout << "First string is less than second string" << endl;
    }

    cout << "Skipping spaces...\n";
    result = rpstrcmp(Str1, Str2, true);

    if (result > 0)
    {
       cout << "First string is greater than second string" << endl;
    }

    else if (result == 0)
    {
       cout << "First string is equal to second string" << endl;
    }

    else 
    {
       cout << "First string is less than second string" << endl;
    }

    cout << "Not skipping spaces and skipping punctuation...\n";
    result = rpstrcmp(Str1, Str2, false, true);

    if (result > 0)
    {
       cout << "First string is greater than second string" << endl;
    }

    else if (result == 0)
    {
       cout << "First string is equal to second string" << endl;
    }

    else 
    {
       cout << "First string is less than second string" << endl;
    }


    cout << "Skipping spaces and punctuation...\n";
    result = rpstrcmp(Str1, Str2, true, true);

    if (result > 0)
    {
       cout << "First string is greater than second string" << endl;
    }

    else if (result == 0)
    {
       cout << "First string is equal to second string" << endl;
    }

    else 
    {
       cout << "First string is less than second string" << endl;
    }

    return 0;
}

#include "rpstrings.h"

#include <cctype>
#include <cstddef>
#include <iostream>
#include <string>

using namespace std;


short rpstrcmp(const char Str1[], const char Str2[], bool skipSpaces,
               bool skipPunctuation)
{
    short x;

    if (Str1 == Str2)
        x = 0;

    else if (Str1 == NULL)
        x = -1;

    else if (Str2 == NULL)
        x = 1;

    else {
        while ((skipSpaces && isspace(*Str1)) ||
               (skipPunctuation && ispunct(*Str1)))
        {
            ++Str1;
        }
        while ((skipSpaces && isspace(*Str2)) ||
               (skipPunctuation && ispunct(*Str2)))
        {
            ++Str2;
        }
    // compare a and b case INsensitively

        while (tolower(*Str1) == tolower(*Str2) &&
               *Str1 != '\0' && *Str2 != '\0')
        {
            //size_t s1;
            //s1 = 0;
            do
            {
                ++Str1;
                //s1++;
            } while ((skipSpaces && isspace(*Str1)) ||
                     (skipPunctuation && ispunct(*Str1)));
            //cerr<<"Skipped "<<s1<<" chars in first string\n";
            //size_t s2;
            //s2 = 0;
            do
            {
                ++Str2;
                //s2++;
            } while ((skipSpaces && isspace(*Str2)) ||
                     (skipPunctuation && ispunct(*Str2)));
            //cerr<<"Skipped "<<s2<<" chars in second string\n";
        }

        if (tolower (*Str1) <  tolower (*Str2))
            x = -1;

        else if(tolower (*Str1) > tolower (*Str2))
            x = 1;

        else
            x = 0;
    }

    return x;
}

So I need to use my code to do the the string comparison. The code works fine when comparing a1 to a10 but not when I compare a10 to a2.

I need "focus on the two chars you are about to compare turn out to be digits at the exact same time. When that happens, look into converting that digit sequence (unless they are both a single digit and not multiple digits in a row) into numeric form -- perhaps from the "String Translation It Does A Body Good (link: http://home.earthlink.net/~craie/122/labs/strtrans.html)" lab -- and comparing at that point based on their numeric values. If they are still equal, then go back to char-by-char comparison, otherwise you have your answer.

I understand I been asking alot of questions and apologize for that.

0

I just noticed ... that you have posted the very same problem at ... at least two other help sites ...

That is NOT the way to learn how to program ... looking for some-one to give you the code !!!

BUT ... I have ALREADY given you an unique algorithm to solve your 'problem' ... that uses a 'struct' ... and that first validates user input, etc.

However, the code that you show me back, each time ... shows NO evidence, what-so-ever, that you have studied or tried to implement that algorithm ... or any validation features ... and the code you show me back also uses fixed length C strings, with the max length pre-fixed at compile time ... not any variety, (that I can see), of C++ string.

If you do not wish to learn how to code ... for yourself ... in C++ ...why should I bother further ... to give away insights, that were very costly for me ... both in time and work ... for me to acquire ???

0

Sorry, I will post once I study the material and try to use what you have taught.

Thanks

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.