Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 直接写入std::string的char*缓冲区_C++_String_C++14_Language Lawyer_C++17 - Fatal编程技术网

C++ 直接写入std::string的char*缓冲区

C++ 直接写入std::string的char*缓冲区,c++,string,c++14,language-lawyer,c++17,C++,String,C++14,Language Lawyer,C++17,所以我有一个std::string,还有一个函数,它接受char*并写入其中。由于std::string::c_str()和std::string::data()returnconst char*,我无法使用它们。所以我分配了一个临时缓冲区,用它调用一个函数并将它复制到std::string 现在我计划处理大量信息,复制这个缓冲区会产生明显的影响,我希望避免这种情况 有些人建议使用&str.front()或&str[0],但它会调用未定义的行为吗?C++98/03 不可能。字符串可以在写入时复制

所以我有一个
std::string
,还有一个函数,它接受
char*
并写入其中。由于
std::string::c_str()
std::string::data()
return
const char*
,我无法使用它们。所以我分配了一个临时缓冲区,用它调用一个函数并将它复制到
std::string

现在我计划处理大量信息,复制这个缓冲区会产生明显的影响,我希望避免这种情况

有些人建议使用
&str.front()
&str[0]
,但它会调用未定义的行为吗?

C++98/03 不可能。字符串可以在写入时复制,因此它需要处理所有读写操作

C++11/14 在[string.require]中:

basic_string
对象中的类字符对象应连续存储。也就是说,对于任何
basic\u字符串

对象
s
,标识
&*(s.begin()+n)==&*s.begin()+n
应适用于
n
的所有值,以便
0可以简单地对非空字符串使用
&s[0]
。这将为您提供一个指向缓冲区开始的指针

当您使用它将一个由n个字符组成的字符串放入其中时,
字符串的长度(不仅仅是容量)需要至少提前为n,因为在不破坏数据的情况下,无法对其进行调整

也就是说,用法可以是这样的:

auto foo( int const n )
    -> string
{
    if( n <= 0 ) { return ""; }

    string result( n, '#' );   // # is an arbitrary fill character.
    int const n_stored = some_api_function( &result[0], n );
    assert( n_stored <= n );
    result.resize( n_stored );
    return result;
}
auto foo(int const n)
->串
{

如果(n我不知道你打算用这个
字符串做什么,但是如果
您所需要的只是一个字符缓冲区,它可以自动释放自己的内存,
然后我通常使用
vector
vector
或任何类型的
你需要多少缓冲

使用
v
作为向量,可以保证
&v[0]
指向

可以用作缓冲区的顺序内存。

回答得好。只需添加一些内容:
std::string
仅自C++11以来是一个连续内存容器。因此,仅自C++11以来,您就可以安全地使用
&str[0]
(之前,它是特定于std lib实现的)在C++11之前,您必须使用一个临时的
std::vector
并将其复制到
std::string
中,或者使用它来实例化一个
std::string
,因为
操作符[]
的定义是“在哪里修改对象会导致未定义的行为”我认为你的答案是错误的。我认为这是标准中的一个缺陷。@Garf365:但实际上,没有一个标准库不为
std::string
(自C++98以来)提供连续内存,所以它一直是安全的,C++11说它永远是安全的。@MartinBonner它说只有
pos==size
。换句话说,你不能触摸终止符号。之前的一切都是公平的。我想我误解了
操作符[]的定义
。未定义的行为仅适用于
pos
不是
的情况。C++17在
std::string
中添加了非常量
数据()
,但它仍然表示不能修改缓冲区。“哈?它在哪里这样说?在访问
&std[0]
&str font()之前”
,…请确保有内存,即
str.size()>0
。如果您刚刚实例化了
str
,请使用
str.resize()
@ildjam,看起来我完全看错了那篇文章。
.data()
应该可以正常工作。
std::string
也是如此,因为C++11及之前的版本,正如MatinBonner在其他答案的评论中所说,尽管这种行为是非标准的,但大多数标准库将
std::string
实现为连续内存
auto foo( int const n )
    -> string
{
    if( n <= 0 ) { return ""; }

    string result( n, '#' );   // # is an arbitrary fill character.
    int const n_stored = some_api_function( &result[0], n );
    assert( n_stored <= n );
    result.resize( n_stored );
    return result;
}