Home > Mobile >  Convert std::vector to std::string without \0
Convert std::vector to std::string without \0

Time:05-15

I want to remove the vowels from a std::string with this code:

# include <string>
#include <vector>

bool IsVowel(char c) {
    return ((c == 'a') ||
        (c == 'A') ||
        (c == 'e') ||
        (c == 'E') ||
        (c == 'i') ||
        (c == 'I') ||
        (c == 'o') ||
        (c == 'O') ||
        (c == 'u') ||
        (c == 'U'));
}

std::string RemoveVowel(const std::string& str) {
    const size_t s = str.length();

    std::vector<char> inProgress(s);

    int index = 0;
    for (char c : str) {
        if (!IsVowel(c)) {
            inProgress[index] = c;
            index  ;
        }
    }

    std::string sy(inProgress.begin(), inProgress.end());
    return sy;

}

But with this input:

"aaaaaa"

I get this output:

"\0\0\0\0\0\0"

But I want to get this:

""

The problem is with std::string sy(inProgress.begin(), inProgress.end());. I don't know how to convert the std::vector to std::string without any \0.

How can I fix this problem?

CodePudding user response:

As you can see, inProgress always contains str.length() many elements. index tells you the actual number of vowels in there. std::string has constructors that let you use that information to determine how much of inProgress to use in the initialization of sy.

So, you could do:

std::string sy(inProgress.begin(), inProgress.begin()   index);
return sy;

This would construct sy using only the initial segment of inProgress that actually contains vowels.

CodePudding user response:

The answer by Nathan Pierson explains how to do what you want.

But there are easier ways:

C 20 or newer:

std::string RemoveVowel(std::string str)
{
    std::erase_if(str, IsVowel);
    return str;
}

C 17:

std::string RemoveVowel(std::string_view str)
{
    std::string ret;
    ret.reserve(str); // Optional.
    std::copy_if(str.begin(), str.end(), std::back_inserter(ret), std::not_fn(IsVowel));
    return ret;
}

C 14 and earlier:

std::string RemoveVowel(const std::string &str)
{
    std::string ret;
    ret.reserve(str); // Optional.
    std::copy_if(str.begin(), str.end(), std::back_inserter(ret), [](char ch){return !IsVowel(ch);});
    return ret;
}

Even if you don't want to keep the custom loop, you should replace std::vector with a std::string to avoid the extra copy at the return.

CodePudding user response:

You could not pass in an initial size for your vector and use push_back:

std::string RemoveVowel(const std::string& str) {
  std::vector<char> in_progress;
  in_progress.reserve(str.size());
  for (const char& c : str) {
    if (!IsVowel(c)) {
      in_progress.push_back(c);
    }
  }
  std::string sy(in_progress.begin(), in_progress.end());
  return sy;
}

Or alternatively use a stringstream instead:

std::string RemoveVowel(const std::string& str) {
  std::stringstream ss;
  for (const char& c : str) {
    if (!IsVowel(c)) {
      ss << c;
    }
  }
  return ss.str();
}

CodePudding user response:

Instead, use std::vector::push_back(value) to insert new valid characters into your vector, rather than setting null values.

for (char c : str) {
    if (!IsVowel(c)) {
        inProgress.push_back(c);
    }
}
std::string sy(inProgress.begin(), inProgress.end());
return sy;

Alternatively, can't you simply just append to an output string?

std::string sy = "";
for (char c : str) {
    if (!IsVowel(c)) {
        sy  = c;
    }
}
return sy;
  •  Tags:  
  • c
  • Related