what(): basic_string::_M_construct null 无效
what(): basic_string::_M_construct null not valid
我正在编写一个程序,我需要使用一个函数来将字符串的标记存储在向量中。该功能无法正常工作,因此我在较小的程序上尝试了该功能。当然,我使用了字符串分词器函数。但它没有按预期工作。首先,这是代码:
#include <vector>
#include <string>
#include <cstring>
using namespace std;
int main()
{
vector<string> v;
string input = "My name is Aman Kumar";
char* ptr = strtok((char*)input.c_str(), " ");
v.push_back((string)ptr);
while(ptr)
{
ptr = strtok(NULL," ");
v.push_back((string)ptr);
}
cout<<"Coming out";
for(string s:v)
{
cout<<s<<endl;
}
}
现在是问题。我认为这个问题与命令有关:
(string)ptr
这个东西在第一次调用时完美运行,但在 while 循环中出现时出错。如果我把它注释掉并打印 ptr,那么它工作正常,但是程序在 while 循环后终止,甚至不执行
cout<<"coming out";
不用管向量的内容。但是同样,如果我也不打印 ptr,则会打印存储在矢量中的第一个标记“My”。我真的找不到造成这种情况的原因。任何建议都会有所帮助。
在尝试从中创建字符串之前,您不知道 ptr
是否是 nullptr
(并且使用 nullptr
调用 std::string
构造函数是 UB)
您需要重新组织循环,例如像这样:
char* ptr = strtok(input.data(), " ");
while(ptr)
{
v.push_back(std::string(ptr));
ptr = strtok(NULL," ");
}
附带说明一下,不要在 C++ 中使用 C 风格的强制转换语法。它很可能会隐藏问题,而 C++ 语法提供了更安全的替代方法。
放弃常量并修改结果在 C++ 中是 UB,因此第一个转换可以替换为 data
调用(需要时 returns 指向非常量的指针)。如果你没有C++11,那么这就是UB,因为不能保证字符串存储在连续内存中,你需要使用different methods.
在
while(ptr)
{
ptr = strtok(NULL," ");
v.push_back((string)ptr);
}
因为最后一个标记 ptr
将为空,从空指针构造 std::string
是未定义的行为。尝试:
while(ptr = strtok(NULL," "))
{
v.push_back(string(ptr));
}
更多 C++ 解决方案:
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
int main()
{
std::vector<std::string> v;
std::string input = "My name is Aman Kumar";
std::stringstream ss(input);
std::string word;
while(ss >> word)
{
v.push_back(word);
}
std::cout << "Coming out\n";
for(std::string& s:v)
{
std::cout << s << "\n";
}
}
您将 std::string
与 C-ish strtok
函数混合使用。这真是个坏主意。 std::string
或多或少可以与 const
char *
互换,但不能与可变的 char *
互换。不是说空指针问题。所以选择一种方法并坚持下去。
C-ish 一个:构建一个普通的 char
数组并存储 char *
:
的向量
char *cstr = strdup(input.c_str());
ptr = strtok(cstr, " ");
while(ptr) {
v.push_back(ptr);
ptr = strtok(NULL, " ");
}
cout<<"Coming out";
for(char *s:v)
{
cout<<s<<endl;
}
free(cstr); // always free what has been allocated...
C++一个,用一个std::stringstream
:
std::stringstream fd(input);
for(;;) {
std::string ptr;
fd >> ptr;
if (! fd) break;
v.push_back(ptr);
}
cout<<"Coming out";
for(std::string s: v)
{
cout<<s<<endl;
}
我正在编写一个程序,我需要使用一个函数来将字符串的标记存储在向量中。该功能无法正常工作,因此我在较小的程序上尝试了该功能。当然,我使用了字符串分词器函数。但它没有按预期工作。首先,这是代码:
#include <vector> #include <string> #include <cstring> using namespace std; int main() { vector<string> v; string input = "My name is Aman Kumar"; char* ptr = strtok((char*)input.c_str(), " "); v.push_back((string)ptr); while(ptr) { ptr = strtok(NULL," "); v.push_back((string)ptr); } cout<<"Coming out"; for(string s:v) { cout<<s<<endl; } }
现在是问题。我认为这个问题与命令有关:
(string)ptr
这个东西在第一次调用时完美运行,但在 while 循环中出现时出错。如果我把它注释掉并打印 ptr,那么它工作正常,但是程序在 while 循环后终止,甚至不执行
cout<<"coming out";
不用管向量的内容。但是同样,如果我也不打印 ptr,则会打印存储在矢量中的第一个标记“My”。我真的找不到造成这种情况的原因。任何建议都会有所帮助。
在尝试从中创建字符串之前,您不知道 ptr
是否是 nullptr
(并且使用 nullptr
调用 std::string
构造函数是 UB)
您需要重新组织循环,例如像这样:
char* ptr = strtok(input.data(), " ");
while(ptr)
{
v.push_back(std::string(ptr));
ptr = strtok(NULL," ");
}
附带说明一下,不要在 C++ 中使用 C 风格的强制转换语法。它很可能会隐藏问题,而 C++ 语法提供了更安全的替代方法。
放弃常量并修改结果在 C++ 中是 UB,因此第一个转换可以替换为 data
调用(需要时 returns 指向非常量的指针)。如果你没有C++11,那么这就是UB,因为不能保证字符串存储在连续内存中,你需要使用different methods.
在
while(ptr)
{
ptr = strtok(NULL," ");
v.push_back((string)ptr);
}
因为最后一个标记 ptr
将为空,从空指针构造 std::string
是未定义的行为。尝试:
while(ptr = strtok(NULL," "))
{
v.push_back(string(ptr));
}
更多 C++ 解决方案:
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
int main()
{
std::vector<std::string> v;
std::string input = "My name is Aman Kumar";
std::stringstream ss(input);
std::string word;
while(ss >> word)
{
v.push_back(word);
}
std::cout << "Coming out\n";
for(std::string& s:v)
{
std::cout << s << "\n";
}
}
您将 std::string
与 C-ish strtok
函数混合使用。这真是个坏主意。 std::string
或多或少可以与 const
char *
互换,但不能与可变的 char *
互换。不是说空指针问题。所以选择一种方法并坚持下去。
C-ish 一个:构建一个普通的
的向量char
数组并存储char *
:char *cstr = strdup(input.c_str()); ptr = strtok(cstr, " "); while(ptr) { v.push_back(ptr); ptr = strtok(NULL, " "); } cout<<"Coming out"; for(char *s:v) { cout<<s<<endl; } free(cstr); // always free what has been allocated...
C++一个,用一个
std::stringstream
:std::stringstream fd(input); for(;;) { std::string ptr; fd >> ptr; if (! fd) break; v.push_back(ptr); } cout<<"Coming out"; for(std::string s: v) { cout<<s<<endl; }