2015-09-03 80 views
0

我想將字符串轉換爲大寫,所以我可以操縱它,但雖然我可以成功地操作自然大寫字符串,以及將小寫字母轉換爲大寫字母,但使用此轉換方法無法進行操作。例如,如果我通過加密傳遞「hello」,我的加密字符串變成「HELLO」,但是當我通過(自然大寫)傳遞「HELLO」時,它會正確地移位。C++ :: toupper不允許平等比較嗎?

是否有不同的方式強制大寫,我需要使用還是我做錯了什麼?

int Caesar::encrypt (const std::string &message, std::string &emessage) { 
    int count = 0; 
    emessage = message; 
    std::transform(emessage.begin(), emessage.end(), emessage.begin(), ::toupper); 
    for (std::string::size_type i = 0; i < message.size(); i++) { 
    for (int j = 0; j < 26; j++) { 
     if (emessage[i] == std_alphabet[j]) { 
     std::replace(emessage.begin(), emessage.end(), message[i], c_alphabet[j]); 
     } 
    } 
    count++; 
    } 
    return count; 
} 

構造:

Caesar::Caesar (int shift) { 
    // loop to populate vector with 26 letters of English alphabet 
    // using ASCII uppcase letter codes 
    for (int i = 0; i < 26; i++) { 
    std_alphabet.push_back(i + 65); 
    } 
    // fills Caesar alphabet with standard generated alphabet 
    c_alphabet = std_alphabet; 
    // shifts Caesar alphabet based off the constructor parameter 
    std::rotate(c_alphabet.begin(), c_alphabet.begin() + shift, c_alphabet.end()); 
} 

測試文件:

void testCaesar() { 
    Caesar test(4); 
    std::string original = "HELLO"; 
    std::string encrypted = ""; 
    test.encrypt(original,encrypted); 
    std::cout << encrypted << std::endl; 
    std::cout << original << std::endl; 
} 

int main() { 
    testCaesar(); 
    return 0; 
} 

顯然有一個報頭,並且包括和的東西,但這是基本的代碼

頭文件包含兩個priv吃載體

+0

什麼是'std_alphabet'?你的'replace'也使用'message [i]',你的意思是'emessage [i]'? – Barry

+0

'std_alphabet'是一個充滿26個英文字母大寫的矢量。 'message [i]'是故意的,因爲它給出了移位所需的正確索引值。 – motifesta

+0

'std_alphabet'是一個字符的向量,'c_alphabet'是一個移位字符的向量。 'message&'引用是指要移動的字符串,而emessage&是一個空字符串。因此,我正在操縱非常量字符串...混淆爲什麼這不工作。 – motifesta

回答

2

你所看到的具體問題是,你要替換錯誤的東西在這裏:

std::replace(emessage.begin(), emessage.end(), message[i], c_alphabet[j]); 

如果message是小寫,那麼emessage將全部大寫的 - 沒有一個會message[i]。所以更換不會做任何事情。您的意思是:

std::replace(emessage.begin(), emessage.end(), emessage[i], c_alphabet[j]); 
               ^^^^^^^^^^^ 

這就是說,你的算法是完全錯誤的HELLO加密爲BCBBA與4的轉變上有字母一對一映射,所以HL不能都去B。你想要做的就是將每封信都按照下一個字母替換。那就是:

for (std::string::size_type i = 0; i < emessage.size(); ++i) { 
    emessage[i] = c_alphabet[emessage[i] - 'A']; 
} 

與您實際上並不需要的初始轉換步驟:

emessage = message; 
for (std::string::size_type i = 0; i < emessage.size(); ++i) { 
    emessage[i] = c_alphabet[::toupper(emessage[i]) - 'A']; 
} 

整個事情可以只是刪除您count(這僅僅是大小刪節了不少無論如何,這是多餘的),並採取值的消息:

std::string encrypt(std::string from) { // intentionally copying 
    for (char& c : from) { 
     c = c_alphabet[::toupper(c) - 'A']; 
    } 
    return from; 
} 
+0

很好的答案。由於OP沒有提到C++ 11,他可能需要使用類似這樣的代碼:'for(int i = 0; i