· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.A&O —› Количество разделителей строк

. 1 . 2 . 3 . >>

Посл.отвђт Сообщенiе


Дата: Авг 24, 2004 03:31:21

Считал в память текстовый файл, разделение строк - 0D0A (CrLf). Подсчитал количество строк. Затем загнал файл в Word, а он показывает мне больше строк, чем я посчитал. Это я обмишурился, или Word? Подскажите, плиз. На маленьком файле вручную посчитал - совпадает, на большом - 240000 строк, Word показал 270000. А вручную подсчитать слабо. Гляньте опытным глазом кто-нить, пожалуйста.
    push esi
    xor ebx,ebx
    xor edx,edx
    mov ecx,FileSize	; размер 		
    mov dx,0A0Dh        ; разделитель
    mov esi,ArrAddr     ; начало
    push esi            ; в стек, для последующего использования
@Loop:
    cmp dx,word ptr[esi]
    jne @F 
    inc ebx
    push esi            ; адрес каждого разделителя - в стек
    @@:
    inc esi
    dec ecx
    jnz @Loop
    shl ebx,2           ; по количеству строк * 4 получаю кусок памяти
    mov PtrTblSize,ebx
    push PAGE_READWRITE
    push MEM_COMMIT
    push ebx
    push NULL
    Call VirtualAlloc
    mov PointerTbl,eax    ; под таблицу указателей
@@: pop dword ptr[eax+ebx]; и заполняю эту таблицу
    sub ebx,4             ; доставая указатели из стека
    jnz @B 
    pop dword ptr[eax+ebx]; и в конце - указатель на начало
    pop esi


Вот примерно так. И ещё 2 вопроса:
1. Можно ли ускорить работу цикла по поиску разделителей и вообще это методически правильный метод составления таблицы указателей?
2. Насколько нехорошо, что я засунул в стек 240000 двордов? В принципе, засунул и тут же высунул. Нигде не таскаю за собой. Отрабатывает довольно быстро, но всё-таки...

Посоветуйте что-нибудь.


Дата: Авг 24, 2004 04:31:01

Вы считаете разделители, которые в ДОСе считаются разделителем строки, а в ВОРДе это конец параграфа. Возможно некоторые ДОС-овские строки не помещаются в ВОРД-овскую строку и переносятся на следующую строку. Вероятно так.


Дата: Авг 24, 2004 04:52:57 · Поправил: q_q

cresta
Уж не собираешься ли ты сортировать файл по строкам?
Ты знаешь, что в ntfs файлы могут иметь размер больше, чем 2^32-1?
Посмотри реализацию функции memchr, например, в VC crt, файл memchr.asm.


Дата: Авг 24, 2004 08:45:27 · Поправил: leo

pas прав - Word выдает "свое" количество строк, зависящее от установок параметров страницы.

Еще возможные источники ошибки:
1) В "правильном" текстовом файле разделителем строк является сочетание 0D0A. Однако в самопальных файлах могут присутствовать и одиночные символы 0D или 0A, которые также считаются разделителем строки. Поэтому для надежности следует проверять три варианта: 0D, 0A и 0D0A (в частности такой анализ делается в TStrings.SetText от Borland)
2) В DOS-файлах может встречаться символ раздела страницы (код 0C,если не ошибаюсь). Считать его отдельной строкой или нет - вопрос.

Что касается стека, то это тоже вопрос надежности. Надежнее, конечно, не возиться со стеком, а сразу работать с VirtualAlloc (MEM_RESERVE + MEM_COMMIT по необходимости) .
Другой известный вариант - SparseArray (используется например в компоненте TStringGrid от Borland). Суть подхода в том, что указатели хранятся не в виде единого массива, а виде массива указателей на массивы (блоки) фиксированного размера (обычно кратного степени 2 для упрощения преобразования линейного индекса в номер блока и индекс элемента внутри блока).


Дата: Авг 24, 2004 15:58:11

pas

Вполне ясно.

leo

В файле только 0d0a, это проверено.
„сразу работать с VirtualAlloc“
Тогда мне дважды надо пройти файл, один раз - получить кол-во строк (указателей), чтобы по этому кол-ву выделить память, и второй раз - собственно заполнение этой памяти адресами.
„Другой известный вариант - SparseArray “
„для упрощения преобразования линейного индекса “
Какие это даёт преимущества? Я должен пройти через массив в любом случае, и раз я это делаю, то заодно и сохраняю адреса строк. SparseArray тоже не сможет обойтись без первого прохода. И каков смысл сначала разложить адреса на составляющие (номер блока+смещение внутри блока), а затем выполнять обратное преобразование? В чём здесь фишка, я не понял. Я буду адресовать непосредственно как dword ptr[eax], а в случае с блоками надо ещё и вычислить значение, которое загрузить в eax.

q_q

Ну да, это моё любимое занятие :) Да и ntfs меня не пугает, я его стороной обойду.

„Посмотри реализацию функции memchr“

Не нашёл я у себя файла memchr.asm.


Дата: Авг 25, 2004 03:56:06

cresta
да, это моё любимое занятие
Если в файле строки не слишком длинные, то запускай sort.exe и используй ее результат.

Не нашёл я у себя файла memchr.asm
см. аттачь.

Насколько нехорошо, что я засунул в стек 240000 двордов?
Зачем? Тебе необходимо рисовать прогресс сортировки?

Я делал так:
Зарезервировал память для N адресов строк - массив адресов отсортированных строк. Адрес первой строки помещаю в начало массива. Читаю очередную строчку и методом половинного деления беру из массива адрес строки для сравнения с очередной. Как только нашел место очередной строки в массиве, то вставляю ее, все которые больше двигаются вниз. Разумеется, необходимо проверять не пора ли увеличить размер массива. Когда прочитаны все строки, то записываю результирующий файл согласно массиву.

Ты используешь mmf?

_1988072419__memchr.rar


Дата: Авг 25, 2004 04:29:44 · Поправил: masquer

в Word-е вообще 0Dh - это окончание параграфа, 0Ah для текста ничего не означает и пропускается

„Word выдает "свое" количество строк, зависящее от установок параметров страницы.“
От каких это, можно уточнить?


Дата: Авг 25, 2004 04:35:51

masquer
Левое и правое поля.


Дата: Авг 25, 2004 04:36:37

masquer
ПОртрет Ландшафт,размер шрифта. ИМХО.


Дата: Авг 25, 2004 04:38:23

pas
размер шрифта
Это не параметр страницы.


Дата: Авг 25, 2004 04:46:33

q_q
„размер шрифта
Это не параметр страницы.“

Согласен, но тоже влияет на количество символов в строке.


Дата: Авг 25, 2004 04:54:29 · Поправил: masquer

q_q, pas
Ну, хорошо, есть у меня, например, длинное предложение (одно на абзац, например), как ваши установки могут привести к изменению этого кол-ва. Честно, перепробовал все (ну, кроме размера шрифта :) ) кол-во абзацев ну никак не поменялось. И не должно оно меняться он _установок листа_.

По теме, загнал большой текстовый файл в ворд, кол-во символов абзаца (0d) в ворде (физическом файле) совпало с кол-вом 0d0a в текстовом файле, но оказалось немного больше того, как показала Статистика в ворде (не знаю, как оно там меряет).

Хе-хе, между кол-вом символов в строке и кол-вом абзацев есть некоторая разница (в ворде, ес-но)


Дата: Авг 25, 2004 05:10:24

masquer
длинное предложение (одно на абзац, например) ... перепробовал все ... кол-во абзацев ну никак не поменялось
Не путай количество абзацев и количество строк.


_373254595__count.gif


Дата: Авг 25, 2004 05:13:22

cresta > „Насколько нехорошо, что я засунул в стек 240000 двордов?“

imho ничего страшного в этом нет, но нужно знать несколько моментов:
http://www.wasm.ru/forum/index.php?action=vthread&forum=4&topic=5573
По ссылкам приведённым Four-F можно много интересного найти ;-)

По поводу CrLf может попробовать, например, OpenOffece или другой редактор, Word imho глючный :-)


Дата: Авг 25, 2004 05:16:30

„Не путай количество абзацев и количество строк.“
а при чем здесь кол-во строк (а понял, это автор топика внес)? Если есть текстовый файл и в нем есть 0d0a, то в ворде это сконвертнется в 0d и будет считаться за абзац, а не строку

. 1 . 2 . 3 . >>


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.044