Reputation: 511
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;
Upvotes: 0
Views: 330
Reputation: 5102
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
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;
Upvotes: 1
Reputation: 915
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.
Upvotes: 1
Reputation: 27538
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])
Upvotes: 1
Reputation: 511
@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;
Upvotes: 1
Reputation: 606
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.
Upvotes: 0