我试图根据此示例按指定的分隔符拆分字符串:http://msdn.microsoft.com/en-us/library/ftsafwz3(v=VS.90).aspx
我的代码在Visual C ++ 2010中编译时没有错误,但是当我想运行它时,我收到此错误消息:
Test.exe中0x773a15de处的未处理异常: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;
}
我尝试显示向量的元素似乎是非法的,但为什么呢?
向量的容量应该足够了
while循环中的printf(“%s \ n”,token1);
打印出令牌!
答案 0 :(得分:2)
vector
的使用不正确。它由15
元素构成,然后push_back()
用于添加字符串,在初始值15之后添加新元素。这意味着第一个15
元素是unassigned(null):
std::cout << parts[0] << end; // parts[0] is null
或者:
operator[]
而非push_back()
(添加额外的循环终止符以保护超出向量的末尾)(考虑更改为std::vector<std::string>
。)
提到boost::split()
可以从输入字符串生成一个令牌列表(std::vector<std::string>
),并允许指定多个分隔符。
答案 1 :(得分:1)
问题是一般警告:你在c ++中使用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;
}
这使用的事实是,默认情况下,iostream将skipws
(跳过空格)