Шифрование заданной строки текста — шифр Цезаря

Изменить: это известно как шифр Цезаря.
Я пытался создать программу, основной целью которой было шифрование заданной (короткой и строчной) строки. Это будет сделано путем сдвига всех букв N пробелы вправо (шифрование) или влево (декодирование).

Вот что я написал до сих пор (отредактировано)

#include "stdafx.h"#include <iostream>
#include <string>
using namespace std;

char abc[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'};

void code(int n) {
string cadena;
cout << "Introduzca la cadena a cifrar : " << '\n';
cin >> cadena;

for (int i(0); i < cadena.length; i++) {
for (int f(0); f < strlen(abc); f++) {
if (cadena[i] == abc[f]) {
int w;
w = f + n;
if (w > strlen(abc)) {
w -= strlen(abc);
}
cadena[i] = abc[w];
}
}
}
cout << cadena << '\n';
system("pause");
}

void decode(int n) {
string cadena;
cout << "Introduzca la cadena a cifrar : " << '\n';
cin >> cadena;

for (int i(0); i < cadena.length; i++) {
for (int f(0); f < strlen(abc); f++) {
if (cadena[i] == abc[f]) {
int w;
w = f - n;
if (w < 0) {
w--;
w = strlen(abc) - w;
}
cadena[i] = abc[w];
}
}
}
cout << cadena << '\n';
system("pause");
}

int main() {
int n;
cout << "Introduzca el numero del cesar " << '\n';
cin >> n;
cout << "Desea usted cifrar o descifrar?" << '\n';
cout << "Introduzca c para cifrar o d para descifrar" << '\n';
char chos;
cin >> chos;
if (chos == 'c')
code(n);
else
decode(n);

return 0;
}

Теперь проблема в том, что я получаю ужасную строку, которую я даже не знаю, как она образовалась. И есть еще одна ошибка.

Это результат

0

Решение

Давайте начнем с быстрой прогулки по коду.

char abc[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' };

Это хорошо. Это не обрабатывает верхний регистр, но хорошее начало

void code(int n)
{
char cadena;

Определяет одинокого персонажа. Позже мы увидим, что это не то, что вы хотите.

    char * cadena_ptr = &cadena;

В нормальных условиях это хорошая идея, но с одним символом, не очень полезная

    cout << "Introduzca la cadena a cifrar : " << '\n';
cin >> cadena;

Здесь вещи начинают идти не так, как надо. Код только читается в одном-единственном символе из-за того, как cadena был определен.

    for (int i(0); i <= sizeof(cadena); i++)

Как упоминалось ранее cadena один персонаж так i <= sizeof(cadena) такой же как i <= 1, это приводит к 2 итерациям цикла. Один для i=0 (0<=1) и один для i=1 (1<=1). Это означает, что цикл выйдет за пределы cadenaодин персонаж Результаты этого не определены. Программа может аварийно завершить работу. Программа может перезаписать и повредить данные вокруг cadena, Программа может съесть кошку вашего соседа. Все было бы совершенно справедливо, но первые два гораздо вероятнее, чем третий.

    {
for (int f(0); f <= 26; f++)

Это также выходит за пределы. Этот цикл также может не понадобиться. В 2017 году очень маловероятно, что вы когда-либо увидите кодировку символов, которая не хранит все символы в восходящем непрерывном блоке. Тем не менее, этот цикл грубой силы исключает возможность столкновения с устаревшей кодировкой или символом Bizzaro, который шифрует порядок символов.

Я собираюсь придерживаться этого цикла, потому что вопрос на самом деле не об арифметике ASCII.

        {
if (*cadena_ptr == abc[f])
{
int w;
w = f + n;
if (w >= 26)
{
w -= 26;
}
*cadena_ptr = abc[w];

Весь этот блок выглядит хорошо и должен работать, как только будут решены проблемы с индексацией. Однако есть одно улучшение. Как только вы нашли один матч, вы можете перестать искать больше. Также много использования магическое число 26 это должно быть заменено.

            }
}

}
cout << cadena << '\n';
system("pause");
}

Очистка до этапа 1:

Исправить отключение одним индексированием. Это довольно быстро:

    for (int i(0); i < sizeof(cadena); i++)
{
for (int f(0); f < sizeof(abc); f++) // death to magic number!

Следующее чтение более чем в одном символе:

Правильный путь! использование std::string и Диапазон на основе for петля

void code(int n)
{
std::string cadena;
//char * cadena_ptr = &cadena; obsoleted by std::string

cout << "Introduzca la cadena a cifrar : " << '\n';
cin >> cadena;

for (char & ch:cadena)// loop through all characters in cadena
{
for (int f(0); f < sizeof(abc) ; f++)
{
if (ch == abc[f])
{
int w;
w = f + n;
if (w >= sizeof(abc))
{
w -= sizeof(abc);
}
ch = abc[w];
break;// we found it! Stop looking.
}
}
}
cout << cadena << '\n';
system("pause");
}

Я не собираюсь тратить свое время на неправильный путь. Это не правильно. Научиться использовать std::string,

Если требования проекта говорят нет std::string, не делай это неправильно. Сделай что-нибудь совершенно другое! Читайте символы один за другим, конвертируйте их и распечатывайте. Чтобы зашифровать, пока мы не найдем символ, который не может быть преобразован, мы могли бы сделать что-то вроде:

bool goodchar(char & cadena, int n)
{
for (int f(0); f < sizeof(abc) ; f++)
{
if (cadena == abc[f])
{
int w;
w = f + n;
if (w >= sizeof(abc))
{
w -= sizeof(abc);
}
cadena = abc[w];
return true;
}
}
return false;
}

void code(int n)
{
char cadena;

cout << "Introduzca la cadena a cifrar : " << '\n';
cin >> cadena; // get first character

while (goodchar(cadena)) // keep looping until we find a character that's
// not in the list
{
cout << cadena << '\n';
cin >> cadena; // get next character
}
cout << '\n';
system("pause");
}
3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]