общее количество строк в файле (считая в обратном порядке)

Могу ли я для данного файла подсчитать количество строк в обратном порядке? то есть начиная с EOF, считая строки до начала?

Я мог искать до конца файла. Начните с формы, продолжайте искать новую строку char (указание на новую строку) и продолжайте увеличивать мой счетчик line_number. Но каким должно быть мое конечное состояние?

Есть ли что-то противоположное EOF? :)

Мое собственное предложение: если я ищу X-ю строку с конца, я всегда могу получить ее с начала по этому номеру строки: total_lines - X --- достаточно справедливо?

Мотив: я заинтересован в том, чтобы перейти к X-й строке в конце ОГРОМНОГО (читай, действительно огромного) файла. Итак, ищем наиболее оптимальное решение.

PS: это не домашнее задание (хотя я всю жизнь учусь :p)


person hari    schedule 07.07.2011    source источник
comment
я могу даже вернуться назад от EOF: D ??   -  person hari    schedule 07.07.2011
comment
@hari вы начинаете сверху к концу или наоборот, но количество строк всегда остается одинаковым, тогда почему назад?   -  person rahularyansharma    schedule 07.07.2011
comment
Есть ли причина, по которой вам нужно сделать это в обратном порядке? Если это домашнее задание, это нормально, но вы должны отметить его как таковое.   -  person Chris Lutz    schedule 07.07.2011
comment
@Chris: ценю ваше любезное предложение. Теперь причина: я хочу перейти на X-ю строку из EOF.   -  person hari    schedule 07.07.2011
comment
Конечным условием является аргумент fseek, равный 0.   -  person Jim Balter    schedule 07.07.2011


Ответы (3)


Противоположностью EOF является pos == 0.

Команда POSIX tail делает это; например код, см. http://www.koders.com/c/fid8DEE98A42C35A1346FA89C328CC3BF94E25CF377.aspx >

person Jim Balter    schedule 07.07.2011

Когда я делал это (например, писал грубый эквивалент стандартного tail), я читал блок с конца, считал строки в нем, если мне не хватало строк, использовал fseek, чтобы вернуться назад и прочитать еще один блок (но я не уверен, что последнее когда-либо действительно происходило, за исключением случаев, когда я принудительно это делал при тестировании).

person Jerry Coffin    schedule 07.07.2011
comment
У OP есть ОГРОМНЫЙ (читай, действительно огромный) файл ... почти гарантировано, что X-я строка не всегда будет найдена в первом прочитанном блоке. - person Jim Balter; 07.07.2011
comment
@Jim: размер файла здесь не имеет значения - важна средняя длина строк (и значение X). Последние, скажем, 10 строк, скорее всего, будут в последних 8 килобайтах, независимо от того, предшествуют ли им 10 мегабайт, 10 гигабайт или даже 10 терабайт другого текста. Когда/если это не так, это потому, что каждая строка очень длинная, а не из-за того, сколько текста предшествует ей. - person Jerry Coffin; 07.07.2011
comment
Конечно, размер файла влияет на то, будет ли запрошенная строка найдена в первом прочитанном блоке. Если файл большой, то ваш блочный буфер гарантированно будет меньше файла, и, таким образом, X-я строка может не найтись в нем. Ваша логика странная... конечно 10-я строка назад не будет найдена в последних N газиллибайтах, только если строки действительно длинные, но кто сказал что-нибудь о 10? Пока X-я строка находится во второй половине файла, быстрее выполнять поиск в обратном направлении; для огромных файлов такие X будут огромными, или строки будут огромными... - person Jim Balter; 07.07.2011
comment
P.S. Мне трудно понять, почему это неочевидно, так что, вероятно, мы как-то говорим мимо друг друга... Я ответил, что не уверен, что последнее когда-либо действительно происходило... если это не так, тогда это означает, что строка, которую вы искали, всегда встречалась в первом прочитанном блоке, а это означает, что вы либо всегда искали строки ближе к концу, либо ваши файлы всегда полностью помещались в буфере вашего блока. Последнее явно не относится к огромным файлам, а первое не является условием, указанным в OP ... нет особых причин думать, что X-я строка находится в блоке EOF. - person Jim Balter; 07.07.2011
comment
@ Джим: я думаю, это означает, что его реплики всегда были короткими, а его X всегда был маленьким. Другими словами, он не писал утилиту tail, которой пользователи будут передавать произвольные файлы и числа, у него был конкретный вариант использования, когда ему нужны были данные ближе к концу отформатированного файла. Я иногда использовал сам tail для получения более нескольких МБ данных, но не часто. Однако, если бы я потратил больше времени на просмотр больших файлов журналов, я мог бы поискать последний миллион событий или что-то еще. - person Steve Jessop; 07.07.2011
comment
@Steve ОП никогда не говорил ничего подобного. Я знаю множество случаев использования, когда X не всегда мал... недостаточно мал, чтобы гарантировать, что X-я запись будет находиться в последнем блоке файла для любого размера блока, который может поместиться в памяти. В любом случае проблема заключается в том, является ли размер файла релевантным, и это явно связано с указанной мною причиной: чем больше файл, тем больше вероятность того, что он не поместится в один блок. . Конец этой дискуссии для меня. - person Jim Balter; 07.07.2011
comment
@Jim: Конечно, ОП никогда не говорил ничего подобного. Джерри говорил о своем собственном опыте, а не об опыте ОП. Следовательно, когда я сделал это. Если вариант использования OP отличается от варианта использования Джерри, ему следует использовать другой подход. Если это то же самое, он мог бы с пользой использовать тот же подход. Поэтому только ОП знает, подходит ли решение Джерри для ОП. - person Steve Jessop; 07.07.2011
comment
@ Стив Джерри говорил о своем собственном опыте, а не об опыте ОП - ага. Я сказал, что этот опыт не применим ЗДЕСЬ. До свидания. - person Jim Balter; 07.07.2011
comment
@ Стив П.С. Это действительно очень глупо. Подход Джерри - это подход хвоста и подход, применимый к ОП. Проблема не в подходе, а в том, произойдет ли чтение другого блока на практике. Если бы подход Джерри заключался в том, чтобы просто выйти, если строка не была найдена в первом прочитанном блоке, тогда ваш комментарий имел бы смысл. А так, это просто спор ради спора. - person Jim Balter; 07.07.2011
comment
@Джим: нет. Я спорю, потому что вы сказали, что я думаю, что мы говорим мимо друг друга, Джерри не ответил и, следовательно, предположительно выполняет какую-то работу, и я подумал, что вижу, как вы говорите мимо друг друга. Вы работали на основе того, что когда-либо действительно случившееся означает все мыслимые варианты использования, Джерри говорил о своем личном использовании. И если вы попрощаетесь, а затем добавите PS, вы не сможете обвинить меня в споре ради спора, но вы правы, я должен был сказать, смотрите то же самое, а не используйте такой же подход. Вы не знаете, применим ли опыт здесь. - person Steve Jessop; 07.07.2011
comment
@Steve Что бы ты ни говорил, я уверен. - person Jim Balter; 07.07.2011

Если вы хотите печатать строки в обратном направлении, вы можете использовать для этого рекурсию (не уверен, что вы подразумеваете под счетом, потому что подсчет количества строк в прямом направлении такой же, как и в обратном). Это звучит как домашняя задача для введения в C, поэтому я воздержусь от написания кода, но подумаю об этом так. Прочитайте строку, если это не EOF, рекурсивно прочитайте следующую строку, в противном случае напечатайте строку и вернитесь.

person Jesus Ramos    schedule 07.07.2011
comment
Вам нужна итерация, а не рекурсия; рекурсия переполнит ваш стек (если не писать на языке, который оптимизирует хвостовую рекурсию, чего, конечно же, не делает C). - person Jim Balter; 07.07.2011
comment
Для этого требуется довольно много строк, он мог бы просто поместить это в связанный список строк, сохраняя при этом счетчик. - person Jesus Ramos; 07.07.2011
comment
ОП сказал, что это огромный файл. Даже если бы это не было указано, было бы ужасной практикой программирования (достаточно для меня, чтобы стрелять) писать код, известный, который дает сбой, просто давая ему большой файл. И зачем создавать связанный список, когда все, что нужно, это X-я строка с конца? В обоих случаях полезно прочитать вопрос. - person Jim Balter; 07.07.2011
comment
Ну, я прочитал вопрос до того, как он был отредактирован, чтобы сделать его более ясным, сначала я не был уверен, что именно он хотел. - person Jesus Ramos; 08.07.2011