14

在 std::string 中,只有 const 成员可以像 c_str() 这样获取数据。但是,我可以通过获取对字符串第一个元素的引用,operator[]并且可以对其进行写入。

例如,如果我有功能:

void toupper(char *first,char *last_plus_one);

我可以直接写入 vector 以获取指向第一个元素的指针:

vector<char> message // has "Some Message";
toupper(&message[0],&message[0]+message.size());

我可以用 std::string 做同样的事情吗?

string message="Some Message";
toupper(&message[0],&message[0]+message.size());

标准是否保证内存的位置实际上是线性的?IE:

&(*(message.begin()+n)) == &message[n]

谢谢。

4

5 回答 5

22

Herb Sutter 有这个说法(http://herbsutter.wordpress.com/2008/04/07/cringe-not-vectors-are-guaranteed-to-be-contiguous/#comment-483):

当前的 ISO C++ 确实需要 &str[0] 提供一个指向连续字符串数据的指针(但不一定以 null 结尾!),因此无论如何,实现者没有太多余地来拥有非连续字符串。对于 C++0x,我们已经采用了 std::string 内容确实必须连续存储的保证。有关详细信息,请参阅http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#530

Matt Austern 在参考文件(http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#530)中也说过类似的话。

因此,您似乎可以假设,一旦您调用 str[0],您确实会得到一个可修改的字符数组(但请注意,它不需要以空值终止)。

于 2009-04-17T15:31:13.250 回答
17

std::string 需要使用新的 c++0x 标准进行连续存储。目前这是未定义的行为。

于 2009-04-17T15:08:21.650 回答
5

是的,您可以修改字符串。

您也可以在使用迭代器的算法中使用它。

您不能以与 vector<> 相同的方式使用它,因为不能保证元素位于连续的内存位置(但是:很快就会成为您附近的标准)。

因此,如果您修改方法以使用迭代器而不是指针,它应该可以工作。由于迭代器的行为与指针非常相似,因此代码更改应该可以忽略不计。

template<typename I>
void toupper(I first,I last_plus_one)
{
    // Probably the same code as you had before.
}


{
     std::string  s("A long string With Camel Case");

     toupper(s.begin(),s.end());
}
于 2009-04-17T15:47:40.917 回答
3

正如已经指出的那样,可以在使用迭代器的算法中使用字符串;可以使用std::transformEx 实现相同的情况:- 考虑将字符串 's' 转换为小写:

int (*pf)(int)=tolower; //lowercase
std::transform(s.begin(), s.end(), s.begin(), pf); 

问候,

于 2009-04-17T17:15:43.623 回答
-2

我认为它给了你一个未定义的行为。使用 stringstream 写入,然后使用 str() 成员获取流的字符串。

于 2009-04-17T15:11:10.770 回答