Найти в файле адрес начала заданной последовательности - C (СИ)

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

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

Имеем абсолютный адрес файла, объявлен массив байт - последовательность, которую нужно найти внутри этого файла. Вывести начальный адрес и несколько байт от этого адреса. Как я понимаю, сначала нужно открыть файл для чтения, потом условие для сравнения. Если не равно, значит переход на следующий адрес. Если весь массив совпал, то вывод на консоль результатов, закрыть файл. (или сначала файл в массив чуть большего размера вывести, и потом искать между двумя массивами?)
Пока тренируюсь читать. Код читает и печатает 10 сиволов в хекс виде. Правильно пока что?
#include <stdio.h>
#include <stdlib.h>
 
int main()
{
    char sequence[12]= {0,  1,  0,  0,  0, 17,  1,  0,  0,  4,  0, 16};
    int i, n;
    unsigned char A[50];
    FILE *fp;
    fp = fopen("C:\\Program Files\\xxx\\yyy\\zzz.exe", "r+" );
     //чтения  из  двоичного функция fread,
    n=fread (A,sizeof(char), 50, fp); // читаем 50 штук
    fclose ( fp );
 
    for (i=1;i<=10 ;i++ ){
        printf("i=%8x char=%2x\n",i,A[i-1]);
    }
    fclose ( fp );
    return 0;
}

Решение задачи: «Найти в файле адрес начала заданной последовательности»

textual
Листинг программы
#include <windows.h>
#include <shlobj.h>  //Диалог выбора файла
#include <stdio.h>   //i/o
#include <conio.h>   //getch
 
char * SelFile(HWND hWnd);
bool   IsFile(LPCTSTR sPath);
long   FindStr(LPCTSTR sPath, LPCTSTR sFind);
void   ShowBytes(LPCTSTR s, unsigned int nBytes);
 
int main()
{
    char ch;
    char szFilePath[256];
    char szFindText[256];
    HWND hWnd = GetForegroundWindow();//Находим дескриптор окна консоли
    do
    {
        if(!strcpy(szFilePath,SelFile(hWnd)))
            printf("File not selected\r\n");
        else
        {
            if(IsFile(szFilePath))
            {
                printf("File is selected\r\n");
                printf("Enter string to find\r\n");
                //Текст может быть с пробелами
                scanf("%[^\n]%c",szFindText,&ch);
                if(FindStr(szFilePath, szFindText) < 1)
                    printf("Search nothing\r\n");
            }
        }
        printf("Y - Repeat search\r\n");
        ch = getch();
    }
    while(ch == 'Y' || ch == 'y');
    return 0;
}
 
char * SelFile(HWND hWnd)
{
    ShowWindow(hWnd,SW_HIDE);
    char sPath[MAX_PATH];sPath[0] = '\0';
    LPCITEMIDLIST lpItemDList;
    BROWSEINFO bi = {NULL, NULL, sPath,
       "Выберите файл или каталог",
        BIF_DONTGOBELOWDOMAIN|BIF_BROWSEINCLUDEFILES,
        NULL,
        NULL,
        0
    };
    if((lpItemDList = SHBrowseForFolder(&bi)))
    {
        if(SHGetPathFromIDList(lpItemDList, sPath))
            GetShortPathName((LPCTSTR)sPath,sPath,strlen(sPath));
    }
    ShowWindow(hWnd,SW_SHOW);
    return &sPath[0];
}
 
bool IsFile(LPCTSTR sPath)
{
    bool bFile = false;
    FILE * f = fopen(sPath,"rb+");
    if(f)
    {
        bFile = true;
        fclose(f);
    }
    return bFile;
}
 
long   FindStr(LPCTSTR sPath, LPCTSTR sFind)
{
    char * str,*buf;
    long nCount = 0;//Число найденных вхождений sFind
    long fLen = 0;
    FILE * f = fopen(sPath,"rb+");
    if(f)
    {
        fseek(f,0,SEEK_END);//Курсор вконец файла
        fLen = ftell(f);//fLen = длинне файла
        fseek(f,0,SEEK_SET);//Курсор вначало файла
        if(str = (char *)malloc(fLen + 1))//Память сразу под весь текст в файле + '\0'
        {
            fread(str,fLen,1,f);
            str[fLen] = '\0';
            buf = strstr(str,sFind);
            while(buf)
            {
                printf("Found pos : %d ",fLen - strlen(buf));
                ShowBytes((LPCTSTR)buf,8);//Показываем первых 8 найденных байт
                buf = strstr(buf + 1,sFind);
                nCount++;
            }
            free((void *)str);
        }
        fclose(f);
    }
    return nCount;
}
 
void   ShowBytes(LPCTSTR s, unsigned int nBytes)
{
    char * str = (char *)malloc(nBytes + 1);
    if(strlen(s) <= nBytes)
        strcpy(str,s);
    else
        strncpy(str,s,nBytes);
    str[nBytes] = '\0';
    printf(" %d Bytes : %s\r\n",nBytes,str);
    free((void *)str);
}

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


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

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

7   голосов , оценка 4 из 5
Похожие ответы