Форум программистов, компьютерный форум CyberForum.ru

Как побайтно считать информацию из исполняемого файла - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 15, средняя оценка - 4.87
bychevoz
1 / 1 / 0
Регистрация: 16.11.2012
Сообщений: 27
21.11.2012, 01:39     Как побайтно считать информацию из исполняемого файла #1
вы не смотрите на убогий код, который не юзает стринг, потому что я тогда еще не знал про стринг

итак, мое задание - считать бинарник и подсчитать частоты каждого байта

например:

текст в бинарнике: " " (то есть два пробельчика)
соответственно прога воспринимает это так
00100000 00100000
и выводит:
00100000 - 2 раза
01000000 - 1 раз
10000000 - 1 раз
00000001 - 1 раз
и т.д.

проблема - не хочет читать файл explorer.exe
с доступом все ок.

самое главное: в режиме отладки - ждет секунд десять и выводит результаты (довольно таки объемные)
т.е. главный вопрос: почему в режиме отладки все ок, а при независимом запуске - неок?

код программы:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <iostream>
#include <fstream>
using namespace std;
 
unsigned char  getbyte (int); // Прочитать байт начиная с i-го бита
char* ToBin   (int); // Вернуть строку нулей и единиц, соответствующую двоичному отображению параметра
ifstream in;
 
int main()
{
    cout<<"Enter name of input file: ";
    char* name=new char[1];
    cin>>name;
    in.open(name, ios::in     | // считывание
                  ios::binary | // бинарного файла
                  ios::ate   ); // открыть в конце
    if (!in.is_open())
    {
        cout<<"Error";
        cin.get();
        return -1;
    }
 
    int bytes[256]; // Будет хранить частоты каждого байта. Например, n[5] - частота байта 0000010
    for (int i=0; i<256; i++) bytes[i]=0;
    
    in.seekg(0,ios::end);
    long size=in.tellg(); //Узнали размер
 
    cout<<endl<<"File: "<<endl<<endl; // Вывели файл в виде единиц и нулей
    for (int i=0; i<size; i++)
    {
        for (int j=0; j<8; j++) 
            cout<<ToBin((int)getbyte(i*8))[j];
        cout<<' ';
    }
 
    for (int i=0; i<=size*8-8; i++) // посчитали
            bytes[getbyte(i)]++; 
    cout<<endl<<endl;
 
    for (int i=0; i<256; i++) //вывели результат
    {
        if (bytes[i]!=0)
        {
            cout<<"Byte ";
            for (int j=0; j<8; j++) cout<<ToBin(i)[j];
            cout<<" met "<<bytes[i]<<" times in this file"<<endl;
        }
    }
    cout<<endl;
    //нашли и вывели самый часто встречающийся байт
    int max=0;
    for (int i=1; i<256; i++) if (bytes[i]>bytes[max]) max=i; 
    cout<<"The most often byte is ";
    for (int j=0; j<8; j++) cout<<ToBin(max)[j];
    cout<<" - "<<bytes[max]<<" times";
    cin.get();
    cin.get();
}
 
char* ToBin(int n)
{
    char* ret=new char[8];
    for (int i=7; i>=0; i--)
        ret[7-i]=48+(n>>i)%2; //Будет присвоено 48 или 49 что соответствует коду нуля и единицы
    return ret;
}   
 
unsigned char getbyte(int pos)
{
    in.seekg(pos/8);                     // переместиться чтоб считать тот байт, где содержится запрашиваемый бит
    char c;
    in.get(c);                           // читаем
    if (pos%8==0) return c;              // возвращаем сразу считанное, если считываем с начала байта
    char c1;                
    in.get(c1);                          // иначе считываем следующий за ним байт
    return (c<<(pos%8))+(c1>>(8-(pos%8))); 
}   
 
    /* например, надо считать 10101010 10110100 11111111 начиная с 11 позиции
    с  = 10110100
    c1 = 11111111
    c  << (pos%8)   = 10110100  << 3 = 10100000
    c1 >> (8-pos%8) = 11111111  >> 5 = 00000111
 
    c + c1 = 10100000
           + 00000111
           = 10100111
Добавлено через 15 минут
если кто желает запустить на своем компе: уберите часть кода, где выводится содержимое файла, думаю понимаете почему)

Добавлено через 1 час 45 минут
отзовитесь пожалуйста ! у меня голова кругом
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.11.2012, 01:39     Как побайтно считать информацию из исполняемого файла
Посмотрите здесь:

Как считать информацию из файла, если в конце стоит пробел? C++
C++ Подскажите как побайтно считать файл
getline() (не получается считать информацию с файла) C++
Как считать информацию с файла C++
C++ Как побайтно считать бинарник?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
I.M.
 Аватар для I.M.
564 / 547 / 5
Регистрация: 16.12.2011
Сообщений: 1,389
21.11.2012, 02:12     Как побайтно считать информацию из исполняемого файла #2
bychevoz, а сам експлорер у вас где лежит? вы точно к нему верный путь задаете?
bychevoz
1 / 1 / 0
Регистрация: 16.11.2012
Сообщений: 27
21.11.2012, 06:02  [ТС]     Как побайтно считать информацию из исполняемого файла #3
да все верно, пока я ждал ответа, я написал более аккуратный работающий и оптимизированный код (оптимизировал функцию ToBin)

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <fstream>
#include <iostream>
#include <exception>
#include <string>
using namespace std;
 
bool           FileCreate(ifstream& in);
unsigned char  getbyte   (int pos, ifstream& in); 
string         ToBin     (unsigned char byte); 
 
void main()
{
    ifstream in;
    FileCreate(in);
    long long size=in.tellg();
    in.seekg(0);
    long long bytes[256]={0};
    for (int i=0; i<=size*8-8; i++)
        bytes[getbyte(i, in)]++;
    cout<<endl<<endl;
    unsigned char max=0;
    for (int i=0; i<256; i++)
        if (bytes[i]!=0)
        {
            if (bytes[i]>bytes[max]) max=i;
            cout<<"Byte "<<ToBin(i)<<" met "<<bytes[i]<<" times in this file\n";
        }
    cout<<"\nThe most often byte is "<<ToBin(max)<<" - "<<bytes[max]<<" times";
    cin.get();
}
 
bool FileCreate(ifstream& in)
{
    cout<<"Enter input filename: ";
    string iname;
    getline(cin,iname);
    try
    {
        in.open(iname,ios::in|ios::binary|ios::ate);
        if (!in) throw exception("Cannot open input file");
    }
    catch(exception& ex)
    {
        in.close();
        cout<<ex.what();
        cin.get();
        system("cls");
        return FileCreate(in);
    }
    return true;
}
 
string ToBin(unsigned char byte)
{
    string ret;
    for (int i=0; i<8; i++) 
        ret+=(byte<<i)&128?'1':'0';
    return ret;
}   
 
unsigned char getbyte(int pos, ifstream& in)
{
    in.seekg(pos/8);                     
    char c;
    in.get(c);                           
    if (pos%8==0) return c;              
    char c1;                
    in.get(c1);                          
    return (c<<(pos%8))+(c1>>(8-(pos%8))); 
}
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
21.11.2012, 10:57     Как побайтно считать информацию из исполняемого файла #4
По первому коду. Открываете файл, курсор в конце. Потом делаете:
C++
1
in.seekg(0, ios::end);
Передвигаете с конца в конец?
И вот это:
C++
1
2
char* name=new char[1];
cin>>name;
Имя файла из одного символа?
Впрочем, во втором коде это всё исправлено.
bychevoz
1 / 1 / 0
Регистрация: 16.11.2012
Сообщений: 27
21.11.2012, 11:30  [ТС]     Как побайтно считать информацию из исполняемого файла #5
Цитата Сообщение от alsav22 Посмотреть сообщение
По первому коду. Открываете файл, курсор в конце. Потом делаете:
этот кусок был написан чтоб узнать размер я потом приписал ios::ate и забыл убрать это. все компилируется и работает из дебага, а автономно нет

вот и вопрос почему



Цитата Сообщение от alsav22 Посмотреть сообщение
Имя файла из одного символа?
ничего страшного, просто ругался на неинициализированную переменную. указатель неконстантный так что все ок
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
21.11.2012, 12:00     Как побайтно считать информацию из исполняемого файла #6
Цитата Сообщение от bychevoz Посмотреть сообщение
ничего страшного, просто ругался на неинициализированную переменную. указатель неконстантный так что все ок
Это не ок, даже если и работает. Размер выделенной память не нужно делать меньше того, что туда будет помещаться.
Код и сейчас автономно не работает? А что пишет при этом? Если в релиз откомпилировать?

Добавлено через 3 минуты
Ввод конкретного имени файла (explorer.exe) как выглядит? ОС какая?

Добавлено через 1 минуту
И на каком-нибудь другом файле попробуйте (на своём).

Добавлено через 13 минут
У меня работает и автономно. Но у меня ХР.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.11.2012, 00:28     Как побайтно считать информацию из исполняемого файла
Еще ссылки по теме:

Как считать информацию с текстового файла? C++
C++ Не получается считать из файла информацию
Считать информацию из с файла массив посимвольно C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
bychevoz
1 / 1 / 0
Регистрация: 16.11.2012
Сообщений: 27
22.11.2012, 00:28  [ТС]     Как побайтно считать информацию из исполняемого файла #7
второй вариант у меня на ХР тоже работает, а вот первый только в дебаге. релиз пробовал - нет
свои файлв первая программа обрабатывает. мне уже все равно, второе решение красивое и оптимизированное

Добавлено через 35 секунд
ах да, первая программа обрабатывает explorer только если он с ней в одной папке. саму себя первый вариант тоже читает.
Yandex
Объявления
22.11.2012, 00:28     Как побайтно считать информацию из исполняемого файла
Ответ Создать тему
Опции темы

Текущее время: 19:18. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru