Quantcast
Viewing all articles
Browse latest Browse all 517272

Разобраться в коде программы - С++ для начинающих

помогите пожалуйста разобраться на примере этого текста подробно
gil bil pes
Код:

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <iostream>
#define max 10000//количество слов
#define len 25//максимальная длина слова
using namespace std;


FILE *PF;//файл данных
char nch='\n';//читаемый символ
int nst=0;//номер строки
//для хранения слов
char stec[max][len]; //слова
char rez[max][len*8];//двоичный код
int top=0;//вершина стека


void get();//для считывания файла и его шифрования
void world();//процедура для чтения слов

void Shifr();//шифруем
void Deshifr();//дешифруем
char* Bit(char x);//возвращает двоичный код символа
int Sim(char binary[8]);//преобразует 8 бит кода символа в  10 код символа


void main(int ac,char* av[])
{
        setlocale(LC_ALL, "Russian");//подключение русского языка
        //проверка задан ли файл для работы
        if (ac==1) //если не задан(количество аргументов 1-имя программы)
                printf("Файл для шифрования\дешифрования не задан\n");
        else //если задан
        {
        PF=fopen(av[1],"rt");//открыть файл
        //проверка открытия файла для работы
        if (PF==0) //если файл не открыт
                {
                        printf("Файл не открыт\n");
                }
        else //если файл открыт
                {
                        char ch='\n';//обнудение переменной
                        //выбор действия
                        while (ch!='1' && ch!='2')
                        {
                                printf("1.Шифровать файл\n");
                                printf("2.Дешифровать файл\n");
                                ch=getch();
                                cout<<ch<<endl;
                        }
                        //обработка действия
                        if (ch=='1')
                        {
                                get();//считаем данные
                                fclose(PF);        //закроем фал
                                Shifr();//зашифруем данные
                               
                                //вывод результата шифрования
                                PF=fopen("Shifr.dan","wt");
                                for(int i=top-1;i>=0;i--)
                                        fprintf(PF,"%s ",rez[i]);
                                fclose(PF);       
                        }
                        else
                        {
                                Deshifr();//дешифруем данные
                                fclose(PF);
                               
                                //вывод результата дешифрования
                                PF=fopen("Deshifr.dan","wt");
                                for(int i=top-1;i>=0;i--)
                                        fprintf(PF,"%s ",stec[i]);
                                fclose(PF);       
                        }

                }
        }
  system("pause");
}



//для считывания файла перед шифрованием
void get()
{
nch=getc(PF);
while(nch!=EOF)
{
while(isspace(nch)) //если пробельный символ
//while(nch==' '|| nch=='\n' || nch=='\t')
        {
                if(nch=='\n')
                {
                        nst++;
                        break;
                }
        nch=getc(PF);
        }

if (isalpha(nch) || isdigit(nch)|| nch=='.' || nch=='!' || nch=='?' || nch=='-' || nch==',' ) //если число или буква или знак
//if((nch>47 && nch<58) || (nch>96 && nch<123) || (nch>'А' && nch<'Я')|| (nch>'а' && nch<'я')|| nch=='.' || nch=='!' || nch=='?' || nch=='-' || nch==',' ) //если число или буква или знак
                world();       
                else
                {
                        printf("Недопустимый символ в строке %i\n",nst+1);
                        nch=getc(PF);
                }
}
return;
}


//процедура разделения на слова
void world()
{
        char tx[40];
        int i;
    char *p;
        p=tx;//запоминаем указатель на строку
        while (isalpha(nch) || isdigit(nch)|| nch=='.' || nch=='!' || nch=='?' || nch=='-' || nch==',' ) //если число или буква или знак
        //while ((nch>47 && nch<58) || (nch>96 && nch<123) || (nch>'А' && nch<'Я')|| (nch>'а' && nch<'я')|| nch=='.' || nch=='!' || nch=='?' || nch=='-' || nch==',' )//пока символ или разделитель - читаем
        {
                *(p++)=nch;//заносим данные в строку
                nch=getc(PF);//читаем следующий символ
        }
        *p='\0';//заносим признак окончания строки
        strcpy(stec[top],tx);//копируем результат в стек данных
        top++;//увеличиваем счетчик
}

//процедура шифрования
void Shifr()
{
//перевод символов в бинарный код
for(int i=top-1;i>=0;i--)
{
        //printf("%s\n",stec[i]);//проверка начального слово(исползовалась при отладке)
        for (int j=0; j<strlen(stec[i]); j++)
        {
                if (j==0)//если разбираем первый символ
                        strcpy(rez[i],Bit(stec[i][j]));//скопируем двоичный код в строку
                else//если последующие символы
                        strcat(rez[i],Bit(stec[i][j]));//добавим код к строке
                //printf(" - %c - %i\n",stec[i][j],stec[i][j]);//проверочный вывод символа и десятичного кода(использовалось при отладке)

        }
        //printf("%s\n",rez[i]);//выведем бинарный код(использовалось при отладке)
}
//временнный вывод для проверки результата
/*FILE *PF1=fopen("Temp.dan","wt");
for(int i=top-1;i>=0;i--)
        fprintf(PF1,"%s ",rez[i]);
fclose(PF1);        */

//определение значимого бита
        char ch;
        ch='\n';
        while(!isdigit(ch) || (int)(ch-'0')>7)
        {
                printf("Введите № символ для шифрования 0-7\n");
                ch=getch();
                cout<<ch<<endl;
        }
//кодирование
//берем двоичный код симовлов
for(int i=top-1;i>=0;i--)
{
//cout<<rez[i]<<endl;
  for(int j=0; j<strlen(rez[i]); j++)
{
        char simvol =96 + rand()%27;//случайный символ английского алфавита
        //char simvol = 'a';//символ 'а'
        //проверочный вывод до замены бита(для отладки)
        //cout<<j<<")"<<rez[i][j]<<endl<<simvol<<endl<<Bit(simvol)<<endl;
        if (rez[i][j]=='0')
        {
                switch (ch)//Оператор & обычно применяют, чтобы обнулить один или несколько битов.
                {
                case '0' : simvol = simvol&(~(1<<0)); break;
                case '1' : simvol = simvol&(~(1<<1)); break;
                case '2' : simvol = simvol&(~(1<<2)); break;
                case '3' : simvol = simvol&(~(1<<3)); break;
                case '4' : simvol = simvol&(~(1<<4)); break;
                case '5' : simvol = simvol&(~(1<<5)); break;break;
                case '6' : simvol = simvol&(~(1<<6)); break;
                case '7' : simvol = simvol&(~(1<<7)); break;
                }
        }
        else
        {
                switch (ch)//Оператор | обычно используют для установки заданных битов переменной в единицу.
                {
                case '0' : simvol = simvol|(1<<0); break;
                case '1' : simvol = simvol|(1<<1); break;
                case '2' : simvol = simvol|(1<<2); break;
                case '3' : simvol = simvol|(1<<3); break;
                case '4' : simvol = simvol|(1<<4); break;
                case '5' : simvol = simvol|(1<<5); break;
                case '6' : simvol = simvol|(1<<6); break;
                case '7' : simvol = simvol|(1<<7); break;
                }
        }
//проверочный вывод после замены бита(для отладки)
//cout<<j<<")"<<endl<<simvol<<endl<<Bit(simvol)<<endl;
        rez[i][j]=simvol;//замена символа в результате
}
//cout<<rez[i]<<endl;//проверочный вывод результата
}

}

void Deshifr()
{
//определение значимого бита
        char ch;
        ch='\n';
        while(!isdigit(ch) || (int)(ch-'0')>7)
        {
                printf("Введите № символ для дешифрования 0-7\n");
                ch=getch();
                cout<<ch<<endl;
        }
//чтение файла
nch=getc(PF);
int i=0;
int j=0;
while(nch!=EOF)
{
if(nch==' ')//т.к. слова разделены пробелами
{
        nch=getc(PF);
        i++;
        j=0;
}
else
{
        char temp[20];
        strcpy(temp, Bit(nch));//получим его бинарный код
        rez[i][j] = temp[7-(int)(ch-'0')];//извлекаем нужный бит
        j++;
        nch=getc(PF);//считаем символ
}
}

top=i;
//проверочный вывод для отладки
/*for(i=top-1;i>=0;i--)
        cout<<rez[i]<<"\n";*/

for (i=0; i<top; i++)
//for(i=top-1;i>=0;i--)
        for(j=0; j<strlen(rez[i])/8; j++)
        {
                char t[8];
                for(int a=0; a<8; a++)
                        t[a]=rez[i][j*8+a];
                //cout<<Sim(t)<<" - "<<(char)Sim(t)<<endl;//проверочный вывод для отладки
                stec[i][j]=(char)Sim(t);//сохранение результата
        }
}

char* Bit(char x)
{
char tx[20];
for (int i=sizeof(x)*8-1; i>=0; --i)
{
        tx[sizeof(x)*8-1-i]=((x>>i)&1)+'0';
  //cout<<(int)((x>>i)&1);был проверочный код
}
tx[sizeof(x)*8]='\0';//символ конца строки
//cout<<endl<<tx;//проверочный вывод на экран
return tx;
}

//преобразует 8 бит кода в  10 код числа
int Sim(char binary[8])
{
  int number = 0;
  int mult = 1;
  for(int i = 7; i>=0; i--, mult *= 2) 
    {
                if(binary[i] == '1') number += mult;
    }
    //cout << number << endl;//проверочный вывод
        return number;
}


Viewing all articles
Browse latest Browse all 517272

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>