Задача: Кодирование текстовых данных (файлов), побитовое кодирование

Тема в разделе "C/C++/C#", создана пользователем Again, 11 дек 2010.

Статус темы:
Закрыта.
  1. Again

    Again Гость

    Постановка задачи
    В этой задаче предполагается использование побитовых операций. Данные вводятся из файла на диске и выводятся в файл и на экран. Имена входного и выходного файлов задаются в командной строке.

    При выполнении этой задачи необходимо:
    1. При открытии или создании любых файлов необходимо проверять наличие ошибок ввода-вывода.
    2. Результат выполнения задания должен быть представлен в наглядной форме, например:

    Результат объединения значений
    65535 = 11111111 11111111
    1 = 00000000 00000001 операцией поразрядное И (&) равна
    1 = 00000000 00000001

    Условие задачи:
    Составить программу, кодирующую текстовый файл, путем перестановки первого и последнего битов в байте, 2-го и предпоследнего и т.д. Предусмотреть возможность декодирования. Для кодирования символа составить функцию.
     
  2. DarkKnight

    DarkKnight Well-Known Member
    C\C++ Team

    Регистрация:
    1 авг 2010
    Сообщения:
    653
    Симпатии:
    0
    Хочется увидишь ваши начинания (код, теорию по теме)...
    Примерно по факту именно в вашу тему смогу ответить не ранее (понедельник, вторник)...
     
  3. Again

    Again Гость

    Код (C++):
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    void kod( char *d, char *s )
    {
    int i;
    for ( i = 0; i < strlen( s ); i++ ) {
    d[i] = s[i] ^ 0x19;
    }
    }

    void main()
    {
    int i;
    char *d;
    char *s = "one two three four five six seven";

    d = (char *)malloc( strlen( s ) );
    kod( d, s );

    printf( "%s\n", s );
    for ( i = 0; i < strlen( s ); i++ ) {
    printf( "%c", d[i] );
    }
    printf( "\n" );
    }
    Это выполняеться в памяти, а мне нужно в файле...
     
  4. DarkKnight

    DarkKnight Well-Known Member
    C\C++ Team

    Регистрация:
    1 авг 2010
    Сообщения:
    653
    Симпатии:
    0
    Объясните пожалуйста что в это месте вы xor'ом делаете, но явно не
     
  5. DarkKnight

    DarkKnight Well-Known Member
    C\C++ Team

    Регистрация:
    1 авг 2010
    Сообщения:
    653
    Симпатии:
    0
    2Again : Кстати, Эгейн, а в задачи можно пользоваться и бинарными операциями и обычными??? Или только бинарными...
    Я что то прям задумался... Просто первое что на ум пришло это сравнение
    например наш символ char a;
    тогда
    итерация 1:
    множитель b = 2^7 = 128
    множитель c = 2^0 = 1;
    Код (C++):
    if (a&b == a&c ){;} //Если нули ничего не меняем
    else if (a&b > 0 && a&c>0) {;} //Если единицы опять же ничего не меняем
    else //Различны то тут же
    {
    a = a^b; //Ивертируем
    a = a^c;
    }
    так можно???? Или все же чисто-чисто бинарными операциями???
     
  6. Again

    Again Гость

    если можно, выложите пож-ста оба варианта.
     
  7. lazybiz

    lazybiz Well-Known Member
    C\C++ Team

    Регистрация:
    3 ноя 2010
    Сообщения:
    1.344
    Симпатии:
    0
    DarkKnight125
    Будь проще:facepalm:
    Код (C++):
        c ^= 0x81, c ^= 0x42, c ^= 0x24, c ^= 0x18;
    Собственно, реверс битов в байте.
     
  8. DarkKnight

    DarkKnight Well-Known Member
    C\C++ Team

    Регистрация:
    1 авг 2010
    Сообщения:
    653
    Симпатии:
    0
    Код (C++):
    #include <stdio.h>
    #include <conio.h>
    #include <locale.h>

    //Функция кодирования (ну и декодирования само собой), т.к. она обратимая
    unsigned char CodeAndDecode(unsigned char b)
    {
    //Т.к. в байте (8бит), то для замены нам нужно 4 итерации
    for (int i = 0; i<4; i++)
    {
    /* ЭТО Я ДЛЯ НАГЛЯДНОСТИ ОСТАВИЛ, ЧТО БЫ ПОНЯЛ КАК ИМЕННО ФОРМИРУЕТСЯ ИТОГОВОЕ УСЛОВИЕ
    //Если байты равны нулю
    if ( (b&(1<<(7-i))) == (b&(1<<i)) )
    {
    printf("Биты равны (0), итерация %i, биты %i и %i\n",i+1,i+1,8-i);
    }
    //Если байты равны единицы
    else if ( (b&(1<<(7-i))) > 0 && (b&(1<<i)) > 0)
    {
    printf("Биты равны (1), итерация %i, биты %i и %i\n",i+1,i+1,8-i);
    }
    //Иначе нужно менять местами (биты разные)
    else
    {
    //Если не то не другое инвертируем байты
    b = b^(1<<(7-i));
    b = b^(1<<i);

    }
    */

    //Тоже самое но короче
    if (!((b&(1<<(7-i))) == (b&(1<<i))) && !((b&(1<<(7-i))) > 0 && (b&(1<<i))>0))
    {
    b = b^(1<<(7-i));
    b = b^(1<<i);
    }
    }
    return b;
    }

    //Главная функция
    int main(int argc, char *argv[])
    {
    setlocale(LC_ALL,".1251");
    int i; //Для цикла... Я просто хз понимает ли C++ определение в цикле тип for (int i = 0....
    FILE *FileIn, *FileOut; //Файловые дескриптов

    //Я буду работать со статическими именами файлов, ты потом уже сам вытащишь из командой строки нужные имена и вставишь в код

    FileIn = fopen("InCode.txt","r+"); //Файл из которого получаем данные (обычные текстовые данные)
    if (!FileIn)
    {
    printf("Ошибка открытия файла для чтения данных");
    return 10;
    }

    FileOut = fopen("OutCode.txt","w+"); //Файл в который пишим кодированные данные
    if (!FileOut)
    {
    printf("Ошибка открытия файла для записи данных");
    return 11;
    }


    unsigned char buffer; //Буфер для 1 байта (я там ниже массив еще ввел, что бы вывод красивее был)
    printf("Кодирование текста : \n");
    //Пока не достигнут конец файла, читаем побайтно
    while (!feof(FileIn))
    {
    fread((void*)&buffer,sizeof(unsigned char),1,FileIn); //Читаем
    fprintf(FileOut,"%c",CodeAndDecode(buffer)); //Пишим в файл сразу (выходной файл)
    printf("%c - %c\n",buffer,CodeAndDecode(buffer)); //Выводим на экран ОРИГИНАЛ - КОДИРОВАНИЕ
    }
    fclose(FileIn); //Закроем текущие дескриптеры
    fclose(FileOut);
    //Откроем только что записанный файл...
    //для наглядности вывода создадим массив на 10000 (без динамики)
    unsigned char Arr[10000] = {0}; //Вот он, как раз все прочитаем в него и выведим строка к строке
    FileIn = fopen("OutCode.txt","r+"); //Откроем для чтения тот файл, в который только что записали кодир. текст
    if (!FileIn)
    {
    printf("Ошибка открытия файла для чтения данных");
    return 11;
    }
    int kol =0; //Кол-во прочитанных данных из файла
    while (!feof(FileIn))
    {
    kol = fread((void*)Arr,sizeof(unsigned char),10000,FileIn); //Прочитаем все в массив
    }
    printf("\nКодированный текст: \n");
    for (int i = 0; i<kol; i++)
    printf("%c",Arr[i]);
    printf("\nДекодированный текст: \n");
    for (int i = 0; i<kol; i++)
    printf("%c",CodeAndDecode(Arr[i]));
    return 0;
    }
     

    Вложения:

    • InCode.txt
      Размер файла:
      121 байт
      Просмотров:
      15
    • OutCode.txt
      Размер файла:
      121 байт
      Просмотров:
      11
    • code1.jpg
      code1.jpg
      Размер файла:
      43,9 КБ
      Просмотров:
      69
    • code2.jpg
      code2.jpg
      Размер файла:
      71,6 КБ
      Просмотров:
      69
  9. DarkKnight

    DarkKnight Well-Known Member
    C\C++ Team

    Регистрация:
    1 авг 2010
    Сообщения:
    653
    Симпатии:
    0
    Не, насчет реверса не согласен, простая инверсия... (было 255 стало 0)
    Проверка все равно нужна.. Мы же инвертировать будем только то, где различия есть 0-1 или 1-0....
    но выглядит красивее чем мои 1<<7; ;-)
     
  10. lazybiz

    lazybiz Well-Known Member
    C\C++ Team

    Регистрация:
    3 ноя 2010
    Сообщения:
    1.344
    Симпатии:
    0
    DarkKnight125
    Погоди.. Я по-моему там что-то упустил... Мне необходимо подумать.

    Добавлено: Но ты, по-моему, все-равно немного усложнил... Сейчас подумаю.
     
  11. lazybiz

    lazybiz Well-Known Member
    C\C++ Team

    Регистрация:
    3 ноя 2010
    Сообщения:
    1.344
    Симпатии:
    0
    DarkKnight125
    А так не проще:welcome:
    Код (C++):
    char reverse( char c )
    {
    int i;
    char    v = 0;
    for ( i = 0; i < 8; i++ ) {
    v |= ((c >> i) & 1) << (7 - i);
    }
    return v;
    }
     
  12. lazybiz

    lazybiz Well-Known Member
    C\C++ Team

    Регистрация:
    3 ноя 2010
    Сообщения:
    1.344
    Симпатии:
    0
    Проще некуда.
    reverse - операция обратимая, т.ч. она и кодирует, и раскодирует.
    Код (C++):
    #include <stdio.h>

    char reverse( char c )
    {
    int     i;
    char    v = 0;
    for ( i = 0; i < 8; i++ ) {
    v |= ((c >> i) & 1) << (7 - i);
    }
    return v;
    }

    void main( int narg, char **arg )
    {
    int     i, n;
    FILE *  fp_in;
    FILE *  fp_out;

    if ( narg != 3 ) {
    printf( "main.exe in_file out_file\n" );
    return;
    }

    fp_in = fopen( arg[1], "rb" );
    fp_out = fopen( arg[2], "wb+" );

    fseek( fp_in, 0, SEEK_END );
    n = ftell( fp_in );
    fseek( fp_in, 0, SEEK_SET );

    for ( i = 0; i < n; i++ ) {
    fputc( reverse( fgetc( fp_in ) ), fp_out );
    }

    fclose( fp_out );
    fclose( fp_in );
    }
     
  13. lazybiz

    lazybiz Well-Known Member
    C\C++ Team

    Регистрация:
    3 ноя 2010
    Сообщения:
    1.344
    Симпатии:
    0
    Чуть попроще:
    Код (C++):
    #include <stdio.h>

    char reverse( char c )
    {
    int     i;
    char    v = 0;
    for ( i = 0; i < 8; i++ ) {
    v |= ((c >> i) & 1) << (7 - i);
    }
    return v;
    }

    void main( int narg, char **arg )
    {
    int     c;
    FILE *  fp_in;
    FILE *  fp_out;

    if ( narg != 3 ) {
    printf( "main.exe in_file out_file\n" );
    return;
    }

    fp_in = fopen( arg[1], "rb" );
    fp_out = fopen( arg[2], "wb+" );

    while ( (c = fgetc( fp_in )) != EOF ) {
    fputc( reverse( c ), fp_out );
    }

    fclose( fp_out );
    fclose( fp_in );
    }
     
Загрузка...
Похожие Темы - Задача Кодирование текстовых
  1. Янчик
    Ответов:
    0
    Просмотров:
    486
  2. TrishaRay
    Ответов:
    1
    Просмотров:
    782
  3. elzim
    Ответов:
    0
    Просмотров:
    931
  4. ShaoKahn
    Ответов:
    1
    Просмотров:
    1.125
  5. eremin-sanek
    Ответов:
    3
    Просмотров:
    1.107
Статус темы:
Закрыта.

Поделиться этой страницей