Шифр Цезаря - ошибка в коде - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Добрый день похожих вариантов задания было много, но не нашла ответа на свой вопрос. Как все таки доделать что бы была шифровка и расшифровка информации? запись и вывод изменю нормально получается, а в шифровке какая-то абракадабра получается. ЗАДАНИЕ: Составить программу, реализующую функции указанного ниже меню. Выполнить функциональное разбиение программного кода. Меню программы: 1 – Сформировать с клавиатуры строку и записать в файл (строка может содержать пробелы); 2 – Считать строку из файла и распечатать; 3 – Зашифровать строку и записать в файл; 4 – Расшифровать строку и записать в файл; 5 – Выход. Каждая буква меняется на следующую по часовой стрелке в алфавите букву, буква "я" остается без изменения.
#include <conio.h>
#include <stdio.h>
#include <locale.h>
#include <string.h>
#include <stdlib.h>
#include <process.h>
#include <windows.h>
#include <malloc.h>
#define RUS 32
 
void vvod(char*); //ввод данных
void vivod (char*); //вывод на экран содержимого файла
void shifr ();
void deshifr();
 
void main ()
{   setlocale(LC_CTYPE, "Russian");
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
    system ("cls");
    fflush(stdin);
    char *C=new char[100];
    int menu=0;
while (1)
{
    int k=0;
    menu=0;
    system("cls");
    puts("Выберите пункт меню:");
    puts("1-Записать строку в файл");
    puts("2-Считать строку из файла и распечатать");
    puts("3-Зашифровать строку и записать в файл");
    puts("4-Расшифровать строку и записать в файл");
    puts("5-Выход");
    scanf_s("%d", &menu);
switch (menu)
{
    case 1: vvod(C); break;
    case 2: vivod(C); break;
    case 3:  shifr(); break;
    case 4: deshifr(); break;
case 5: exit(0);
default: system("cls");
fflush(stdin); 
puts("Неверный выбор, нажмите любую клавишу для возврата в меню"); 
_getch();
}}
_getch();}
 
void vvod(char *C)
{
    system("cls");
    FILE *f1;
    system("cls");
    char *C1= new char [100];
    f1=fopen("f1.txt","w");
    if ((C1!=0)&&(f1!=0))
{
    printf ("Введите символы:\n");
    fflush (stdin);
    fgets(C1,100,stdin);
    fputs (C1,f1);
    printf ("Записано в файл \n");
    fclose (f1);
    delete [] C1;
    _getch();
}
}

    void vivod (char *C) 
{FILE *f1;
system("cls");
char *C1= new char [100];
f1=fopen("f1.txt","r");
if ((C!=0)&&(f1!=0))
{printf ("Содержимое текстового файла:\n");
fgets (C,100,f1);
puts(C);
fclose(f1);
delete [] C;
_getch();}}

void shifr ()
{
        FILE *f1;
    system("cls");
    fflush(stdin);
    char* str1=new char[100];
    char* str2=new char[100];
    f1=fopen("f1.txt","r+");
    while (!feof(f1))
    {int flag;
    int n=1;
    int j=0;
    fgets(str1,100,f1);
    for (int i=0; i<strlen(str1);i++)
    {if ((*(str1+i))>='А' && (*(str1+i))<'Я')
    {*(str2+j)=*(str1+i)+(n% RUS);}
    if (*(str1+i)>'Я')  *(str2+j)='А'+(*(str1+i))-'Я'-1;
    fprintf (f1, "c%", str2);
    flag=1;
    }
    for (int i=0; i<strlen(str1);i++)
    if (*(str1+i)>='а' && (*(str1+i))<'я')
        {
                (*(str2+j))=*(str1+i)+(n% RUS);
            if (*(str1+i)>'я') *(str2+j)='а' + ((*(str1+i))- 'я') - 1;
            {fprintf (f1, "%c", str2);
            flag = 1;
            }
 
        }
        if (!flag) fprintf (f1, "%c", str2);
        //str2 = getc(f1);
        printf_s ("zashifr stroka:\n");
            puts(str2);
        fputs(str2,f1);
        fclose(f1);
        delete str1;
        delete str2;
        _getch();}
    }

void deshifr()
{
        FILE *f1;
    system("cls");
    fflush(stdin);
    char* str2=new char[100];
    char* str3=new char[100];
    f1=fopen("f1.txt","r+t");
    while (!feof(f1))
    {
    int flag;
    int n=1;
    int j=0;
    fgets(str2,100,f1);
      for (int i=0; i<strlen(str2);i++)
if ((*(str2+i))>='А' && (*(str2+i))<='Я')
    {*(str3+j)=*(str2+i)-(n% RUS);}
  for (int i=0; i<strlen(str2);i++)
    if (*(str2+i)<'Я')  *(str3+j)='Я'-('А'-(*(str2+i))+1);
    fprintf (f1, "c%", str2);
    flag=1;
    
    for (int i=0; i<strlen(str2);i++)
    if (*(str2+i)>='а' && (*(str2+i))<='я')
        {
                (*(str3+j))=*(str2+i)-(n % RUS);
            if (*(str2+i)<'а') *(str3+j)='я' - ('а'-(*(str2+i))) +1;
            {fprintf (f1, "%c", str3);
            flag = 1;
            }
 
        }
        if (!flag) fprintf (f1, "%c", str2);
        //str2 = getc(f1);
        /*printf_s ("zashifr stroka:\n");*/
        fputs(str2,f1);
        fclose(f1);
        delete str2;
        delete str3;
        _getch();}
    }

Решение задачи: «Шифр Цезаря - ошибка в коде»

textual
Листинг программы
#include <stdio.h>
#include <ctype.h>
#include <string.h>
/* Константы для смещения и количество символов в алфавите */
#define VAL 3
#define ALF 26
/* Прототипы функций зашифровки и расшифровки */
void encrypt(char * str);
void decrypt(char * str);
/* Используется массив функций */
void (*select[])(char *str)={encrypt,decrypt};
int main(void)
{
    /* Переменные для выбора в меню и строковый массив */
    int mode;
    char src[255];
    puts("Welcome! Please select mode: 0-encypt, 1-decrypt, any key - exit");
    scanf("%d",&mode);
    while (mode>=0 && mode<2)
    {
        puts("Enter string:");
        /* В циклах иногда не успевает сработать запрос ввода с клавиатуры. Для нормализации
         * используется fflush(stdin) */
        fflush(stdin);
        gets(src);
        (*select[mode])(src);
        puts("---------------------------------------------------------");
        printf("%s%s\n","Result: ",src);
        puts("---------------------------------------------------------");
        puts("Please select mode: 0-encypt, 1-decrypt, any key - exit");
        scanf("%d",&mode);
    }
    system("PAUSE");
    return 0;
}
 
void encrypt(char *str)
{
    /* Собственно мой быдлокод-алгоритм шифровки. В цикле, до тех пор, пока не достигнут конец строки двигаемся
     * по строке. Если встречен пробел или другой знак, ничего не делаем. Иначе, если символ расположен менее чем
     * за (Z-3 буквы), то сдвигаем на три. В противном случае, вычитаем разницу между числом букв в алфавите и смещением)
     * Условный оператор ? сделан для различения заглавных и простых  букв. Если введена цифра проделываем тоже самое, за последнюю
     * цифру принимая 9 (9-3), за начальную 0(разница между количеством чисел (их всегда 10) и смещением).
     *  Аналогичный процесс происходит в расшифровке. */
    int i;
    for (i=0;str[i]!='\0';i++)
    {
        if (isalpha(str[i]))
        {
            if (str[i]<= (islower(str[i]) ? ('z'-VAL) : ('Z'-VAL)) ) str[i]+=VAL;
            else str[i]-=(ALF-VAL);
        }
        if (isdigit(str[i]))
        {
            if (str[i]<= ('9'-VAL)) str[i]+=VAL;
            else str[i]-=(10-VAL);
        }
    }
}
 
void decrypt(char *str)
{
    int i;
    for (i=0;str[i]!='\0';i++)
    {
    if (isalpha(str[i]))
        {
            if (str[i]>= (islower(str[i]) ? ('a'+VAL) : ('A'+VAL))) str[i]-=VAL;
            else str[i]+=(ALF-VAL);
        }
    if (isdigit(str[i]))
    {
        if (str[i]>=('0'+VAL)) str[i]-=VAL;
        else str[i]+=(10-VAL);
    }
    }
}

Объяснение кода листинга программы

  1. Программа использует шифр Цезаря для шифрования и расшифровки текстовых данных.
  2. Входные данные вводятся пользователем с клавиатуры, а затем выводятся на экран.
  3. Программа предлагает пользователю выбрать режим работы: шифрование, расшифровка или выход из программы.
  4. Для шифрования и расшифровки используется массив функций, который содержит адреса функций шифрования и расшифровки.
  5. В функции main() происходит основной цикл программы, который повторяется до тех пор, пока пользователь не введет неправильный номер режима или не отправит сигнал на выход из программы.
  6. В функции encrypt() происходит шифрование входной строки, а в функции decrypt() - расшифровка.
  7. Шифрование и расшифровка основаны на сдвиге символов в алфавите на фиксированное количество позиций.
  8. Если символ является буквой, то он сдвигается на три позиции вперед в шифровании и на три позиции назад в расшифровке.
  9. Если символ является цифрой, то он сдвигается на количество позиций, равное значению шифра Цезаря, вперед в шифровании и на количество позиций, равное разнице между количеством цифр и значением шифра Цезаря, в расшифровке.
  10. В обоих функциях используется цикл, который проходит по каждому символу входной строки.
  11. В обоих функциях используются условные операторы для обработки заглавных и строчных букв и цифр.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

11   голосов , оценка 3.364 из 5