Как при чтении в файле, при необходимости, реализовать быстрый переход на начало новой строки?

Актуальность вопроса объясняется тем, что читаемая БД создавалась на мониторе и по-строчно. Функции, имеющиеся в арсенале С и С++ чтения в файле, не рассчитаны для этого случая(по-необходимости, быстрый переход на начало новой строки) или ещё не известны мне, как и, возможно, макросы, если таковые есть. Фактически, здесь необходимо реализовать функцию/макрос, аналогичную управляющему символу '\n' (переход на начало новой строки), используемому для вывода на монитор и принтер.


Ответы (2 шт):

Автор решения: MBo

Ну что ж, попробуем так...

Если размер файла позволяет держать его целиком в памяти, то читаете его один раз в вектор строк.

Если файл слишком большой и не изменяется:
Прочитайте файл целиком один раз, составьте массив/вектор B[] индексов начал строк.

"Мама
 мыла
 раму" 
B: [0, 6, 12, 18]  
(для однобайтовой кодировки, с учётом переносов строк CRLF)

Затем при обращении к i-й строке прочитайте часть файла от байта B[i] до B[i+1]-1

→ Ссылка
Автор решения: InterceptorTSK

В общем смысле - эта проблема нерешаема, в случае если строки - переменной длины. Никто и ни что не может рассчитать в таких данных начало n-ой строки; даже кол-во строк рассчитать нельзя [но предсказать - можно]. Но задачу поиска начала конкретной n-ой строки - решить невозможно, нужен полный проход по всему файлу.

Однако же посмотрите на то, а вдруг ваша [не ваша] бд - выровнена? Это значит - каждая строка бд имеет фиксированный размер [в байтах]; если это так - тогда доступ к началу каждой строки прост:

p - начало n-ой строки
len - длина строки [в байтах] (исключая \r\n ?)
p = n * len + len(\r\n ?)

При этом, если бд - статическая [неизменяемая по времени/крайне редко изменяемая по времени/программно - неизменяемая по времени], то есть следующий смысл:

  1. Выровняйте строки бд, и вышеизложенным способом вы найдёте начала нужных строк.

  2. Если вы не хотите выравнивать строки, тогда соберите файл-индекс к этому файлу-бд и в виде файла положите рядом с файлом-бд. Т.е. в файле-индексе вы будете хранить список на начала каждой строки. Т.е. файл-индекс - это набор упорядоченных смещений на каждую строку, относительно начала файла, @MBo привёл пример, смотрите его пример.

  3. Если вы добавляете в/удаляете из/изменяете в базе [надо полагать ручками] какие то данные, то эти данные нужно переиндексировать, т.е. пересоздать файл-индекс, где будут новые пересчитанные начала на строки. Т.е. для этого нужна маленькая микро-программка, которая запускается отдельно, вы внесли изменения в базу - переиндексируйте базу этой микро-программкой. Положите её рядом с файлом базы/файлом индексов.

  4. Предсказать кол-во строк, и соответственно среднюю длину строки - можно, но это работает на более менее больших данных. И в вашем случае это ничего не даёт. Потому что вам не предсказания нужны, а конкретное число начала n-ой строки.

  5. В случае если строки бд выровнены - смысл в разделителях отсутствует полностью. Однако же он нужен только с одной целью - что бы просматривать и редактировать бд любыми доступными способами через те самые "блокнотики".

  6. Выравнивание бд работает строго байтами, а не чарами. Что такое чар - не известно. Вы можете видеть в блокнотике строку как набор чаров, но вы никогда не сможете сказать сколько байт в этой строке.

  7. Учитывайте кодировку. Понятое дело тут utf-8 не подойдёт, но и с utf-16le/be нужно быть аккуратным, плюс имейте ввиду что некоторые блокнотики оставляют bom (byte order mark), т.е. это нужно учитывать, когда будете искать начала ваших строк.

            1. Проблема не так проста как кажется, и если бы была проста, то давно бы имелись решения, причём множественные массовые решения.
→ Ссылка