Расщепление строки с помощью strtok_s

Я пытаюсь разделить строку указанным разделителем в соответствии с этим примером: http://msdn.microsoft.com/en-us/library/ftsafwz3(v=VS.90).aspx

Мой код компилируется без ошибок в Visual C ++ 2010, но когда я хочу его запустить, я получаю следующее сообщение об ошибке:

Необработанное исключение в 0x773a15de в Test.exe: 0xC0000005: расположение чтения нарушения доступа 0x00000000.

Вот мой код:

#include "stdafx.h"#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <regex>

using namespace std;

vector<char *> splitString(char in[])
{
vector<char *> parts(15);
char seps[]   = " ,\t\n";
char *next_token1 = NULL;
char *token1 = NULL;
token1 = strtok_s(in, seps, &next_token1);
while ((token1 != NULL))
{
if (token1 != NULL)
{
token1 = strtok_s( NULL, seps, &next_token1);
//printf( " %s\n", token1 );
parts.push_back(token1);
}
}
return parts;
}

int main(int argc, char * argv[])
{
char string1[] =
"A string\tof ,,tokens\nand some  more tokens";
vector<char *> parts=splitString(string1);
cout << parts[0] <<endl;
cout << parts[1] <<endl;
return 0;
}

Кажется незаконным, что я пытаюсь отобразить элементы вектора, но почему?

Емкость вектора должна быть достаточной и

printf («% s \ n», token1);

в то время как цикл выводит токены!

1

Решение

Использование vector это неверно. Он построен с 15 элементы, а затем push_back() используется для добавления строк, которые добавляют новые элементы после начальный 15. Это означает, что первый 15 элементы не назначены (null):

std::cout << parts[0] << end; // parts[0] is null

Или:

  • не выделяйте элементы при создании или
  • использование operator[] и не push_back() (добавить дополнительный терминатор цикла, чтобы защитить выход за пределы вектора)

(Рассмотрите возможность изменения на std::vector<std::string>.)

Просто упомянуть boost::split() который может произвести список токенов (std::vector<std::string>) из входной строки и разрешает указание нескольких разделителей.

2

Другие решения

Беда в том, Общее предостережение: вы используете strtok (семейство) функций в с ++. Обратите внимание, что это старый API модифицирует это аргумент. Это часто не то, что вы ожидаете, и по этой причине я бы посоветовал не использовать это C библиотечная функция.

Кроме того, вы предполагаете, что 15 элементов будут прочитаны, оставляя «лишние» элементы неинициализированными. Это также приводит к неопределенному поведению при доступе к этим элементам.


Могу ли я предложить подход C ++, так как вы используете его:

#include <iostream>
#include <sstream>
#include <iterator>
#include <algorithm>

using namespace std;

vector<std::string> splitString(const char in[])
{
std::istringstream iss(in);
std::istream_iterator<std::string> first(iss), last;

std::vector<std::string> parts;
std::copy(first, last, std::back_inserter(parts));
return parts;
}

int main(int argc, char * argv[])
{
const char string1[] = "A string\tof ,,tokens\nand some  more tokens";
vector<std::string> parts = splitString(string1);
cout << parts[0] <<endl;
cout << parts[1] <<endl;
return 0;
}

При этом используется тот факт, что по умолчанию iostreams будет skipws (пропустить пробел)

1

По вопросам рекламы [email protected]