Файловый вывод в теле FOR-FILES

Обсуждение программ nnCron и nnCron LITE

Файловый вывод в теле FOR-FILES

Postby HimFighter » Wed, 19 Nov 2008, 18:40

Все хорошо про файловый вывод написано в FAQ/help_ru.chm и на форуме, но только действия производятся над конкретным файлом, и проблемы моей не решают...
Задача стоит такая: В некую папку ежедневно валятся файлы с мутным содержимым... кроме 1 строчки, по которой можно определить, что это за файл, я бы хотел реализовать счетчик файлов с нужной мне строкой за сутки на предмет их количества в папке.
На сегодняшний момент я в тупике.
Вот известный пример из help с построчным выводом файла через MSG.


#( test_read_by_line
NoActive
\ Построчно (в цикле) считываем файл
\ test.txt в массив list-contents и
\ выводим каждую строчку на экран.
\ Строки в файле не должны быть длиннее 255 символов.
VARIABLE list-file
CREATE list-contents 258 ALLOT
Action:
S" test.txt" R/O OPEN-FILE-SHARED THROW list-file !
\ записываем строку во вторую ячейку массива list-content
BEGIN list-contents 1+ 255 list-file @ READ-LINE THROW WHILE
\ На стеке осталось число прочитанных символов.
\ Сохраняем его в первую ячейку массива, чтобы
\ получить строку со счетчиком
list-contents C!
MSG: "%list-contents COUNT%"
REPEAT
DROP
list-file @ CLOSE-FILE DROP
)#

если его загнать в тело цикла FOR-FILES, то вылетает ошибка примерно : "Внутряння ошибка [название задания] файл не найден!"
как я понимаю, вот так мы работать хотим:
S" test.txt" R/O OPEN-FILE-SHARED THROW list-file !
а вот так уже нет:
S" %FOUND-FULLPATH%" R/O OPEN-FILE-SHARED THROW list-file !

грубо говоря мне нужно в теле цикла FOR-FILES делать построчное сравнение каждой строки с моей строкой на предмет совпадения ее части

подскажите пожалуйста, может есть другой способ, но мне нужно это все делать над файлами в нужной папке скажем по такой маске e*.*
HimFighter
 
Posts: 2
Joined: Wed, 19 Nov 2008, 18:22

Re: Файловый вывод в теле FOR-FILES

Postby SeMa » Wed, 19 Nov 2008, 22:12

Прочти это.
В твоем случае проще:
FOUND-FULLPATH R/O OPEN-FILE-SHARED THROW list-file !
Компьютер ─ устройство, разработанное для ускорения и автоматизации человеческих ошибок
User avatar
SeMa
 
Posts: 637
Joined: Fri, 15 Apr 2005, 12:49
Location: Украина

Re: Файловый вывод в теле FOR-FILES

Postby elos » Thu, 20 Nov 2008, 09:30

куски кода к размышлению...
Code: Select all
\ Выведет в сообщении первую строчку файла test.txt
READ-BY-LINE: "D:\test.txt"
MsgBox 0
;?READ-BY-LINE

Code: Select all
#( Test-Read-BY-Line
NoActive
Action:
\ Выведет в сообщении все строчки файла test.txt
READ-BY-LINE: "D:\test.txt"
MsgBox
;READ-BY-LINE

S" D:\test.txt" READ-BY-LINE  \ Быстрее, т.к. строке не делается EVAL-SUBST (т.е. не работает %<...code...>%)
MsgBox
;READ-BY-LINE


\ Выведет в сообщении все строчки файла test.txt
READ-BY-LINE: "D:\test.txt"
MsgBox -1
;?READ-BY-LINE

S" D:\test.txt" READ-BY-LINE  \ Быстрее, т.к. строке не делается EVAL-SUBST (т.е. не работает %<...code...>%)
MsgBox -1
;?READ-BY-LINE


\ Выведет в сообщении первую строчку файла test.txt
READ-BY-LINE: "D:\test.txt"
MsgBox 0
;?READ-BY-LINE

S" D:\test.txt" READ-BY-LINE  \ Быстрее, т.к. строке не делается EVAL-SUBST (т.е. не работает %<...code...>%)
MsgBox 0
;?READ-BY-LINE
)#


плагин недавно в очередной раз проскакивал на форуме (в секцию плагинов вроде так и не положен)
обозвал как string_manipulation.spf и подключил как плагин
Code: Select all
: (?READ-BY-LINE) { xt \ Lf Lc fEND -- }  ( a u xt -- )
    -1 TO fEND
    10240   \ максимальная длина строки (в символах)
    ALLOCATE THROW TO Lc
    R/O OPEN-FILE-SHARED THROW TO Lf
    BEGIN Lc 10238 Lf READ-LINE THROW
    fEND AND WHILE  \ Выход по команде
    Lc + 0 SWAP C!
    Lc ASCIIZ> xt EXECUTE TO fEND
    REPEAT  DROP
    Lf CLOSE-FILE DROP
    Lf FREE DROP
    Lc FREE DROP ;
: (READ-BY-LINE) { xt \ Lf Lc fEND -- }  ( a u xt -- )
    10240   \ максимальная длина строки (в символах)
    ALLOCATE THROW TO Lc
    R/O OPEN-FILE-SHARED THROW TO Lf
    BEGIN Lc 10238 Lf READ-LINE THROW WHILE
    Lc + 0 SWAP C!
    Lc ASCIIZ> xt EXECUTE \ TO fEND
    REPEAT  DROP
    Lf CLOSE-FILE DROP
    Lf FREE DROP
    Lc FREE DROP ;
: READ-BY-LINE \ compile: ( -- )
            \  execute: ( a u --)
    POSTPONE [NONAME
; IMMEDIATE
: ;READ-BY-LINE
    POSTPONE NONAME]
    POSTPONE (READ-BY-LINE)
; IMMEDIATE
: ;?READ-BY-LINE  ( ? -- )  \ 0 (FALSE) - выход из цикла, все остальные значения считаются правдой и цикл продолжится
    POSTPONE NONAME]
    POSTPONE (?READ-BY-LINE)
; IMMEDIATE
: READ-BY-LINE: eval-string,  POSTPONE READ-BY-LINE ; IMMEDIATE



переделанная из обычного примера простенькая записная книжка - где-то какой-то глюк сидит (уже даже забыл какой, за работой некогда доотладить), но так вроде работает...
Code: Select all
#( phone_book
\ выводит все в СТОЛБИК
AsLoggedUser
WatchHotKey: "+$p"
CREATE s_request 256 ALLOT                          \ искомая подстрока
CREATE s_found 256 ALLOT                            \ найденная подстрока
CREATE s_contents 256 ALLOT                         \ буфер ввода
USER-VALUE phone_list                               \ строковый буфер вывода
: TO-LOWER ( aс --  ) COUNT LOWER-TABLE RECODE ;    \ преобразование в нижний регистр

Action:

WIN-INPUT-TEXT: "Поиск телефонов" "Введите искомое слово" "*" 0 0=
IF                                      \ что-то ввели! помещаем в буфер s_request
  s_request PLACE                       \ разыскиваемое слово в переменной s_request (ac)
  10256 ALLOCATE THROW TO phone_list    \ резервируем место под будущий вывод
  S" " phone_list ZPLACE                \ и помещаем туда пустую строку

  FOR-FILES: "C:\PHONES\*.txt"
    READ-BY-LINE: FOUND-FULLPATH        \ ( -- a u )
      s_contents PLACE                  \ сохраняем считанное
      s_contents COUNT s_found PLACE    \ дублируем для конвертирования
      s_found   TO-LOWER                \ считанная строка
      s_request TO-LOWER                \ искомая подстрока
      RE-MATCH: "%s_found COUNT%" "/%s_request COUNT%/"
      IF                                \ нашли - запихиваем в az-буфер исходную строку
        s_contents COUNT 72 MIN phone_list +ZPLACE crlf phone_list +ZPLACE
      THEN
    ;READ-BY-LINE
  ;FOR-FILES                            \ теперь выводим - если есть что... надо проверить
  \ список заполнен? как проверить?
  phone_list ASCIIZ> NIP                \ оставим только длину строки
  IF                                    \ ничего не нашли - нулевая строка
    BEEP: 500 500
  ELSE                                  \ выводим найденное
    HINT: "%phone_list ASCIIZ>%"
    phone_list FREE DROP                \ освобождение памяти занятой строкой
  THEN
THEN
)#

не забываем подключить соответствующие плагины типа recode.spf

переделано из вот этого работающего кода, который был сделан на основе примера:
Code: Select all
#( phone_birthdays
\ выводит все в СТОЛБИК
AsLoggedUser
WatchHotKey: "+$p"
VARIABLE f_buf             \ файловый буфер-указатель
CREATE string-contents 258 ALLOT \ буфер считанной строки
CREATE s1 256 ALLOT           \ искомая подстрока
CREATE s2 256 ALLOT           \
\ CREATE filecur 256
: TO-LOWER ( ac -- ac ) COUNT LOWER-TABLE RECODE ;
Action:
FILE-WRITE: "C:\nnCron\phone.txt" ""
WIN-INPUT-TEXT: "Поиск телефонов" "Введите искомое слово" "*" 0 0=

IF \ что-то ввели! помещаем в буфер s1
s1 PLACE                     \ разыскиваемое слово в переменной s1

FOR-FILES: "C:\PHONES\*.txt"
    S" %FOUND-FULLPATH%" EVAL-SUBST R/O OPEN-FILE-SHARED THROW f_buf !
    BEGIN string-contents 1+ 255 f_buf @ READ-LINE THROW WHILE
    string-contents C!         \ в string-contents лежит прочитанная строка в ac-формате
    string-contents COUNT s2 PLACE      \ ДУБЛИРУЕМ СЧИТАННОЕ ДЛЯ  ПРЕОБРАЗОВАНИЯ
           s1 TO-LOWER                  \ искомая подстрока
           s2 TO-LOWER                  \ исходная строка
RE-MATCH: "%s2 COUNT%" "/%s1 COUNT%/"
IF
string-contents COUNT 72 MIN S" C:\nnCron\phone.txt" FAPPEND
FILE-APPEND: "C:\nnCron\phone.txt" "%crlf%"
THEN
    REPEAT
    DROP
    f_buf @ CLOSE-FILE DROP
;FOR-FILES

 FILE-EMPTY: "C:\nnCron\phone.txt"
 IF BEEP: 500 500 ELSE
 S" Courier New" 16 HINT-FONT
 THINT: "%FILE: C:\nnCron\phone.txt%" 0
 THEN
\ затираем, чтобы никто не посмотрел, что мы искали
 FILE-WRITE: "C:\nnCron\phone.txt" ""
THEN
)#
переделка была затеяна по причине - ну не хочу я лишний файл на диске иметь и диск лишний раз мусолить...
elos
 
Posts: 664
Joined: Tue, 25 Apr 2006, 11:15


Return to nnCron forum (Russian)

Who is online

Users browsing this forum: No registered users and 3 guests