Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [Ассемблер] Вырезать спецсимволы из строки 
V
    Опции темы
InviZible
Дата 22.4.2007, 18:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 63
Регистрация: 13.9.2006

Репутация: нет
Всего: нет



Как можно вырезать спецсимволы (цифры,знаки,точки,запятые и т.д.) из строки,заменив их пробелами, и установить указатель на последнию букву в строке?
Т.е. дано:

@qwe@!$#%^WCe%^yX36E^@">Q@5

выход:
qwe WCe yX E Q

Желательно на tasm'e и без цепочечных операций. Могу выложить, то что у меня получилось
Заранее спасибо.

Это сообщение отредактировал(а) InviZible - 22.4.2007, 18:14
PM MAIL   Вверх
JAPH
Дата 22.4.2007, 20:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 312
Регистрация: 8.1.2007
Где: Ленобласть

Репутация: 12
Всего: 23



Выложите, плиз. Зачем дублировать вопросы на русфаке? (Не в первый раз замечаю)
В чём сложность? Сравнение кодов символов? Проход по строке?

Кстати, уточните - @# заменяется на один или два пробела?


--------------------
Что непонятно - спрашиваем smile
PM MAIL ICQ   Вверх
InviZible
Дата 22.4.2007, 20:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 63
Регистрация: 13.9.2006

Репутация: нет
Всего: нет



Код

....
    mov ah,0ah
    lea dx,strg
    int 21h
    xor ah,ah
    mov al,rsize
    lea si,buff
    add si,ax
    mov byte ptr[si],'$'
    dec si
    mov temp_di,si
    mov cx,si
    mov al,' '
    inc si
spec:                 ;Вот тут начинаю вырезать
    dec si
    cmp si,offset rsize
    jz find_space
    mov bl,[si]
    cmp bl,'z'
    jg del
    cmp bl,'A'
    jl del
    jmp  kon
del:    mov [si],al
kon:    loop spec

....


> Зачем дублировать вопросы на русфаке? (Не в первый раз замечаю)
Дело в том, что из 3-х мест отвечают в 1-м

> В чём сложность? Сравнение кодов символов? Проход по строке?
Не могу вырезать то, что между 'Z' и 'a'. 

> Кстати, уточните - @# заменяется на один или два пробела?
Хотелось бы посмотреть на оба варианта. Предпочтительней на 1.

Спасибо за помощь
PM MAIL   Вверх
JAPH
Дата 22.4.2007, 22:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 312
Регистрация: 8.1.2007
Где: Ленобласть

Репутация: 12
Всего: 23



Я ещё ничем не помог, а уже поблагодарили. Хм... smile

Начнём с простого. @# заменяются на два пробела
Код

        .486
dseg    segment use16
strn    db      0040h dup (0)
crlf    db      0Dh, 0Ah
dseg    ends
cseg    segment use16
        assume  cs: cseg, ds: dseg, ss: sseg
@:      mov     ax, dseg
        mov     ds, ax
        ; Вводим строку
        mov     ah, 3Fh
        mov     cx, 0040h
        xor     dx, dx
        xor     bx, bx
        int     21h
        ; Заменяем сиволы перевода каретки нулями
        mov     di, ax
        sub     di, 2
        mov     word ptr [di], 0
        ; Получаем длину строки в CX
        mov     cx, di
        xor     di, di
        ; Проходим по строке. Проверяем сиволы на принадлежность 'A'..'Z','a'..'z'
        ; Пробел считаем неподходящим - заменим его на пробел
@1:     cmp     byte ptr [di], 'A'
        jb      short @cut
        cmp     byte ptr [di], 'Z'
        jbe     short @OK
        cmp     byte ptr [di], 'a'
        jb      short @cut
        cmp     byte ptr [di], 'z'
        jbe     short @OK
        ; Не подошёл - вырезаем
@cut:   mov     byte ptr [di], ' '
@OK:    inc     di
        loop    @1
        ; Выводим то, что получилось, плюс переводим строку
        mov     ah, 40h
        mov     cx, 0042h
        int     21h
        mov     ax, 4C00h
        int     21h
cseg    ends
sseg    segment use16 stack
        db      0400h dup (0)
sseg    ends
        end     @


Ну а теперь напрягаемся. Случай со слипанием пробелов. Советую посмотреть работу в отладчике, одних комментов тут маловато.
Код

        .486
dseg    segment use16
strn    db      0040h dup (0)
crlf    db      0Dh, 0Ah
dseg    ends
cseg    segment use16
        assume  cs: cseg, ds: dseg, ss: sseg
@:      mov     ax, dseg
        mov     ds, ax
        ; Начало такое же
        mov     ah, 3Fh
        mov     cx, 0040h
        xor     dx, dx
        xor     bx, bx
        int     21h
        mov     di, ax
        sub     di, 2
        mov     word ptr [di], 0
        mov     cx, di
        xor     di, di
        mov     si, di
        ; Теперь самое сложное. Идея:
        ; DI проходит по исходной строке в поиске небукв
        ; SI записывает новую строку прямо поверх старой
        ; По BP мы определим, вставили ли мы пробел вместо небуквы или нет
        ; Изначально не вставили
        mov     bp, offset @ins
        ; Итак. Берём символ
@1:     mov     al, [di]
        ; Смотрим, подходит ли он
        cmp     al, 'A'
        jb      short @cut
        cmp     al, 'Z'
        jbe     short @OK
        cmp     al, 'a'
        jb      short @cut
        cmp     al, 'z'
        ja      short @cut
        ; Если подходит, то сбрасываем BP, тем самым говоря,
        ; что вместо следующей партии закорючек
        ; нужно будет вставить новый пробел
@OK:    mov     bp, offset @ins
        ; Записываем правильный символ в новую строку
        mov     [si], al
        ; Сдвигаем указатель новой строки
        inc     si
        ; Идём дальше
        jmp     short @next
        ; Если закорючка
@cut:   jmp     bp
        ; Сюда прыгаем, если надо вставлять пробел
@ins:   mov     bp, offset @next
        ; Говорим, что уже вставили, т.е. если дальше подряд
        ; пойдут закорючки, мы пропустим @ins
        ; Собственно записываем пробел в новую строку
        mov     byte ptr [si], ' '
        inc     si
        ; В любом случае сдвигаем указатель старой строки
@next:  inc     di
        loop    @1
        ; Далее, SI в общем случае < DI, так что
        ; у новой строки остался хвост от старой
        ; Надо бы его репрессировать
        mov     cx, 0040h
        sub     cx, si
        xor     al, al
@2:     mov     [si], al
        inc     si
        loop    @2
        ; Выводим результат
        mov     ah, 40h
        mov     cx, 0042h
        int     21h
        mov     ax, 4C00h
        int     21h
cseg    ends
sseg    segment use16 stack
        db      0400h dup (0)
sseg    ends
        end     @


Ну что ж, будут вопросы - задавайте. Но это уже завтра smile


Это сообщение отредактировал(а) JAPH - 22.4.2007, 22:10


--------------------
Что непонятно - спрашиваем smile
PM MAIL ICQ   Вверх
InviZible
Дата 23.4.2007, 19:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 63
Регистрация: 13.9.2006

Репутация: нет
Всего: нет



Спасибо, я решил данный вопрос

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.0454 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.