Шифр Цезаря - ошибка в коде - 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); } } }
Объяснение кода листинга программы
- Программа использует шифр Цезаря для шифрования и расшифровки текстовых данных.
- Входные данные вводятся пользователем с клавиатуры, а затем выводятся на экран.
- Программа предлагает пользователю выбрать режим работы: шифрование, расшифровка или выход из программы.
- Для шифрования и расшифровки используется массив функций, который содержит адреса функций шифрования и расшифровки.
- В функции main() происходит основной цикл программы, который повторяется до тех пор, пока пользователь не введет неправильный номер режима или не отправит сигнал на выход из программы.
- В функции encrypt() происходит шифрование входной строки, а в функции decrypt() - расшифровка.
- Шифрование и расшифровка основаны на сдвиге символов в алфавите на фиксированное количество позиций.
- Если символ является буквой, то он сдвигается на три позиции вперед в шифровании и на три позиции назад в расшифровке.
- Если символ является цифрой, то он сдвигается на количество позиций, равное значению шифра Цезаря, вперед в шифровании и на количество позиций, равное разнице между количеством цифр и значением шифра Цезаря, в расшифровке.
- В обоих функциях используется цикл, который проходит по каждому символу входной строки.
- В обоих функциях используются условные операторы для обработки заглавных и строчных букв и цифр.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д