Я пишу функцию на C ++, которая теоретически должна принимать пользовательский ввод и разделять этот ввод на сегменты в соответствии с пробелами и возвращать эти сегменты как вектор.
В настоящее время я использую strtok () во входной строке, чтобы отделить слова от пробелов. Для каждого «слова» я помещаю его в буферный вектор. Перебирая каждое слово, я возвращаю вектор.
Итак, этот код у меня есть:
#include <iostream>
#include <string>
#include <cstring>
#include <vector>
std::vector<char*> tokenize(std::string input_, char const* delims=" \t\r\n\a")
{
char* input = (char*)input_.c_str();
std::vector<char*> tk_stream;
char* tk = strtok(input, delims);
while(tk != NULL) {
tk_stream.push_back(tk);
tk = strtok(NULL, delims);
}
return tk_stream;
}
int main(int argc, char** argv)
{
while (true) {
std::string input;
std::getline(std::cin, input);
if (input.empty()) {
continue;
}
std::vector<char*> tks = tokenize(input);
for (char* el : tks) {
std::cout << el << std::endl;
}
}
return 0;
}
Так что же должно произойти? хорошо, если у меня есть ввод "1 2 3 4", он должен напечатать каждое из этих чисел в отдельных строках. Это на самом деле работает с этим входом. Но когда длина входной строки больше, например, «1 2 3 4 5 6 7 8 9», вывод будет другим:
1 2 3 4 5 6 7 8 9
5
6
7
8
9
Не хватает первых 4 цифр! Это также происходит с любой строкой, длина которой больше этой, а число пропущенных чисел постоянно. Я также заметил, что это происходит с более длинными предложениями. Например, «Привет всем, это тест» дает:
hello everyone this is a test
0��
this
is
a
test
Я уже покопался в gdb и нашел кое-что интересное. С помощью ввода «1 2 3 4 5 6 7 8 9» я установил точку останова перед возвратом «tk_stream» и проверил ее значение:
(gdb) print tk_stream
$1 = std::vector of length 9, capacity 16 = {0x6176c0 "1", 0x6176c2 "2", 0x6176c4 "3", 0x6176c6 "4", 0x6176c8 "5", 0x6176ca "6", 0x6176cc "7", 0x6176ce "8", 0x6176d0 "9"}
Это кажется правильным. Но после того, как я перешагну несколько строк, когда это будет возвращено из функции, и проверю значение 'tks' (вектор, который должен содержать возвращаемое значение функции 'tokenize'); Я получаю это:
(gdb) print tks
$2 = std::vector of length 9, capacity 16 = {0x6176c0 "", 0x6176c2 "a", 0x6176c4 "", 0x6176c6 "", 0x6176c8 "5", 0x6176ca "6", 0x6176cc "7", 0x6176ce "8", 0x6176d0 "9"}
, в котором отсутствуют первые 4 записи с искаженной 2-й записью.
Так что что-то должно произойти в возвращении вектора 'tk_stream'.
В чем причина этого ненормального поведения? Как я могу это исправить, чтобы элементы вектора не были удалены?