2009-04-17 49 views
14

在std :: string中,只有const成員可以像c_str()那樣獲取數據。不過,我可以通過operator[]獲得字符串的第一個元素的引用,我可以寫入它。寫入std :: string是否合法?

舉例來說,如果我有功能:

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

我可以直接寫信給矢量獲得一個指向第一個元素:

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()); 

標準是否確保內存的位置實際上是線性的?即:

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

謝謝。

+0

不能您只需模板化的TOUPPER功能,允許使用字符串迭代器而不是指針? – jalf 2009-04-17 15:17:53

+0

如果我能我不會問。想想我有一個龐大的第三方庫,可能支持Unicode或其他的東西,他們的API使用指針。因爲將它作爲模板來實現只需花費很多成本。 – Artyom 2009-04-17 15:20:32

+0

@jalf:我手邊沒有這個標準,但我相信std :: to_upper正是你的建議。 – 2009-04-17 16:19:26

回答

17

std :: string將被要求與新的C++ 0x標準進行連續存儲。目前這是未定義的行爲。

+7

是否有使用非連續字符串的編譯器? I.E.我可以在99%的案例中涉及到(可能只是針對特定的編譯器進行變通以避免複製開銷) – Artyom 2009-04-17 15:11:56

-1

我認爲它給你一個未定義的行爲。使用stringstream來寫入,然後使用str()成員來獲取流的字符串。

22

香草薩特有這樣說(http://herbsutter.wordpress.com/2008/04/07/cringe-not-vectors-are-guaranteed-to-be-contiguous/#comment-483):(!但不一定空終止)

當前ISO C++確實需要& STR [0]咳出的指針連續串的數據,所以無論如何,實施者不會有非連續的字符串。對於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],你會得到一個可修改的字符數組(但是請注意,它不需要以null結尾)。

5

是的,你可以修改一個字符串。

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

您不能像使用矢量<>那樣使用它,因爲不能保證元素處於連續的內存位置(然而:即將到達您附近的標準)。

所以,如果你修改你的方法來使用迭代器而不是指針,它應該工作。而且因爲迭代器的行爲非常像指針,所以代碼更改應該可以忽略不計。

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()); 
} 
3

正如已經指出的那樣,可以在使用迭代器的算法中使用字符串;同樣的情況下,可以使用std::transform例來實現: - 考慮一個字符串的'轉換爲小寫:

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

問候,

相關問題