我有一个// C function
void foo(char* buf);
// C++ code
std::string str("str");
foo(&str[0]);
类的对象需要传递给C函数,该函数通过遍历它并搜索空终止符号来操作std::string
缓冲区。
所以,我有这样的事情:
&str[0]
假设我们使用C ++ 11,因此我们保证\0
表示将具有连续存储的字符。
但我想知道是否有c_str
指向以operator[]
结尾的缓冲区?是的,有didFinishLaunchingWithOptions launchOptions:
成员函数,但我在谈论var accessToken = ""
if let key = NSUserDefaults.standardUserDefaults().objectForKey("accesstoken"){
accessToken = key as! String
}
。
有人可以引用标准吗?
答案 0 :(得分:7)
在实践中,是的。 std::string
完全没有符合标准的实现,它们不会在缓冲区的末尾存储NUL字符。
所以如果你不想知道这个想法,你就完成了。
但是,如果你想知道该标准是否已被证实:
在C ++ 14中,是的。明确要求[]
返回一组连续的元素,[size()]
必须返回一个NUL字符,而const方法可能不会修改状态。因此*((&str[0])+size())
必须与str[size()]
相同,str[size()]
必须是NUL,因此游戏结束。
在C ++ 11中,几乎可以肯定。有些规则const
方法可能无法修改状态。可以保证data()
和c_str()
返回一个空终止的缓冲区,该缓冲区在每个点都与[]
一致。
对C ++ 11标准进行复杂的阅读会说明在调用data()
或c_str()
之前,[size()]
不会在缓冲区末尾返回NUL终结符而是单独存储的static const CharT
,并且缓冲区具有NUL应该是的单位化(甚至是陷阱值)。由于要求const
方法不能修改状态,我认为这种读数不正确。
这需要在&str[str.size()]
的调用之间进行.data()
更改,这是string
通过const
调用的状态可观察到的更改,我认为这是非法的。
绕过标准的另一种方法可能是,在您通过调用str[str.size()]
,.data()
或实际将.c_str()
传递给{{}合法访问标准之前,不要初始化str.size()
1}}。由于除了标准中的那些元素之外没有定义的方法来访问该元素,因此您可以扩展并说NUL的延迟初始化是合法的。
我对此提出质疑,因为operator[]
的定义意味着.data()
的返回值是连续的,因此[]
与&[0]
的地址相同,并且.data()
保证指向NUL .data()+.size()
,因此必须CharT
,并且没有非(&[0])+.size()
方法称为const
的状态可能不会发生变化电话。
但是,如果编译器看起来并且看到你永远不会调用std::string
或.data()
,那么如果可以证明你从不称呼它们,那么连续性的要求是否成立呢?
此时我会举起手来射击敌对的编译器。
这个标准非常被动地表达出来。因此,可能有一种方法可以使符合.c_str()
的标准符合这些规则。并且由于保证越来越接近明确要求那里的NUL终结符,新的编译器出现的几率使用折磨的C ++读取来声称这符合标准是很低的。
答案 1 :(得分:5)
根据标准,是的。可以使用标准显示的string::data
或string::c_str
访问底层字符容器:
21.4.7.1
basic_string
访问者[string.accessors]
const charT* c_str() const noexcept;
const charT* data() const noexcept;
1 返回:指针
p
,p + i == &operator[](i)
中每个i
[0,size()]
。{ 2 复杂性:恒定时间。
3 要求:程序不得更改存储在字符数组中的任何值。
要证明,它是空终止的,请看operator[]
的定义(强调我的):
21.4.5
basic_string
元素访问[string.access]
const_reference operator[](size_type pos) const;
reference operator[](size_type pos);
1 需要:
pos <= size().
2 返回:*(begin() + pos)
ifpos < size()
。 否则,返回对值为charT
的{{1}}类型的对象的引用,其中修改对象会导致未定义的行为。
3 引发:没什么 4 复杂性:恒定时间。
因此charT()
返回operator[size()]
,由于charT()
为std::string
,std::basic_string<char>
为charT()
。
这意味着,在您的情况下,根据标准,'\0'
始终为*(&str[0] + str.size()) == '\0'
。
请注意,修改true
是UB。