简体   繁体   English

将std :: string转换为const char *,获取错误

[英]Converting std::string to const char*, getting errors

#include <iostream>
#include <sstream>

template <typename T>
const char* numberToString(T number) {
    std::ostringstream ss;
    ss << number;
    return ss.c_str();
}

int main() {
    printf(numberToString(123));
    return 0;
}

My error: 我的错误:

1>d:\programming\euler\problem 4\problem 4\problem 4\source.cpp(8): error C2039: 'c_str' : is not a member of 'std::basic_ostringstream<char,std::char_traits<char>,std::allocator<char>>'
1>          d:\programming\euler\problem 4\problem 4\problem 4\source.cpp(26) : see reference to function template instantiation 'const char *numberToString<int>(T)' being compiled
1>          with
1>          [
1>              T=int
1>          ]

Why doesn't this work? 为什么这不起作用?

c_str is a member of std::string , not ostringstream . c_strstd::string的成员,而不是ostringstream If you want to get a string out of the stream, use str() . 如果str()流中获取string ,请使用str() Note, however, that returning a const char* from that string is wrong - the string will go out of scope before you can use the const char* . 但是请注意,从该string返回const char*是错误的 - 在使用const char*之前, string将超出范围。 Therefore, have your function return a string (or have it get a buffer to write to): 因此,让您的函数返回一个string (或让它获取一个缓冲区来写入):

template <typename T>
std::string numberToString(T number) {
    std::ostringstream ss;
    ss << number;
    return ss.str();
}

c_str() does not exist for std::ostringstream . std::ostringstream不存在c_str() What you meant was: 你的意思是:

template <typename T>
const char* numberToString(T number) 
{
    std::ostringstream ss;
    ss << number;
    return ss.str().c_str();
}

After you make that change, you will have another problem: you will be returning a pointer to a buffer that was just destroyed. 进行更改后,您将遇到另一个问题:您将返回一个指向刚刚销毁的缓冲区的指针。 To fix that, you should return a std::string : 要解决这个问题,你应该返回一个std::string

template <typename T>
std::string numberToString(T number) 
{
    std::ostringstream ss;
    ss << number;
    return ss.str();
}

Which you can do with std::to_string already, so it is really pointless to write your own function. 您已经可以使用std::to_string ,因此编写自己的函数真的没有意义。

That's because c_str() is the member function of std::string which returns a const char* . 那是因为c_str()std::string的成员函数,它返回一个const char*

To get the underlying string of a strinstream, you must use str() . 要获取strinstream的基础字符串,必须使用str()

The error was pretty much self explanatory: 错误几乎是自我解释的:

error C2039: 'c_str' : is not a member of 'std::basic_ostringstream 错误C2039:'c_str':不是'std :: basic_ostringstream的成员

Note however that you're returning a pointer to something (the underlying data of the temporary string returned by str() ) that will not exist after the return statement (ie in the calling code) and that manipulating that pointer will quite sureley end up in undefined behavior. 但请注意,您正在返回一个指向某些内容的指针(由str()返回的临时字符串的基础数据),该指针在返回语句之后(即在调用代码中)将不存在,并且操作该指针将非常肯定会结束在未定义的行为。

As you are in C++, you could rather return the std::string directly, and output it with 就像你在C ++中一样,你宁愿直接返回std::string ,并输出它

std::cout << numberToString(123);

which would be safer. 这会更安全。

You want to do: 你想做:

template <typename T>
std::string numberToString(T number) {
    std::ostringstream ss;
    ss << number;
    return ss.str();
}

int main() {
    std::cout << numberToString(123);
    return 0;
}

To get the underlying std::string in std::ostringstream , and then the resulting c-style string in std::string . 获取std::ostringstream的底层std::string ,然后在std::string生成c样式std::string As others have pointed out, the pointer returned by c_str goes out of scope, and therefore you must copy it to a buffer or to another std::string . 正如其他人指出的那样, c_str返回的指针超出了范围,因此您必须将其复制到缓冲区或另一个std::string If you insist on using printf , then use c_str on the function call: 如果你坚持使用printf ,那么在函数调用上使用c_str

printf("%s", numberToString(123).c_str());

For more information, see Is it a good idea to return " const char * " from a function? 有关更多信息,请参阅从函数返回“const char *”是否是一个好主意?

Depending on what somestlstring is and what is being done there. 取决于somestlstring是什么以及在那里做了什么。

If it is a local variable you are returning a pointer into memory that is being released when GetSomeString completes, so it is a dangling pointer and an error. 如果它是一个局部变量,则返回指向GetSomeString完成时释放的内存的指针,因此它是一个悬空指针和一个错误。

It all boils down to the lifetime of somestlstring and the operations you perform on it. 这一切都归结为somestlstring的生命周期以及你对它执行的操作。 The pointer returned by .c_str() is guaranteed to be valid only up to the next mutating operation in the string. 由.c_str()返回的指针保证仅在字符串中的下一个变异操作时有效。 So if something changes somestlstring from the call to .c_str() and before s is constructed you will be in undefined behavior land. 因此,如果某些内容从调用.c_str()更改somestlstring,并且在构造s之前,您将处于未定义的行为域。

However, you can simply use std::to_string . 但是,您可以简单地使用std::to_string

std::string s = std::to_string(123);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM