简体   繁体   中英

c++ toupper() to compare two strings

I have created a set of algorithms that takes an input of a string vector, checks whether any of the strings occur more than once: if so erases all additional occurrences of the string from the vector, then outputs the new, 'lighter' array without the redundancies.

It works great except now I am to make it case-insensitive; I am attempting to simply add the toupper() std function to the == comparison statement, however it does not seem to work.

I have a more familiar background with Java and am trying to learn C++.
Can someone please show me how to correct my syntax?

// Output old list.
cout << endl << "==========\nOld list:\n==========";
for (int i = 0; i < count; i++) {
    cout << endl << list[i];
}
cout << endl << endl;

// Check uniqueness.
for (int i = 0; i < count; i++)
    for (int j = i+1; j < count; j++) {
        if (toupper(list[i]) == toupper(list[j])) {
            list[j] = "";
            count--;
        }
    }

// Output new list.
cout << endl << "==========\nNew list:\n==========";
for (int i = 0; i < count; i++) {
    cout << endl << list[i];
}
cout << endl << endl;

I just did a quick google of toupper and I didn't find any string versions of it. The only standard touppper() I have seen is int toupper(int c); - that means you can only use it to compare individual characters! Have you tried stricmp() ?

        if ( 0 == _stricmp(list[i], list[j]) ) {
            list[j] = "";
            count--;
        }

Depending on your compiler you may or may not have this function at your disposal.

@DaveS, thanks Dave I will try that; it looks clean and short. However, I found dirtier solution using transform and making a duplicate of the old vector.

    // Output old list.
    cout << endl << "==========\nOld list:\n==========";
    for (int i = 0; i < count; i++) {
        cout << endl << list[i];
    }
    cout << endl << endl;

    // Check uniqueness.
    for (int i = 0; i < count; i++)
        for (int j = i + 1; j < count; j++) {
            std::transform(list[i].begin(), list[i].end(), list[i].begin(), ::toupper);
            std::transform(list[j].begin(), list[j].end(), list[j].begin(), ::toupper);
            if (list[i] == list[j]) {
                newlist[j] = "";
                count--;
            }
        }

    // Output new list.
    cout << endl << "==========\nNew list:\n==========";
    for (int i = 0; i < count; i++) {
        cout << endl << newlist[i];
    }
    cout << endl << endl;

Your loop leaves "holes" in the list array vector, but the size of the array vector does not change (but you decrease your upper bound count )

There are probably many other alternatives, but if you don't want to modify it much, probably you need in an addtional loop to copy non-empty elements from the list array into a new array

Edit: integrating some of the answers

First we're going to have a function to do the toUpper (this is modified from @Jim22150)

std::string stringToUpper(const std::string &input) {
    std::string toBeModified=input;
    std::transform(toBeModified.begin(), toBeModified.end(), toBeModified.begin(), ::toupper);
    return toBeModified;
}

Now, we must not leave holes, so we should use erase (as @Scott Christopher Stauffe indicated):

// Output old list.
cout << endl << "==========\nOld list:\n==========";
for (int i = 0; i < count; i++) {
    cout << endl << list[i];
}
cout << endl << endl;

// Check uniqueness.
for (int i = 0; i < count; i++)
    for (int j = i + 1; j < count; j++) {
        if(stringToUpper(list[i]) == stringToUpper(list[j])) {
            list.erase(j,1);
            count--;
        }
    }
}

// Output new list.
cout << endl << "==========\nNew list:\n==========";
for (int i = 0; i < count; i++) {
    cout << endl << newlist[i];
}
cout << endl << endl;

First of all,

list[j] = ""; // should never work. 

You can remove a char by using erase.

list.erase(j, 1);

Alternatively, to avoid this altogether, you could use a temporary "builder" string and just push_back chars to it when needed.

If you want to handle C++ strings as easily as Java strings, then the Boost String Algorithms Library is the way to go. Installing Boost may be a bit hard for a newbie C++ programmer (although it's a breeze compared to many other C++ libraries), but it pays off.

Your problem will essentially be reduced to this:

boost::algorithm::to_upper_copy(list[i]) == boost::algorithm::to_upper_copy(list[j])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM