Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   [решено] Запись в файл (http://forum.oszone.net/showthread.php?t=191567)

pogo 18-11-2010 15:18 1545704

Запись в файл
 
Люди добрые и знающие помогите пожалуйста
есть задача:
Программа просит ввести строку. Строка - слова разделённые одним или несколькими пробелами.
Удалить лишние пробелы (вначале строки, в конце строки, 1 пробел между словами).
Результат вывести на экран и записать в файл (файл создаётся в процессе)

Я тут написал часть программы:
Код:

        .MODEL small                        ;отводим под стек и под данные по 64Кб
        .STACK 100h                                ;отмечаем начало сегмента стека
        .DATA                                        ;отмечаем начало сегмента данных
        NL                db                0Ah, 0Dh, '$'
        Buf                DB                255, 0, 256 DUP (0)    ;
        .CODE                                ;отмечаем начало сегмента кодов
        main PROC
        mov                ax,@data                ;копируем адрес
        mov                ds,ax                ;сегмента данных
        mov                dx,offset Buf        ;считываем  строку с клавиатуры
        mov                ah,0Ah
        int                21h
        xor                cx,cx
        mov                al,[Buf+1]      ;если считано 0 байт, то выход из
        mov                cl,al              ;задаем количество повторений (длина строки)
        test        al,al                        ;программы
        jz                Exit
        mov                ah,09h
        mov                dx,offset NL          ;перейти на следующую строку
        int                21h
        mov                si,offset Buf+2
        mov                dh,0Dh                ;подготовка - суём в регистр символ,
                                                        ;которого не может быть во введённой строке
       
        tmp:
                mov                dl,[si]
                cmp                dl,' '
                jne                Cycle1
                inc                si
                dec                cx
                jmp                tmp
               
               
    Cycle:
                mov    dl,[si]                ;считать символ
        Cycle1:
                cmp    dl,' '                ;сравнить с пробелом
                jne    Print                ;если не пробел - вывести
        cmp        dx,'  '                        ;а если пробел - то предыдущий был пробел или нет?
        je    NextChar                        ;если два пробела подряд - не печатаем
                jne                Print
                        Print:
                                mov    ah,02h                ;выбор функции 2
                                int    21h                        ;вызов DOS
        NextChar:
        mov        dh,dl                              ;сохранить текущий символ для теста на следующем витке
        inc        si                              ;перейти к следующему символу
    loop    Cycle
    Exit:
                mov                AX,4C00h        ;выход
                int                21h                ;из программы
    main    ENDP
    END main

Программа удаляет пробелы вначале строки и делает 1 пробел между словами.
Помогите пожалуйста удалить последние пробелы, а главное записать всё это дело
в файл...
В ассемблере не силён, погуглив в принципе нашёл как работать с файлами...
Но у меня ничего не получилось, по сюда даже не писал мои попытки работать с файлами,
ибо сам посидел, посмотрел и понял, что это бред.
Заранее спасибо!!

Admiral 18-11-2010 16:36 1545746

pogo, задачу нужно решить именно под DOS (для иллюстрации процесса с академической точки зрения, судя по коду это TASM)? Или же нужна именно такая программа, и для ОС отличной от DOS?

Если на второе да, и ОС для которой нужно решение - MS Windows, то для решения можно воспользоваться функциями CreateFile\WriteFile\CloseHandle.
Если нужен именно под DOS, то задача сведётся к поиску нужных прерываний по работе с файлами.

pogo 18-11-2010 17:26 1545772

да использую tasm и tlink
Надо именно под DOS
да и прерывания в инете найти не проблема введя в любом поисковике ассемблер работа с файлами он всё выдаст...
у меня проблема именно с реализацией этих прерываний в коде программы...
помогите пожалуйста дописать прогу

pogo 19-11-2010 13:02 1546338

Что на таком большом форуме никто ассемблера не знает?((

ganselo 19-11-2010 16:52 1546549

Цитата:

Цитата pogo
Что на таком большом форуме никто ассемблера не знает?(( »

тебе на wasm.ru

Admiral 19-11-2010 17:13 1546568

pogo, вот пример http://subscribe.ru/archive/comp.pro.../26170402.html
Исключительно по теме:
Код:

TITLE Write 2 File Example

;Запись в файл

DOSSEG
.MODEL TINY
.STACK 100h
.DATA
        szFileName DB 'My file.txt', '0'
        msgSize = $-szFileName
.CODE
.386
ENTRY PROC NEAR
        mov ax, @data
        mov ds, ax

;создаём файл
        mov ah, 3Ch        ;Запись в файл или устройство
        lea dx, szFileName ; эквивалентно -> mov dx, offset szFileName
        xor cx, cx
        int 21h
;считаем что проблем с созданием не возникло (а так нужна проверка)
        mov bx, ax        ; сохраняем описатель (handle) файла в bx
;пишем в файл
        mov ah, 40h
        lea dx, szFileName
        mov cx, msgSize
        int 21h
;закрываем файл
        mov ah, 3Eh
        int 21h

        mov ax, 4c00h
        int 21h
ENTRY ENDP
END

Создаётся файл с именем My file.txt с таким же содержанием + символ окончания строки.

pogo 19-11-2010 18:01 1546593

Дошёл до того, что сделал 1 часть с пробелами:
Код:

        .MODEL small                        ;отводим под стек и под данные по 64Кб
        .STACK 100h                                ;отмечаем начало сегмента стека
        .386
        .DATA                                        ;отмечаем начало сегмента данных
        NL                db                0Ah, 0Dh, '$'
    Buf                DB                255, 0, 256 DUP (0)    ;
        hFile        dw                ?
        Filename        db                'file.txt',0
        .CODE                                ;отмечаем начало сегмента кодов
        main PROC
                mov                ax,@data                ;копируем адрес
                mov                ds,ax                ;сегмента данных
       
                mov dx, offset Buf
                mov ah, 0Ah
                int 21h                                ;запрашиваем строку
 
                mov dx, offset NL
                mov ah, 9h
                int 21h                                ;переводим строку на экране, выводя CRLF
 
                xor cx, cx
                mov cl, [Buf+1]
                test cl, cl
                jz Exit                                ;проверяем длину строки - если пустая, то выходим
       
;                mov si, offset Buf+2                ;если не пустая - то будем искать пробелы
;                add Buf+2,cl
                add bx, offset Buf+1
                add bl, cl
                mov        si, bx
last:
                mov                dl,[si]
                cmp                dl,' '
                jne                tmp
                dec                si
                dec                cx
                jmp                last
               
               
tmp:        mov si, offset Buf+2

first:        mov                dl,[si]
                cmp                dl,' '
                jne                Cycle
                inc                si
                dec                cx
                jmp                first
               
Cycle:
                mov dl, [si]                        ;берём очередной байт
                cmp dl, ' '                        ;сравниваем с пробелом
                jne        Print
                cmp        dx,'  '                        ;а если пробел - то предыдущий был пробел или нет?
        je    NextChar                ;если два пробела подряд - не печатаем
               
Print:
                mov    ah,02h                ;выбор функции 2
                int    21h                        ;вызов DOS
               
NextChar:
                mov        dh,dl                ;сохранить текущий символ для теста на следующем витке
        inc        si                        ;перейти к следующему символу
               
                loop        Cycle
 
 
Exit:
                mov ax, 4c00h
                int 21h                                ;выходим из программы

    main    ENDP
    END main

как с файлом сделать теоретически я представляю,
взять полученную строку и посимвольно записать её в файл...
или записать всё в переменную, что бы в ней получилась обработанная строка...
Но я вообще не поднимаю как это в Ассемблере реализовать ((
я не понимаю как вообще в файл запись происходит...

pogo 24-11-2010 09:15 1550175

Вот готовый рабочий код программы:
Программа просит ввести строку. Строка - слова разделённые 1 или несколькими пробелами, удалить лишние пробелы (вначале строки, в конце строки, 1 пробел между словами)
Результат вывести на экран и записать в файл (файл создаётся в процессе). Запись в файл организовать в процедуре.

Код:

        .MODEL small                        ;отводим под стек и под данные по 64Кб
        .STACK 100h                                ;отмечаем начало сегмента стека
        .386
        .DATA                                        ;отмечаем начало сегмента данных
        NL                db                0Ah, 0Dh, '$'
        Buf                DB                255, 0, 256 DUP (0)    ;
        hFile        db        300                dup(?)
        Filename        db                'file.txt',0
        .CODE                                ;отмечаем начало сегмента кодов
        main PROC
                mov                ax,@data                ;копируем адрес
                mov                ds,ax                ;сегмента данных
       
                mov dx, offset Buf
                mov ah, 0Ah
                int 21h                                ;запрашиваем строку
 
                mov dx, offset NL
                mov ah, 9h
                int 21h                                ;переводим строку на экране, выводя CRLF
 
                xor cx, cx
                mov cl, [Buf+1]
                test cl, cl
                jz Exit                                ;проверяем длину строки - если пустая, то выходим
       
                add bx, offset Buf+1
                add bl, cl
                mov        si, bx
last:
                mov                dl,[si]
                cmp                dl,' '
                jne                tmp
                dec                si
                dec                cx
                jmp                last
               
               
tmp:        mov si, offset Buf+2
 
first:        mov                dl,[si]
                cmp                dl,' '
                jne                Cycle
                inc                si
                dec                cx
                jmp                first
 
               
Cycle:                lea di, hFile
                mov bx,0
 
Cycle1:                mov dl, [si]                        ;берём очередной байт
                cmp dl, ' '                        ;сравниваем с пробелом
                jne        Print
                cmp        dx,'  '                        ;а если пробел - то предыдущий был пробел или нет?
                      je    NextChar                ;если два пробела подряд - не печатаем
               
Print:
                mov        [di], dl
                inc        di
                mov    ah,02h                ;выбор функции 2
                int    21h                        ;вызов DOS
                inc        bx
                               
NextChar:
                mov        dh,dl                ;сохранить текущий символ для теста на следующем витке
                inc        si                        ;перейти к следующему символу
               
                loop        Cycle1
               
                push        bx
 
                mov ah, 3Ch                        ;если же добрались до конца - будем сохранять.
                mov dx, offset Filename
                xor cx, cx
                int 21h                                ;создаём файл
 
                pop        si               
 
                push        offset        hFile
                call        vivod
 
                mov ah, 3eh
                int 21h                                ;закрываем файл
 
Exit:
                mov ax, 4c00h
                int 21h                                ;выходим из программы
 
    main    ENDP
 
    vivod        proc
    mov bx, ax
    mov ah, 40h
    mov cx, si
    mov bp, sp
    add bp, 2
    mov dx, [bp]
    int 21h
    ret
    vivod        endp
    END main

Может кому пригодится ))


Время: 18:24.

Время: 18:24.
© OSzone.net 2001-