LINUX.ORG.RU

Найти последовательность символов в файле


0

2

Возник вопрос следующего порядка:

Имеется бинарный файл, необходимо найти определенную последовательность чисел из 6 символов и если она присутствует в файле, читать символы за этой последовательностью до тех пор пока не встретится определенный символ (например 0х0C). Никак не придумаю, как реализовать это на С...

Ответ на: комментарий от anonymous

Как искать подстроки я знаю, вопрос в том как читать это из бинарного файла. Не считывать же многомегабайтный файл в буфер. Операций кроме считывания по 1 символу через getc() в голову не приходит...

Lorchanko
() автор топика
Ответ на: комментарий от AITap

Да, и повнимательнее с границами буфера!

anonymous
()

Если ты не можешь решить эту задачу никаким, даже самым неэффективным способом, то я могу лишь посоветовать тебе бросить программирование и продолжить любить матан.

pathfinder ★★★★
()
Ответ на: комментарий от Lorchanko

Алгоритмы Рабина-Карпа и КМП, например, не требуют считывания всей строки заранее.

anonymous
()
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <memory.h>
#include <sys/mman.h>
#include <fcntl.h>

static const char search_template[6] = { ... };
const char limit = 0x0C;

size_t find(const char *file_name, void *buf, size_t maxlen) {
        int fd;
        off_t size;
        void *p, *s;

        fd = open(file_name, O_RDONLY);
        /* TODO: check C<fd> and C<errno> */
        size = lseek(fd, 0, SEEK_END);
        /* TODO: check C<size> & C<errno> */
        lseek(fd, 0, SEEK_SET);
        /* TODO: check return value and C<errno> */
        p = mmap(NULL, (size_t)size, PROT_READ, MAP_PRIVATE, fd, 0);
        /* TODO: check C<p> against C<MAP_FAILED> and C<errno> */
        s = memmem(p, (size_t)size, search_template, sizeof(search_template));
        if (s != NULL) {
                void *e = memchr(s + sizeof(search_template), limit, (size_t)size - ((char *)s - (char *)p) - sizeof(search_template));
                if (e != NULL) {
                        if (maxlen > (char *)e - (char *)s)
                                maxlen = (char *)e - (char *)s;
                        read(fd, r, maxlen);
                        /* TODO: check return value and C<errno> */
                        return maxlen;
                }
        }
        return 0;
}
arsi ★★★★★
()
Ответ на: комментарий от pathfinder

> А где объявлена r? И какая позиция будет в файле в момент чтения?

/* oops! >_<" */

memcpy(buf, s, maxlen);

/* thanks… */

// ps: btw, don't forget to close the file b4 return… T_T

arsi ★★★★★
()

Вопрос решен

Все-таки написал алгоритм, громоздкий, но вроде работает... С вопросом я поспешил. Всем спасибо.

Lorchanko
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.