C++如何将字符串转换为char*
我需要将字符串转换为 char * 以在 strtok_s 中使用,但一直无法弄清楚。 c_str() 转换为 const char *,这是不兼容的。
另外,如果有人可以向我解释为什么第二个 strtok_s 函数(在循环内)是必要的,这将是一个很大的帮助。为什么我需要显式地推进令牌,而不是例如它所在的 while 循环,该循环隐式地连续获取文件的每一行。
while( getline(myFile, line) ) { // Only one line anyway. . . is there a better way?
char * con = line.c_str();
token = strtok_s( con, "#", &next_token);
while ((token != NULL))
{
printf( " %s\n", token );
token = strtok_s( NULL, "#", &next_token);
}
}
相关问题。
I need to convert a string to a char * for use in strtok_s and have been unable to figure it out. c_str() converts to a const char *, which is incompatible.
Also, if someone could explain to me why the second strtok_s function (inside the loop) is necessary, it'd be a great help. Why do i need to explicitly advance the token rather than, for example, the while loop it is in, which fetches each line of a file consecutively, implicitly.
while( getline(myFile, line) ) { // Only one line anyway. . . is there a better way?
char * con = line.c_str();
token = strtok_s( con, "#", &next_token);
while ((token != NULL))
{
printf( " %s\n", token );
token = strtok_s( NULL, "#", &next_token);
}
}
related question.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
使用
strdup()
将c_str()
返回的const char *
复制到char *
(记住free()
之后)请注意,
strdup()
和free()
是 C 函数,而不是 C++ 函数,你会更好使用std::string
方法代替。需要第二个 strtok_s() ,因为否则循环将不会终止(
token
的值不会改变)。Use
strdup()
to copy theconst char *
returned byc_str()
into achar *
(remember tofree()
it afterwards)Note that
strdup()
andfree()
are C, not C++, functions and you'd be better off using methods ofstd::string
instead.The second strtok_s() is needed because otherwise your loop won't terminate (
token
's value won't change).您无法转换为
char *
,因为这将允许您写入std::string
的内部缓冲区。为了避免使std::string
的实现可见,这是不允许的。尝试一种更“类似 C++”的字符串标记方式,而不是
strtok
。请参阅此问题:如何在 C++ 中标记字符串?
You can't convert to a
char *
because that would that would allow you to write tostd::string
's internal buffer. To avoid makingstd::string
's implementation visible, this isn't allowed.Instead of
strtok
, try a more "C++-like" way of tokenizing strings. See this question:How do I tokenize a string in C++?
正如丹尼尔所说,你可以使用
strdup(line.c_str());
这比我最初提出的 strcpy 更好,因为它分配了必要的空间
As Daniel said, you could go with
strdup(line.c_str());
Which is better then the strcpy I originally proposed since it allocates the necessary space
strtok()
本来就是一个设计糟糕的函数。检查您的文档,看看是否有更好的文档。顺便说一句,永远不要在任何类型的线程环境中使用strtok()
,除非您的文档明确表示它是安全的,因为它在调用之间存储状态并修改它所调用的字符串。我认为 strtok_s() 是一个更安全的版本,但它不会是一个真正安全的版本。要将
std::string
转换为char *
,您可以执行以下操作:并使用
temp_line
。您的安装可能有一个strdup()
函数,它将重复上述内容。您需要两次调用
strtok_s()
的原因是它们执行不同的操作。第一个告诉strtok_s()
它需要处理什么字符串,第二个继续使用相同的字符串。这就是 NULL 参数的原因;它告诉strtok_s()
继续使用原始字符串。因此,您需要一次调用来获取第一个令牌,然后为每个后续令牌调用一次。它们可以与诸如此类的东西组合起来
,因为这样会使用字符串指针调用一次
strtok_s()
,然后使用NULL
调用。不要为此使用 temp_line,因为您希望在处理后delete[] temp_line;
。您可能认为这需要大量的摆弄,但这正是
strtok()
及其相关函数通常需要做的事情。strtok()
is a badly designed function to begin with. Check your documentation to see if you have a better one. BTW, never usestrtok()
in any sort of threaded environment unless your docs specifically say it's safe, since it stores state in between calls and modifies the string it's called on. I assumestrtok_s()
is a safer version, but it's not going to be a really safe one.To convert a
std::string
into thechar *
, you can do:and use
temp_line
. Your installation may have astrdup()
function, which will duplicate the above.The reason you need two calls to
strtok_s()
is that they do different things. The first one tellsstrtok_s()
what string it needs to work on, and the second one continues with the same string. That's the reason for the NULL argument; it tellsstrtok_s()
to keep going with the original string.Therefore, you need one call to get the first token, and then one for each subsequent token. They could be combined with something like
and so on, since that would call
strtok_s()
once with the string pointer and after that withNULL
. Don't use temp_line for this, since you want todelete[] temp_line;
after processing.You may think this is a lot of fiddling around, but that's what
strtok()
and relatives usually entail.strtok 的工作原理如下:
第一个调用从头开始返回字符串,如果未找到分隔符,则返回整个字符串:
第二个调用使用 NULL 允许您继续解析相同的字符串以查找下一个分隔符:
如果到达末尾string 下一次调用将返回 NULL;
strtok works like this:
First call return string from beginning unril the delimiter or all the string if no delimiter were found:
Second call using with NULL allow you to continue parsing the same string to find the next delimiter:
If you reach the end of the string next call will return NULL;
每当您有一个
std::string
并且您需要的是一个(可修改的)字符数组时,那么std::vector
就是您所需要的:Whenever you have a
std::string
and what you need is a (modifiable) character array, thenstd::vector<char>
is what you need:第二个 strtok 调用位于循环内部。它使您的令牌指针前进,以便您逐一打印出令牌,直到打印出所有令牌为止,指针变为空并退出循环。
要回答您问题的第一部分,正如其他人所建议的那样, c_str() 只为您提供内部缓冲区指针 - 您无法修改它,这就是它是 const 的原因。如果你想修改它,你需要分配自己的缓冲区并将字符串的内容复制到其中。
the 2nd strtok call is inside the loop. It advances you token pointer so that you print out tokens one-by-one, until you've printed out all of them, the pointer becomes null and you exit the loop.
To answer the 1st part of your question, as other have suggested, c_str() only gives you the internal buffer pointer - you can't modify that, that's why it's const. If you want to modify it, you need to allocate your own buffer and copy the string's contents into it.
如果您确实需要访问字符串的内部缓冲区,请执行以下操作:
&*string.begin()
。在某些情况下,直接访问字符串的缓冲区很有用,在这里你可以看到这样的一个案例。
If you really need to access the string's internal buffer here is how:
&*string.begin()
.Direct access to string's buffer is useful in some cases, here you can see such a case.
您可以轻松编写一个转换例程来标记字符串并返回子字符串向量:
You can easily write a conversion routine that will tokenize a string and return a vector of sub-strings:
我认为您可以首先将 string 转换为 const char*,然后将 const char* 复制到 char* 缓冲区以供进一步使用。
I think you can first convert string to const char*, then copy the const char* to a char* buffer for further use.