如何解决从字符串中获取 char * 或 const char * 数据中断 16 个或更长的字符串
我有一个函数 string_to_char()
,它试图给我一个字符串形式,我可以将它传递到我正在使用的库中,它需要 char *
(但我认为适用于 {{1} },所以我一直在尝试两者)。
我为测试 const char *
的实现而编写的代码如下:
string_to_char()
这是我得到的输出:
#include <iostream>
const std::string endl = "\n";
char * string_to_char(std::string str)
{
return (char*) str.c_str();
}
int main()
{
std::string test1 = "Some test strin";
std::string test2 = "Some test string";
char * result1 = string_to_char(test1);
char * result2 = string_to_char(test2);
std::cout << "part1" << endl;
std::cout << result1 << endl;
std::cout << string_to_char(test1) << endl;
std::cout << "part2" << endl;
std::cout << result2 << endl;
std::cout << string_to_char(test2) << endl;
std::cout << "done" << endl;
return 0;
}
因此,出于某种原因,part1
Some test strin
Some test strin
part2
Some test string
done
仅适用于 15 个字符或更短的字符串,并从函数直接输出到 std::cout,但似乎无法将其存储到 16 个字符的变量中或更长。
我对 C++ 比较陌生,所以下面的一些代码对于更有经验的程序员来说可能有点奇怪,但这里是我尝试过的代码来代替 string_to_char()
return (char*) str.c_str();
改用 #include <vector>
#include <string.h>
char * string_to_char(std::string str)
{
return (char*) str.c_str();
return const_cast<char*>(str.c_str());
std::vector<char> vec(str.begin(),str.end());
char * chr;
vec.push_back('\0');
chr = (char*) &vec[0];
//chr = & (*vec.begin());
return chr; //all outputs from both are empty with this both versions of chr
return &str[0]; //this makes the output from the 15 character string also be empty when put in a
//variable,but the function going directly to std::cout is fine
return strcpy((char *) malloc(str.length() + 1),str.c_str()); //this one works with everything,but
//it looks like it leaks memory without further changes
std::vector<char> copied(str.c_str(),str.c_str() + str.size() + 1);
return copied.data(); //returns "random" characters/undefined behaviour for both outputs in test1 and is empty for both
//outputs in test2
}
,并将 const
更改为 char * result1 = string_to_char(test1);
(与 const char * result1 = string_to_char(test1);
一样),以查看是否适用于这些其他解决方案:
result2
我得到了很多给定的方法:
How to convert a std::string to const char* or char*?
Converting from std::string to char * in C++
在 https://www.cplusplus.com/reference/ 和 https://en.cppreference.com/w/ 处对字符串和向量的主题进行了一些阅读
解决方法
c_str()
返回的指针只有在字符串存在时才有效。传递引用时会得到 expected output:
auto string_to_char(std::string& str)
{
return str.c_str();
}
因为现在返回的指针在调用者字符串的缓冲区中。在您的代码中,调用者获得一个指向函数本地字符串的指针(因为您传递了一个副本)。
不过,您可以直接调用 c_str()
,而不是调用函数。这也减轻了在字符串扩展到一定程度后仍保持指针的问题。
你想多了。没有必要两个人自己写这个函数。 std::string::data
已存在并返回指向字符串的以空字符结尾的内部缓冲区的指针。假设您使用的是 C++17 或更高版本,如果 const char*
对象是 std::string
限定的(即只读),则此指针将是 const
,否则将是可修改的char*
。
std::string test1 = "string";
const std::string test2 = "const string";
char* result1 = test1.data();
const char* result2 = test2.data();
只要它来自的 std::string
对象处于活动状态且未被修改(修改单个元素除外),此指针就有效。
另请注意,强制转换指针和丢弃 const
-ness 是一种在不知情的情况下导致未定义行为的非常简单的方法。一般来说,您应该避免使用 C 风格的强制转换(例如 (char*)str.c_str()
),因为它们非常不安全。有关详细信息,请参阅 this Q/A on the proper use of C++ casts。
string_to_char()
正在按值获取其 str
参数,因此创建了调用者输入字符串的副本。当函数退出时,复制的 std::string
将被销毁。因此,返回的 char*
指针将悬空,指向已释放的内存,任何使用该指针访问数据的行为都将是未定义行为。
改为通过引用传递 str
参数:
char* string_to_char(std::string &str)
{
return const_cast<char*>(str.c_str());
}
或者,在 C++17 及更高版本中,您可以改用它:
char* string_to_char(std::string &str)
{
return str.data();
}
这就引出了一个问题,为什么您根本需要 string_to_char()
而不要直接使用 data()
,除非您使用的不是现代版本的 C++。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。