Функция разделения строк C ++ дает неожиданный результат - PullRequest
0 голосов
/ 02 августа 2020
std::vector<char*> Split(std::string input) {
  std::vector<char*> ret;
  std::istringstream f(input);
  std::string s;
  while (getline(f, s, ' ')) {
    ret.push_back((char*)s.c_str());
  }
  return ret;
}

Эта функция предназначена для того, чтобы взять строку и поместить каждое слово в вектор. Но скажем, я поставил ls -l как строку. Он должен вернуть вектор с двумя элементами ls и -l. Вместо этого он возвращает вектор с двумя элементами -l и l. Кто-нибудь может мне с этим помочь?

Ответы [ 3 ]

0 голосов
/ 02 августа 2020

Копирование указателей не означает копирование того, что указано.

Кажется, вам нужно скопировать строки.

#include <cstring> // for strlen() and strcpy()

std::vector<char*> Split(std::string input) {
  std::vector<char*> ret;
  std::istringstream f(input);
  std::string s;
  while (getline(f, s, ' ')) {
    char* buf = new char[strlen(s.c_str()) + 1]; // +1 for terminating null-character
    strcpy(buf, s.c_str());
    ret.push_back(buf);
  }
  return ret;
}
0 голосов
/ 02 августа 2020

Вы получили свой ответ из двух других ответов, но у меня есть другой способ разбить строку (называется String Tokenization):

std::vector<std::string> split(std::string text) {
    std::vector<std::string> words;

    std::string temp{};
    for (int i=0; i < text.size(); ++i) {
        if (text[i] != ' ') {
            temp.push_back(text[i]);
            if (i ==  text.size()-1) {
                words.push_back(temp);
            }
        }
        else if (temp.size() != 0) {
            words.push_back(temp);
            temp.clear();
        }
    }

    return words;
}
0 голосов
/ 02 августа 2020

Вы сохраняете указатели на строки в своем векторе, но строка s уничтожается при выходе из функции. Таким образом, вы сохраняете указатели на удаленные объекты.

Используйте строки вместо указателей. Строки легко копировать правильно, в отличие от указателей. Попробуйте это

std::vector<std::string> Split(std::string input) {
  std::vector<std::string> ret;
  std::istringstream f(input);
  std::string s;
  while (getline(f, s, ' ')) {
    ret.push_back(s);
  }
  return ret;
}
...