Метод вектора data()
возвращает необработанный указатель на выделенный массив вектора в памяти.clear()
уничтожает содержимое этого массива, если необходимо, и устанавливает size()
вектора в 0, но не перераспределяет сам массив и, следовательно, не изменяет capacity()
вектора.Вызов метода shrink_to_fit()
вектора перераспределяет массив так, что его capacity()
совпадает с size()
, если это возможно (shrink_to_fit()
носит рекомендательный характер и не гарантирует , чтобы действительно что-либо делать).
Кроме того, при построении std::string
из указателя char*
данные char должны заканчиваться нулем, а ваши данные - нет.Вам нужно вставить нулевой терминатор в вектор перед использованием data()
:
void splitString(const string &str, char delimiter, vector<string> * out) {
vector<char> word_buffer;
for (int i = 0; i < str.length(); ++i) {
if (str[i] == delimiter) {
word_buffer.push_back('\0');
out->push_back(word_buffer.data());
word_buffer.clear();
} else {
word_buffer.push_back(str[i]);
}
}
if (!word_buffer.empty()) {
word_buffer.push_back('\0')
out->push_back(word_buffer.data());
}
}
В противном случае вы можете просто принять во внимание size()
вектора при построении строк, нулевые терминаторы не нужны:
void splitString(const string &str, char delimiter, vector<string> * out) {
vector<char> word_buffer;
for (int i = 0; i < str.length(); ++i) {
if (str[i] == delimiter) {
out->push_back(string(word_buffer.data(), word_buffer.size()));
// alternatively:
// out->emplace_back(word_buffer.data(), word_buffer.size());
word_buffer.clear();
}
else {
word_buffer.push_back(str[i]);
}
}
if (!word_buffer.empty()) {
out->push_back(string(word_buffer.data(), word_buffer.size()));
// alternatively:
// out->emplace_back(word_buffer.data(), word_buffer.size());
}
}
При этом существуют и другие способы реализации функции splitString()
без необходимости использования вектора word_buffer
, например:
void splitString(const string &str, char delimiter, vector<string> * out) {
string::size_type start = 0, pos = str.find(delimiter);
while (pos != string::npos) {
out->push_back(str.substr(start, pos-start));
start = pos + 1;
pos = str.find(delimiter, start);
}
if (start < str.size()) {
if (start > 0) {
out->push_back(str.substr(start));
} else {
out->push_back(str);
}
}
}
Live Demo
void splitString(const string &str, char delimiter, vector<string> * out) {
istringstream iss(str);
string word;
while (getline(iss, word, delimiter))
out->push_back(std::move(word));
}
Live Demo
Но даже если бы вы хотели буферизовать слова вручную, std::string
имел бы больше смысла, чем std::vector<char>
тем более что вы выводите std::string
значения:
void splitString(const string &str, char delimiter, vector<string> * out) {
string word_buffer;
for (string::size_type i = 0; i < str.length(); ++i) {
if (str[i] == delimiter) {
out->push_back(std::move(word_buffer));
word_buffer.clear();
} else {
word_buffer.push_back(str[i]);
}
}
if (!word_buffer.empty()) {
out->push_back(std::move(word_buffer));
}
}
Live Demo