C++std::字符串流到常量字符*的转换

C++ std::stringstream to const char* conversion

本文关键字:转换 字符 字符串 C++std 常量      更新时间:2023-10-16

我试图将stringstream转换为const char*,但总是得到一个空字符串。

我的代码:

#include<string>
#include<sstream>
#include<stdio.h>
const char* test(std::string city, std::string street, int houseNumber, int postCode) {
std::stringstream ss;
ss << city << " " << street << " " << houseNumber << " " << postCode;
const std::string tmp =  std::string{ss.str()};
const char* str = tmp.c_str();
return str;
}
int main(){
printf(test("demo", "Demo", 1, 1234));
}

预期输出:demo Demo 1 1234

我尝试了"如何将std::string转换为const char*或char*?"中提到的所有增强功能?,但我没有成功。

问题是const char*指向的字符串数据在return str;之后被释放。只要关联的std::string实例在作用域内,const char*指针将保持有效。这是假设您在这里显示的代码位于一个函数中。在这种情况下,字符串tmp将在return str;之后超出作用域,并且它的析构函数将被调用,导致任何指向其字符数据的指针都变成悬空指针。

返回一个std::string,并对返回的字符串调用c_str()。如上所述,只要关联的std::string实例在作用域内,就可以使用const char*指针。

您遇到的问题是,当此函数离开作用域时(即,当return str;执行时(,str指向的内存将被清除。您需要返回一个对象,该对象将保持对数据的所有权。

//std::string_view is >=c++17, use std::string const& for older compilers
std::string get_formatted_address(
std::string_view city, 
std::string_view street, 
std::string_view houseNumber, 
std::string_view postCode
) {
std::stringstream ss;
ss << city << " " << street << " " << houseNumber << " " << postCode;
return ss.str();
}
int main() {
auto city = "New York", street = "Rockefeller Lane", houseNumber = "1234", postcode = "56789";
auto formatted_address = get_formatted_address(city, street, houseNumber, postcode);
//Here, formatted_address holds ownership over the memory, so calling c_str is safe
printf("Address: %sn", formatted_address.c_str());
}

通过使用static thread_local存储临时对象,可以将悬挂引用转换为非悬挂引用。

请注意,一次只能有一个活动的"非悬挂"引用:

#include <string>
#include <sstream>
#include <iostream>
const char* to_cstr(std::string && s)
{
static thread_local std::string sloc;
sloc = std::move(s);
return sloc.c_str();
}
const char* make_address(std::string const& city, 
std::string const& street, 
std::string const& houseNumber, 
std::string const& postCode)
{
std::stringstream ss;
ss << city << " " << street << " " << houseNumber << " " << postCode;
return to_cstr(std::move(ss).str());
}
int main()
{
const char* p = make_address("London","Bob Street","42","W1ABC");
std::cout << p << std::endl;
}

预期输出:

London Bob Street 42 W1ABC

http://coliru.stacked-crooked.com/a/228e6c0cb8359222