【问题标题】:Strange anomalies when converting an array of chars to a string将字符数组转换为字符串时出现奇怪的异常
【发布时间】:2014-08-28 17:47:42
【问题描述】:

我正在尝试构建一个程序,该程序利用替换表和密钥来生成密码/加密文本。到目前为止,我已经成功地将加密文本存储在一个 char 数组中。如果我使用 for 循环遍历文本,它每次都能完美运行。但是,我需要将加密文本作为字符串返回。这是我正在使用的方法...

string ciphertext = cipherArray; //cipherArray is of type char

当我尝试计算密文时,它有时会正常输出,有时会显示一些正确的字母,然后是奇怪的符号。当我使用 for 循环打印数组时,它工作得很好,但是将它转换为字符串给我带来了问题。从字符转换为字符串时,它似乎正在存储超出范围的项目。

这是完整的程序:(问题在加密方法定义下)

#include <iostream>
#include <string>
using namespace std;

//=============================================================================
//                          -Cipher Class-
//
class Cipher {
    public:
        Cipher();
        Cipher(string key);
        Cipher(string key, string message);

        void newKey();
        string inputMessage();
        string encipher(string message);
        string decipher(string message);
        string getPlainText() const;
        string getCipherText() const;

    private:
        void initAlphabet();
        void initTable();

        char alphabet[26];
        char table[26][26];
        string key;
        string plaintext;
        string ciphertext;
};

//=============================================================================
//                          -Main-
//
int main()  {
    Cipher myCipher;

    cout << "Key: ";
    myCipher.newKey();
    cout << endl;

    cout << "Message: ";
    myCipher.encipher(myCipher.inputMessage());


    return 0;
}

//=============================================================================
//                          -Constructor-
//
Cipher::Cipher() {
    initAlphabet();
    initTable();
}

//=============================================================================
//                          -Initialize Alphabet-
//
void Cipher::initAlphabet() {

    char alphaStore[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m',
                         'n','o', 'p','q','r','s','t','u','v','w','x','y','z'};

    for (int i = 0; i < 26; i++)
        alphabet[i] = alphaStore[i];
}

//=============================================================================
//                          -Initialize Table-
//
void Cipher::initTable() {

    int alphaIndex = 0;

    for (int index1 = 0; index1 < 26; index1++) {
        for (int index2 = 0; index2 < 26; index2++) {   

            if ((index1 + index2) < 26) {
                alphaIndex = index1 + index2;
                table[index1][index2] = alphabet[alphaIndex];
            }
            else
                alphaIndex = 0;

            while (((index1 + index2) > 25) && index2 < 26) {
                table[index1][index2] = alphabet[alphaIndex];
                index2++;
                alphaIndex++;
            }           
        }               
    }
}


//=============================================================================
//                          -Input Message-
//
string Cipher::inputMessage() {
    cin >> plaintext;
    return plaintext;
}

//=============================================================================
//                          -New Key-
//
void Cipher::newKey() {
    cin >> key;
}

//=============================================================================
//                          -Encipher-
//
string Cipher::encipher(string message) {

    int iTableRow, iTableCol, i;
    unsigned int iKey, iMsg;
    int keyValStorage[key.length()];
    int msgValStorage[message.length()];
    char cipherArray[message.length()];    

    for (iKey = 0; iKey < key.length(); iKey++)
        for (iTableCol = 0; iTableCol < 26; iTableCol++)
            if (key[iKey] == table[0][iTableCol]) {
                keyValStorage[iKey] = iTableCol;
                iTableCol = 26;
            }

    for (iMsg = 0; iMsg < message.length(); iMsg++)
        for (iTableRow = 0; iTableRow < 26; iTableRow++)
            if (message[iMsg] == table [0][iTableRow]){
                msgValStorage[iMsg] = iTableRow;
                iTableRow = 26;
            }

    for (iKey = 0, iMsg = 0; iMsg < message.length(); iKey++, iMsg++) {
        if (iKey > (key.length() - 1))
            iKey = 0;
        cipherArray[iMsg] = table[keyValStorage[iKey]][msgValStorage[iMsg]];
    }         

    for (iKey = 0; iKey < message.length(); iKey++) 
        cout << cipherArray[iKey] << " ";   //This prints the encrypted text fine

    ciphertext = cipherArray; //This produces anomalies in the output.
    cout << ciphertext;

    return "placeholder";             

}

【问题讨论】:

  • 你如何期望构造函数知道要复制多少字节? (您的for 循环是如何知道的?发布一些代码。)
  • 好的,当我使用 for 循环打印 cipherArray 时,我使用了原始消息(要加密)的长度作为限制。将 char 数组转换为字符串类型时如何指定这个? cipherArray 的大小始终与要加密的原始消息的长度相同。
  • 您必须像 Arnold 一样终止字符串....或提供开始和结束迭代器。只是取决于你如何构造std::string 的实例
  • @Victor 使用采用范围或序列的构造函数。它不能靠魔法起作用。 (如果您向我们展示您的一些代码,我可以向您展示实际代码。)

标签: c++ arrays string char type-conversion


【解决方案1】:

std:string 有一个constructor,它接受一个char 缓冲区和一个字符串长度。只需使用:

string ciphertext = string(cipherArray, /*length_of_cipherArray_here*/);

甚至更短:

string ciphertext(cipherArray, /*length_of_cipherArray_here*/);

当然,这里假设 cipherArray 是 char[]char*

【讨论】:

  • 这就是我要找的!谢谢 metacubed!
猜你喜欢
  • 1970-01-01
  • 2017-05-22
  • 1970-01-01
  • 2015-10-19
  • 2021-10-06
  • 2013-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多