2014-11-04 49 views
1

將字符串轉換爲小寫可以轉化的字符串在一個新的字符串

std::transform(s.begin(), s.end(), s.begin(), ::toupper); 

做,但什麼是將其改造成一個新的修改後的副本的最佳方式?

嘗試:

string s1="text",s2; 
std::transform(s1.begin(), s1.end(), s2.begin(), ::toupper); 

,但它在運行時失敗,「段錯誤」

我設法做到這一點:

string s1="text",s2; 
s2 = s1; 
std::transform(s2.begin(), s2.end(), s2.begin(), ::toupper); 

,當然你可以創建一個功能去char字符,但我不認爲這是最佳的,我不學什麼,從這...

+5

您需要'std :: back_inserter()'。 – 0x499602D2 2014-11-04 22:27:31

+0

你應該使用'std :: toupper'並確保如果'char'被簽名,負值不會被傳遞給它,以免你有未定義的行爲。 – chris 2014-11-04 22:33:45

+0

@chris這個例子實際上是從[cppreference](http://en.cppreference.com/w/cpp/algorithm/transform)網站複製粘貼的, 那麼std :: string是否有unsigned char或負值? – 2014-11-04 22:38:17

回答

5

std::transform不知道容器和不會爲您插入新的元素。
std::back_inserter提供了一個迭代器,push_back的分配的值:

// DO NOT use this 
std::transform(s1.begin(), s1.end(), std::back_inserter(s2), ::toupper); 
//         ^^^^^^^^^^^^^^^^^^^^^^ 

但是,你不應該使用的toupper全球版本,因爲它是不推薦使用。
也是你have to cast the argument to unsigned char首先,或者未定義的行爲很容易遇到。

transform似乎不適合在這裏,因爲你需要一個lambda;使用

for (auto ch : s1) 
    s2 += std::toupper((unsigned char)ch); 

Demo

+0

因此''unsigned char'問題需要使用lambda? 所以這使得 轉換(str-> begin(),str-> end(),str-> begin(),:: tolower);'也是無效的? – 2014-11-04 23:16:54

+0

@clickstefan首先需要一個lambda來調用'std :: tolower'。是的,帶有'transform'的行是無效的。問題是用'char'調用(toloft)的非本地版本通常是錯誤的。 – Columbo 2014-11-04 23:28:46

1

除非使用std::transform是一個要求,你可以使用:

string s1="text"; 
string s2 = s1; 
for (auto& ch : s2) 
    ch = toupper((unsigned char)ch); 
+0

哦,我完全忽略了你的循環與我的不同:)無論如何,代碼仍然缺乏演員。 – Columbo 2014-11-04 23:00:30

+0

我不明白需要鑄造。'std :: toupper()'接受一個'int'作爲輸入。 – 2014-11-04 23:00:42

+2

http://stackoverflow.com/questions/21805674/do-i-need-to-cast-to-unsigned-char-before-calling-toupper – Columbo 2014-11-04 23:03:09

相關問題