в
for (i = 1; i <= 26; i++) { // Run 26 times (1 for each letter)
letters_cipher[i] = letters[(i + (i + 1)) % 26];
вы пишете 2 индекса из letters_cipher
, являющегося char letters_cipher[25];
, поведение не определено
и в
for (k = 0; k <= 25; k++) {
if (String[i] == letters[k]) {
cout << letters_cipher[k];
}
вы читаетеодин индекс из letters_cipher
, поведение снова не определено
Максимально допустимый индекс в letters_cipher
равен 24
Обратите внимание, что в
for (unsigned int i = 0; i < strlen(letters_cipher); i++) {
cout << letters_cipher[i];
}
strlen(letters_cipher)
тоже не будет работать, потому что нигде в вашем коде, где вы вводите в него нулевой символ конца, поэтому strlen также выйдет из инициализированной части letters_cipher
и может быть снова из нее.
У вас также есть проблема в:
for (unsigned int i = 0; i < strlen(String); i++) {
String[i] = '\0';
}
, потому что вы делаете strlen(String)
первый цикл без инициализации String , замените его на 500 (или лучше используйте стандартный:: string)
Есть идеи, как я могу это исправить?
В общем случае не используйте числа типа 26 или 25 в своих циклах, используйте sizeof
, и вы также можете использовать std :: vector вместо (C) массивов.Когда содержимое является постоянным, не делайте размер самостоятельно, поэтому для letters
просто сделайте:
static const char letters_cipher[] = {
'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'
};
Вероятно, letters_cipher
должен иметь тот же размер, что и letters
, и исправьте набор, потому что for начинаетсяна 1, а не 0
Дополнительные замечания
- массив
letters
бесполезен, он содержит только буквы a..z, поэтому letters[i]
это просто 'a' + i
- вы делаете и
using namespace std;
, и std::xxx
, выберите один из них (многие скажут, что вы не делаете using namespace std;
)
Предложение, если яхорошо понимают ваш сценарий:
#include <iostream>
#include <string>
class Encrypt {
private:
std::string str;
char letters_cipher['z' - 'a' + 1];
inline char letter(size_t i) { return 'a' + i; } // to help
public:
Encrypt() {} // default definition is useless in fact
~Encrypt() {} // default definition is useless in fact
bool Getstr() {
std::cout << "Enter str : ";
return (std::cin >> str); // to indicates EOF in case
}
void encrypt() {
for (size_t i = 1; i <= sizeof(letters_cipher); i++) { // Run 26 times (1 for each letter)
letters_cipher[i - 1] = letter((i + (i + 1)) % 26);
std::cout << letters_cipher[i - 1] << std::endl;
}
for (size_t i = 0; i < str.length(); i++) { // individual characters of string x can be referenced by x[0] etc
for (size_t k = 0; k < sizeof(letters_cipher); k++) {
if (str[i] == letter(k)) {
std::cout << letters_cipher[k];
}
}
}
std::cout << std::endl;
}
void Print() {
for (size_t i = 0; i < sizeof(letters_cipher); i++) {
std::cout << letters_cipher[i];
}
std::cout << std::endl;
}
};
int main()
{
Encrypt e;
e.Getstr();
e.encrypt();
e.Print();
}
Компиляция и выполнение:
/tmp % g++ -pedantic -Wextra e.cc
/tmp % ./a.out
Enter str : azerty
d
f
h
j
l
n
p
r
t
v
x
z
b
d
f
h
j
l
n
p
r
t
v
x
z
b
dbllpz
dfhjlnprtvxzbdfhjlnprtvxzb
Выполнение под valgrind :
/tmp % valgrind ./a.out
==29157== Memcheck, a memory error detector
==29157== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==29157== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==29157== Command: ./a.out
==29157==
Enter str : azerty
d
f
h
j
l
n
p
r
t
v
x
z
b
d
f
h
j
l
n
p
r
t
v
x
z
b
dbllpz
dfhjlnprtvxzbdfhjlnprtvxzb
==29157==
==29157== HEAP SUMMARY:
==29157== in use at exit: 0 bytes in 0 blocks
==29157== total heap usage: 4 allocs, 4 frees, 115 bytes allocated
==29157==
==29157== All heap blocks were freed -- no leaks are possible
==29157==
==29157== For counts of detected and suppressed errors, rerun with: -v
==29157== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)