0 / 0 / 0
Регистрация: 22.10.2017
Сообщений: 29
1

Поменять в исходном файле буквы слов местами

22.10.2017, 00:19. Показов 2640. Ответов 16
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Программа должна быть на писана на языке Assembler. С комментариями.
Программа должна обрабатывать исходный текстовый файл с использованием функций DOS и формировать новый файл с результатами обработки исходного файла.
Имя исходного и обработанного файлов задать в программе в виде ASCIIZ-строк.
При обработке файла использовать следующую последовательность вызова функций DOS:
1. открытие исходного файла (функция 3DH);
2. создание нового файла, куда будут помещаться результаты обработки исходного файла (функция 3CH);
3. чтение исходного файла (функция 3FH);
4. обработка прочитанных данных;
5. запись обработанных данных в созданный файл (функция 40H);
6. закрытие файла с результатами обработки (функция 3EH);
7. закрытие исходного файла (функция 3EH).
Для чтения данных из исходного файла может быть использован буфер, определенный в программе как массив байт или слов. Рекомендуемый размер буфера – 512 байт (256 слов). На шаге 4 обрабатываются данные, находящиеся в буфере, а на шаге 5 обработанные данные из буфера записываются в файл.
Размер исходного файла для обработки выбрать меньшим или равным размеру буфера.
Задание (для 4 пункта):
Поменять в исходном файле буквы слов местами. Пример: windows -> swodniw.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.10.2017, 00:19
Ответы с готовыми решениями:

Поменять в исходном файле строки местами
Здравствуйте. Нужно написать программу на языке Assebler , которая считывает текстовый файл со...

Заменить в исходном файле четные буквы слов на прописные
добрый день) Программу надо сделать на языке Assembler 1. открытие исходного файла (функция...

Заменить в исходном файле русские буквы ‘к’ на буквы ‘т’, буквы ‘т’ на буквы ‘к’, буквы ‘л’ на буквы ‘в’, буквы ‘в’ на
Задание: Заменить в исходном файле русские буквы ‘к’ на буквы ‘т’, буквы ‘т’ на буквы ‘к’, буквы...

Обмен в исходном файле соседних слов местами
Всех приветствую! Прошу помочь в написании программы на Ассемблере,которая меняет ближние слова...

16
Модератор
Эксперт по электронике
8475 / 4334 / 1642
Регистрация: 01.02.2015
Сообщений: 13,455
Записей в блоге: 8
22.10.2017, 15:55 2
kristinka_15, само задание - несложное, но при реализации на ассемблере выльется в несколько сот строк. Там вся соль в том, что слово может оказаться частью в одном буфере, частью в следующем. Решение - буферизация ввода и вывода, т.е. реализация аналога сишных fread и fwrite.

Т.е. без вашего личного участия - не обойтись.

Нужно будет организовать 2 буфера - один для чтения, другой для записи - иначе разделённое слово невозможно будет корректно записывать.

Добавлено через 10 минут
Я когда-то начинал, но не закончил запись в файл - она осталась неправильной, хотя с той задачей справлялась
В текстовом файле переписать символы каждой строки в обратном порядке
Чтение из файла, перевод строки в число

Добавлено через 13 часов 17 минут
kristinka_15, что-то сообщения потёрлись, поэтому ещё раз повторю.
Соберите программку на простом C, которая будет решать задачу. И эту программу можно будет транслировать в асм. Я прикинул, она будет очень похожа на приведённую по первой ссылке.
0
593 / 390 / 70
Регистрация: 29.03.2013
Сообщений: 813
22.10.2017, 16:15 3
Цитата Сообщение от ФедосеевПавел Посмотреть сообщение
Там вся соль в том, что слово может оказаться частью в одном буфере, частью в следующем.
Там же написано:
Цитата Сообщение от kristinka_15 Посмотреть сообщение
Размер исходного файла для обработки выбрать меньшим или равным размеру буфера.
1
Модератор
Эксперт по электронике
8475 / 4334 / 1642
Регистрация: 01.02.2015
Сообщений: 13,455
Записей в блоге: 8
22.10.2017, 18:28 4
Argogo, спасибо. Невнимательно прочёл условие, как-то сразу начал мысленно тестировать его на слабые места. Просто, доводилось парсить log на unicode, а для ускорения делать самостоятельную буферизацию (правда, на ЯВУ). И теперь всех подталкиваю на этот пагубный путь.

А раз так, то получается ерунда, в одно действие считывается один единственный буфер, обрабатывается и тут же сохраняется.-

Добавлено через 54 минуты
Так, без обработки строк файла - т.е. исходный файл просто копируется в результирующий. Осталось создать обработчик строк (строки)
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
_TEXT   segment word    public  'CODE'
        assume  cs:_TEXT, ds:_TEXT, ss:_TEXT
        org     100h
start:
        ;1.     открытие исходного файла (функция 3DH);
        mov     ah,     3Dh
        mov     al,     00h             ;открыть для чтения
        lea     dx,     InFileName
        int     21h
        jnc     @@InFileOpenOk
        mov     ah,     09h
        lea     dx,     errFileOpen
        int     21h
        jmp     @@Exit
@@InFileOpenOk:
        mov     InFileHandler,  ax
        ;2.     создание нового файла, куда будут помещаться результаты
        ;обработки исходного файла (функция 3CH);
        mov     ah,     3Ch             ;открыть для записи
        mov     cx,     00h             ;атрибут файла - обычный файл
        lea     dx,     OutFileName
        int     21h
        jnc     @@OutFileOpenOk
        mov     ah,     09h
        lea     dx,     errFileOpen
        int     21h
        jmp     @@CloseInFileAndExit
@@OutFileOpenOk:
        mov     OutFileHandler, ax
        ;3.     чтение исходного файла (функция 3FH);
        mov     ah,     3Fh
        mov     bx,     InFileHandler
        mov     cx,     SizeBuffer
        lea     dx,     FileBuffer
        int     21h
        jnc     @@InFileReadOk
        mov     ah,     09h
        lea     dx,     errFileRead
        int     21h
        jmp     @@CloseOutFileAndExit
@@InFileReadOk:
        mov     BufLength,      ax
        ;4.     обработка прочитанных данных;
        ;5.     запись обработанных данных в созданный файл (функция 40H);
        mov     ah,     40h
        mov     bx,     OutFileHandler
        mov     cx,     BufLength
        lea     dx,     FileBuffer
        int     21h
        ;6.     закрытие файла с результатами обработки (функция 3EH);
@@CloseOutFileAndExit:
        mov     ah,     3Eh
        mov     bx,     OutFileHandler
        int     21h
        jnc     @@Exit
        mov     ah,     09h
        lea     dx,     errFileClose
        int     21h
        ;7.     закрытие исходного файла (функция 3EH).
@@CloseInFileAndExit:
        mov     ah,     3Eh
        mov     bx,     InFileHandler
        int     21h
        jnc     @@Exit
        mov     ah,     09h
        lea     dx,     errFileClose
        int     21h
@@Exit:
        int     20h
;-----------------------------------------------------------------------
; данные
;-----------------------------------------------------------------------
        ;---------------------------------------------------------------
        ;сообщения программы
        ;---------------------------------------------------------------
        errFileOpen     db      0Dh, 0Ah, 'File open error', '$'
        errFileClose    db      0Dh, 0Ah, 'File close error', '$'
        errFileRead     db      0Dh, 0Ah, 'File read error', '$'
        CrLf            db      0Dh, 0Ah, '$'
        ;---------------------------------------------------------------
        ;файлы
        ;---------------------------------------------------------------
        InFileName      db      'InFile.txt', 0
        OutFileName     db      'OutFile.txt', 0
        InFileHandler   dw      ?
        OutFileHandler  dw      ?
        BufLength       dw      ?               ;количество байт, реально
                                                ;считанное из файла
        FileBuffer      db      512 dup(?)
        SizeBuffer      equ     $-FileBuffer
_TEXT   ends
 
        end     start
Добавлено через 6 минут
Осталось обработать строки в буфере.
Предположим (т.к. об этом нет в задании), что исходный (а следовательно и итоговый) файл содержит одну строку, в которой слова разделены пробелами и нет даже переводов строк - т.е. файл представляет из себя длинную строку.

Тогда, можете воспользоваться алгоритмом выделения по ссылкам
В строке в словах с четным номером изменить порядок букв на обратный
Количество слов, содержащих более 3-х символов

Добавлено через 17 минут
Обработка
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
        ;4.     обработка прочитанных данных;
        lea     si,     FileBuffer
        mov     cx,     BufLength
        ;пропускаем все разделители
@@WhileDelimiter:
        mov     al,     [si]
        cmp     al,     DelimChar
        jne     @@NewWord
        inc     si
        loop    @@WhileDelimiter
 
        jcxz    @@Finish        ;если строка закончилась - выйти
        ;найдено новое слово
@@NewWord:
        mov     dx,     0       ;длина очередного слова пока равна 0
        mov     di,     si      ;сохраняем индекс (адрес) начала очередного слова
        ;пропускаем все буквы слова до разделителя
@@WhileWord:
        mov     al,     [si]
        cmp     al,     DelimChar
        je      @@Break
        inc     dx              ;увеличиваем длину слова
        inc     si              ;переходим к следующему символу
        loop    @@WhileWord
@@Break:
    ;обрабатываем найденное слово
    push    si
    dec si
    shr dx, 1
    jz  @@NoReverse
    @@ReverseChars:
        mov al, [si]
        xchg    al, [di]
        mov [si],   al
        inc di
        dec si
        dec dx
    jnz @@ReverseChars
@@NoReverse:
    pop si
        jcxz    @@Finish
        jmp     @@WhileDelimiter
@@Finish:
1
0 / 0 / 0
Регистрация: 22.10.2017
Сообщений: 29
23.10.2017, 19:53  [ТС] 5
ФедосеевПавел, ничего не понятно... особенно что такое @@...
0
Модератор
Эксперт по электронике
8475 / 4334 / 1642
Регистрация: 01.02.2015
Сообщений: 13,455
Записей в блоге: 8
23.10.2017, 21:13 6
Сначала я набрал каркас программы - открытие файлов, чтение буфера, запись буфера, закрытие файлов - никакой обработки.

Зато компилируется а при выполнении копирует содержимое файла.

Потом посидел, подумал и набрал 4-й пункт - обработку файла. Но не стал публиковать весь текст, а только сам 4-й пункт.

Попробуйте запустить шаблонную программу, а потом скопируйте и вставьте в неё дополнение. Это будет ваше готовое задание.

Символы @@ я добавляю для локальных меток - которые не должны быть видны за пределами данной процедуры. Но такое действует только в TASM и при добавлении специальной директивы. А добавляю - скорее, по инерции - можете удалить их во всём тексте.
1
0 / 0 / 0
Регистрация: 22.10.2017
Сообщений: 29
23.10.2017, 21:59  [ТС] 7
ФедосеевПавел, DelimChar есть в обработке... но его задания я не нашла..
и можете пожалуйста либо кратко объяснить как что вы делаете в обработке...либо комментарии по дописать, пожалуйста если не сложно а то до конца не доходит просто...

Добавлено через 22 минуты
ФедосеевПавел, проще говоря DelimChar не определён...
0
Модератор
Эксперт по электронике
8475 / 4334 / 1642
Регистрация: 01.02.2015
Сообщений: 13,455
Записей в блоге: 8
23.10.2017, 22:09 8
DelimChar
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
;-----------------------------------------------------------------------
; данные
;-----------------------------------------------------------------------
        ;---------------------------------------------------------------
        ;сообщения программы
        ;---------------------------------------------------------------
        errFileOpen     db      0Dh, 0Ah, 'File open error', '$'
        errFileClose    db      0Dh, 0Ah, 'File close error', '$'
        errFileRead     db      0Dh, 0Ah, 'File read error', '$'
        CrLf            db      0Dh, 0Ah, '$'
        ;---------------------------------------------------------------
        ;обрабатываемая строка
        ;---------------------------------------------------------------
        DelimChar       db      ' '             ;символ разделитель слов
                                                ;в строке
        ;---------------------------------------------------------------
        ;файлы
        ;---------------------------------------------------------------
        InFileName      db      'InFile.txt', 0
        OutFileName     db      'OutFile.txt', 0
        InFileHandler   dw      ?
        OutFileHandler  dw      ?
        BufLength       dw      ?               ;количество байт, реально
                                                ;считанное из файла
        FileBuffer      db      512 dup(?)
        SizeBuffer      equ     $-FileBuffer
В обработке выделяю слова.
Общий принцип
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
  repeat
    {пропускаем разделители - их может быть несколько подряд}
    while s[i]=DelimChar do
      i:=i+1;
    Istart:=i; {Istart - индекс начала слова}
    {пропускаем символы слова}
    while i<>DelimChar do
      i:=i+1;
    {теперь есть индекс Istart - начала слова, (i-1) - конца слова
     зная их, нужно обменять символы в позиции Istart с (i-1) и т.д.}
    for j:=1 to ((i-1)-Istart)/2 do
      swap(s[j+Istart-1], s[i-j])
  until в буфере нет символов
1
0 / 0 / 0
Регистрация: 22.10.2017
Сообщений: 29
23.10.2017, 22:18  [ТС] 9
ФедосеевПавел, сначала гонит по строке, пропуская разделители, потом берет начало слова...и пока начало слова (или i) <> разделителя ...увеличивает i на один. В итоге у него появляется индекс начала слова и конца слова. Далее зная их он меняет символы , делая их задом на перёд, до того момента пока в буфере не закончатся все символы, так? я правильно поняла?оО
0
Модератор
Эксперт по электронике
8475 / 4334 / 1642
Регистрация: 01.02.2015
Сообщений: 13,455
Записей в блоге: 8
23.10.2017, 22:27 10
Да, поняли вы правильно. В псевдокоде не всё учтено в целях упрощения понимания, но в реальном коде проверок несколько больше - всё время проверяется ситуация "конец строки (буфера)".

И терминология "гонит по строке" - нечто.

В ссылках, которые привёл ранее я делал пояснения по выделению слов в строке (буфере) - можете и там почитать.
1
0 / 0 / 0
Регистрация: 22.10.2017
Сообщений: 29
23.10.2017, 22:42  [ТС] 11
ФедосеевПавел, спасибо огромнейшее
0
Модератор
Эксперт по электронике
8475 / 4334 / 1642
Регистрация: 01.02.2015
Сообщений: 13,455
Записей в блоге: 8
23.10.2017, 22:50 12
Вы, таки, разобрались и сможете выделять слова не только в асме, но и на С/Pascal/BASIC ?
Ну всё, вы - хакер!
1
0 / 0 / 0
Регистрация: 22.10.2017
Сообщений: 29
23.10.2017, 23:23  [ТС] 13
ФедосеевПавел, я еще завтра до разбираю))
кстати я правильно поняла, что это ведь использование директив: _TEXT segment word public 'CODE'
assume cs:_TEXT, ds:_TEXT, ss:_TEXT ?
0
Модератор
Эксперт по электронике
8475 / 4334 / 1642
Регистрация: 01.02.2015
Сообщений: 13,455
Записей в блоге: 8
24.10.2017, 06:58 14
Да.
Можете упрощённо
_TEXT segmentТо мне на глаза попалась какая-то статья
1
0 / 0 / 0
Регистрация: 22.10.2017
Сообщений: 29
24.10.2017, 21:20  [ТС] 15
ФедосеевПавел, а можно еще уточнить, зачем вот эта строчка: SizeBuffer equ $-FileBuffer ?
0
Модератор
Эксперт по электронике
8475 / 4334 / 1642
Регистрация: 01.02.2015
Сообщений: 13,455
Записей в блоге: 8
24.10.2017, 22:55 16
Символ $ это текущий адрес. Кстати FileBuffer это не просто символы, это адрес переменной.
Тогда, $-FileBuffer начинает напоминать разницу индексов (Ifinish+1)-Istart что соответствует длине (размеру в байтах) переменной FileBuffer - т.е. буфера.

Иногда новички переделывают программы с форума и перемещают выражение $-FileBuffer в другое место и программы перестают работать. Потому, что $ - это текущий адрес. Кроме того, символ $ можно использовать многократно в программе.
Assembler
1
2
3
4
5
6
7
a dw 5
b db 10 dup(0)
c dw $-b;  длина буфера b
d dw $-a; размер переменных a, b, c вместе взятых, т.е. d=2+10+2=14
e dw $  ;в e адрес переменной e. Сам адрес (значение) станет известен после компиляции.
f dw $-b; несмотря на то, что выражение похоже на переменную c, в этой
          ;переменной будет длина переменных b, c, d, e вместе взятых
Вроде понятно объяснил.
Вобще-то это есть в учебнике по синтаксису tasm.

Добавлено через 4 минуты
Конкретно в программе константа FileBuffer нужна один раз при чтении из файла. Можно было бы сразу указать 512, но при изменении размера буфера пришлось бы искать и заменять 512 на новое значение. А так - всё в символах.
0
3406 / 1825 / 489
Регистрация: 28.02.2015
Сообщений: 3,696
25.10.2017, 12:03 17
Цитата Сообщение от kristinka_15 Посмотреть сообщение
SizeBuffer equ $-FileBuffer
Компилятор считает разницу текущего адреса ($) и адреса (FileBuffer), и каждый раз в местах, где встретится SizeBuffe будет подставлено это значение.
1
25.10.2017, 12:03
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
25.10.2017, 12:03
Помогаю со студенческими работами здесь

Заменить в исходном файле буквы слов-палиндромов на прописные
Заменить в исходном файле буквы слов-палиндромов на прописные.

Заменить в исходном файле буквы слов-палиндромов на прописные
Заменить в исходном файле буквы слов-палиндромов на прописные Имя исходного и обработанного...

В исходном текстовом файле первое слово поменять местами со вторым
Ребята, нужна помощь. Только начал изучать, помогите. как в си реализовать такую задачу. В...

В исходном текстовом файле поменять местами первое с последним словом в тексте
Помогите, пожалуйста) В исходном текстовом файле поменять местами первое с последним словом в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru