Преобразовать строку так, чтобы после каждой точки был пробел, и следующая встречающаяся буква была прописная. - Assembler

Узнай цену своей работы

Формулировка задачи:

Задана строка минимум 30 любых отображаемых символов, содержащая несколько точек. Преобразовать строку так, чтобы после каждой точки был пробел, и следующая встречающаяся буква была прописная. Элементы строки должны вводиться с клавиатуры. Результат работы – преобразованную строку символов - необходимо вывести на экран. Обмен информацией с пользователем организовать в виде специальных сообщений, каждое из которых следует размещать в отдельной строке экрана.

Решение задачи: «Преобразовать строку так, чтобы после каждой точки был пробел, и следующая встречающаяся буква была прописная.»

textual
Листинг программы
LOCALS
 
.model small
 
.stack 100h
 
.data
        msgInStr        db      'Введите строку, длиной не менее 30 отображаемых символов:', 0Dh, 0Ah, '$'
        msgResStr       db      'Строка после обработки:', 0Dh, 0Ah, '$'
        msgShortStr     db      'Длина строки должна быть не менее 30 отображаемых символов.', 0Dh, 0Ah, '$'
        CrLf            db      0Dh, 0Ah, '$'
 
        kbdBuf          db      80
        StrLen          db      0
        String          db      81 dup(?)
.code
 
main    proc
        mov     ax,     @data
        mov     ds,     ax
 
        ;ввод строки
@@GetString:
        mov     ah,     09h
        lea     dx,     msgInStr
        int     21h
        mov     ah,     0Ah
        lea     dx,     kbdBuf
        int     21h
        mov     ah,     09h
        lea     dx,     CrLf
        int     21h
        cmp     StrLen, 30
        jae     @@ProcessString
        mov     ah,     09h
        lea     dx,     msgShortStr
        int     21h
        jmp     @@GetString
 
@@ProcessString:
        ;обработка строки
        push    es
        push    ds              ;настроить регистр сегмента es для строковых операторов
        pop     es
        lea     si,     String  ;ds:si - адрес строки
        lea     di,     StrLen  ;ds:di - адрес байта длины строки
        mov     cx,     0       ;cx - длина строки
        mov     cl,     StrLen
        mov     ah,     0       ;признак необходимости преобразования символа к прописному
@@For:
        lodsb
        cmp     al,     '.'
        jne     @@IsUpCaseRequired
        ;если встретилась точка:
        ; - установить признак, что следующий символ должен быть прописным
        ; - проверить, не последний ли это символ в строке.
        ; - проверить наличие пробела после точки
        ; - если пробела нет - вставить
        mov     ah,     1       ;следующий символ необходимо слелать прописным
        cmp     cx,     1       ;это последний символ в строке?
        je      @@Next
        cmp     [si],   byte ptr ' '    ;следующий символ - пробел?
        je      @@Next
        ;вставка пробела
        ;перемещение строки вправо на 1 символ
        push    ax
        push    cx
        push    si
        push    di
        pushf
 
        add     si,     cx
        sub     si,     2
        mov     di,     si
        add     di,     1
        sub     cx,     1
        std
        rep     movsb
 
        popf
        pop     di
        pop     si
        pop     cx
        pop     ax
        ;после точки вставить пробел
        mov     [si],   byte ptr ' '
        ;увеличение длины
        inc     byte ptr[di]
        add     si,     1       ;пропустить пробел при рассмотрении следующего символв
        jmp     @@Next
 
@@IsUpCaseRequired:
        test    ah,     1       ;если требуется сделать символ прописным
        jz      @@Next
        mov     ah,     0
        call    UpCaseChar
        mov     [si-1], al
@@Next:
        loop    @@For
 
        mov     [si],   byte ptr '$'
        pop     es
 
        ;вывод результата
        mov     ah,     09h
        lea     dx,     msgResStr
        int     21h
        mov     ah,     09h
        lea     dx,     String
        int     21h
 
        mov     ax,     4C00h
        int     21h
main    endp
 
UpCaseChar      proc
        cmp     al,     'a'
        jb      @@Exit
        cmp     al,     'z'
        ja      @@Exit
        add     al,     'A'-'a'
@@Exit:
        ret
UpCaseChar      endp
 
end     main

Объяснение кода листинга программы

  1. Объявляются переменные: a. msgInStr - строка для вывода пользователю с просьбой ввести строку b. msgResStr - строка для вывода обработанной строки c. msgShortStr - строка для вывода предупреждения о короткой длине строки d. CrLf - переменная для перехода на новую строку e. kbdBuf - буфер для ввода строки f. StrLen - переменная для хранения длины строки g. String - массив символов для хранения введенной строки
  2. Процедура main начинается: a. Инициализируется сегмент данных и регистр данных b. Ввод строки с проверкой её длины c. Если длина строки менее 30 символов, выводится предупреждение d. Иначе начинается обработка строки
  3. В процедуре обработки строки: a. Происходит установка сегмента данных и регистра в ES для строковых операций b. Последовательно для каждого символа проверяется: i. Если символ - точка, то:
    • Флаг устанавливается на необходимость преобразования следующего символа в верхний регистр
    • Проверяется, не последний ли это символ в строке
    • Проверяется наличие пробела после точки, и если его нет, вставляется
    • Длина строки увеличивается ii. Если символ не точка, проверяется, нужно ли его преобразовать в верхний регистр, и если нужно, происходит преобразование
  4. Выводится обработанная строка
  5. Процедура main завершается
  6. Процедура UpCaseChar просто преобразует символ в верхний регистр, если он это уже не так
  7. Программа завершается вызовом функции завершения программы.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

6   голосов , оценка 4.167 из 5
Похожие ответы