Почему я получаю две разные строки? - PullRequest
0 голосов
/ 09 декабря 2011

Я написал очень простую программу шифрования для практики c ++, и я столкнулся с этим странным поведением.Когда я преобразовываю свой массив char * в строку, устанавливая строку, равную массиву, я получаю неверную строку, однако, когда я создаю пустую строку и добавляю символы в массив отдельно, это создает правильную строку.Может кто-нибудь объяснить, почему это происходит, я только начал программировать на c ++ на прошлой неделе, и я не могу понять, почему это не работает.

Кстати, я проверил онлайн, и это, по-видимому, оба действительных способа преобразования массива символовв строку.

void expandPassword(string* pass)
{
    int pHash = hashCode(pass);
    int pLen = pass->size();
    char* expPass = new char[264];
    for (int i = 0; i < 264; i++)
    {
        expPass[i] = (*pass)[i % pLen] * (char) rand();
    }
    string str;
    for (int i = 0; i < 264; i++)
    {
        str += expPass[i];// This creates the string version correctly
    }

    string str2 = expPass;// This creates much shorter string
    cout <<str<<"\n--------------\n"<<str2<<"\n---------------\n";

    delete[] expPass;
}

РЕДАКТИРОВАТЬ: я удалил все нули из массива, и это ничего не изменило

Ответы [ 4 ]

0 голосов
/ 09 декабря 2011

Я полагаю, что следующая строка обрезает вашу строку:

expPass[i] = (*pass)[i % pLen] * (char) rand();

Если rand () возвращает 0, вы получаете терминатор строки в позиции i.

0 голосов
/ 09 декабря 2011

При копировании из char * в std :: string оператор присваивания останавливается, когда достигает первого символа NULL.Это указывает на проблему с вашим «шифрованием», которая вызывает использование встроенных символов NULL.

Это одна из основных причин, по которой кодирование используется с зашифрованными данными.После шифрования полученные данные должны быть закодированы с использованием алгоритмов Hex / base16 или base64.

0 голосов
/ 09 декабря 2011

Это связано с тем, что str2 = expPass интерпретирует expPass как строку в стиле C, что означает, что нулевой ("нулевой") байт '\0' указывает на конец строки.Так, например, это:

char p[2];
p[0] = 'a';
p[1] = '\0';
std::string s = p;

приведет к тому, что s будет иметь длину 1, так как p имеет только один ненулевой байт до его окончания '\0'.Но это:

char p[2];
p[0] = 'a';
p[1] = '\0';
std::string s;
s += p[0];
s += p[1];

приведет к тому, что s будет иметь длину 2, потому что он явно добавляет оба байта к s.(A std::string, в отличие от строки в стиле C, может содержать фактические нулевые байты - хотя это не всегда хорошая идея, чтобы воспользоваться этим.)

0 голосов
/ 09 декабря 2011

c-строка, поскольку то, что вы создаете, представляет собой серию символов, заканчивающуюся значением \ 0 (ноль) ascii.

в случае

expPass[i] = (*pass)[i % pLen] * (char) rand();

возможно, вы вставляете \ 0 в массив, если выражение имеет значение 0, а также вы не добавляете \ 0 в конец строки, чтобы убедиться, что это допустимая c-строка.

когда вы делаете

string str2 = expPass;

вполне может быть так, что строка становится короче, так как она усекается, когда находит где-то в строке \ 0.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...