I've almost finished this task but have a little trouble in result. Here's the problem description: Given a vector of strings, please implement the following 2 functions to process and output it:
process(): remove strings that contain digits and convert others in upper case
output(): print the strings and separate them with comma. Hints:
If possible, manipulate the vector elements in place to avoid copying vector.
It is encouraged to leverage STL functions/algorithms. Expected Output: ==========================================
Before: abc, 123, 456, xyz
After: ABC, XYZ
But my code caused the input is not as expected
before process: abc, 123, 456, xyz,
after process: ABC, XYZ,
Please tell me how to remove the comma in the end of string in both case before/after process
Here's my code:
#include <algorithm>
#include <cctype>
#include <iostream>
#include <vector>
void process(std::vector<std::string>& v)
{
// Remove strings that contain digits
for(std::string &s : v)
s.erase(std::remove_if(std::begin(s), std::end(s),
[](unsigned char ch) { return std::isdigit(ch); }),
s.end());
// Convert other characters into upper case
// std::toupper has several overloads
// template <class charT> charT toupper(charT, const locale&)
// int toupper(int ch)
// So taking its address might be complicated.
// We can use lambda to let compiler found the right overload:
// (In addition, as char might be signed or not, and toupper expects unsigned char value (or EOF))
for(std::string &s : v)
{
std::transform(s.begin(), s.end(), s.begin(),
[](unsigned char c){ return std::toupper(c); });
}
std::cout << '\n';
}
void output(std::vector<std::string>& v)
{
for(std::string &str : v)
if(str != "\0")
std::cout << str << ", ";
}
int main()
{
std::vector<std::string> v = { "abc", "123", "456", "xyz" };
std::cout << "Before: "; output(v);
process(v);
std::cout << "After: "; output(v);
return 0;
}
CodePudding user response:
Print first element of your vector. Make comma be printed with next elements.
void output(const std::vector<std::string> &v) {
if (v.empty()) { // make sure v is not empty or v[0] will cause U.B.
return;
}
std::cout << v[0]; // 1st element printed
for (size_t i = 1; i < v.size(); i) { // loop starts with 2nd element
std::cout << ", " << v[i];
}
std::cout << '\n';
}
CodePudding user response:
Sometimes, good old syntax is a good thing.
void output(std::vector<std::string>& v) {
// clean array
size_t n = v.size();
while(n--) if(v[n] == '\0') v.erase(v.begin() n);
// print words
for(size_t i = 0; i < v.size(); i) {
std::cout << v[i];
if(i < (v.size() - 1) std::cout << ", ";
}
}
another method
void output(std::vector<std::string>& v) {
// clean array
size_t n = v.size();
while(n--) if(v[n] == '\0') v.erase(v.begin() n);
// print words
size_t max = v.size() - 1;
for(size_t i = 0; i < max; i)
std::cout << v[i] << ", ";
std::cout << v[max];
}