Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Отчет по чему-то

.doc
Скачиваний:
5
Добавлен:
20.05.2014
Размер:
62.46 Кб
Скачать

МИХЕЙ

А6. выделить подстроку заключенную между (самыми внешними) круглыми скобками.

Разместить символы подстроки в обратном порядке и найти ее длину,а также

номера позиций внешнимих круглых скобок.

(*строка пуста*,*в строке нет открывающей круглой скобки*,

*в строке нет закрывающей круглой скобки*,*порядок скобок перепутан*)

A6VMIXEY.C

#include <stdio.h>

#include <windows.h>

#define MAX_SIZE 100 /* Предельная длина строки */

UINT ParseString( LPSTR, LPSTR, UINT*, UINT* );

INT user_errno;

CHAR old_str[MAX_SIZE];

CHAR new_str[MAX_SIZE];

static CHAR* message[]={ "Строка пуста",

"в строке нет открывающей круглой скобки",

"в строке нет закрывающей круглой скобки",

"порядок скобок перепутан"};

int main(int argc, char** argv)

{

CHAR text[MAX_SIZE];

UINT substring_len;

UINT first_bracket_pos;

UINT last_bracket_pos;

FILE* fp;

user_errno = 0;

CharToOem("Введите строку", text);

puts(text);

gets(old_str);

if( argc > 1 )

{

if ( (fp = fopen(argv[1], "a")) == NULL )

{

CharToOem("Невозможно открыть файл %s\n", text);

fprintf(stderr, text, argv[1]);

return 1;

}

CharToOem("Строка: %s\n", text);

fprintf( fp, text, old_str );

}

substring_len = ParseString( old_str, new_str, &first_bracket_pos, &last_bracket_pos );

if( !user_errno )

{

CharToOem( "\nНовая строка: %s\nПозиции скобок ( и ): %u %u\nДлина подстроки %u\n\n", text );

printf( text, new_str, first_bracket_pos, last_bracket_pos, substring_len );

if( argc > 1)

{

fprintf( fp, text, new_str, first_bracket_pos, last_bracket_pos, substring_len );

fclose( fp );

}

getchar();

return 0;

}

else

{

puts("\n");

CharToOem( message[ user_errno - 1], text);

puts(text);

if( argc > 1)

{

CharToOem("Ошибка: ", text);

fputs(text, fp);

CharToOem(message[ user_errno - 1], text);

fputs(text, fp);

fputs("\n\n", fp);

fclose(fp);

}

getchar();

return user_errno;

}

}

A6VMIXEY.asm

.386

.MODEL flat,C

EXTRN user_errno: SDWORD

PUBLIC ParseString

.CODE

;-----------------------------------------------------------;

; Процедура обработки строки ;

; ВХОД ;

; old_str - указатель на исходную строку ;

; new_str - указатель на место под новую строку ;

; first_br_pos - указатели на переменные в которые ;

; last_br_pos будут записаны позиции скобок ;

; ВЫХОД: ;

; EAX( возвращаемое значение ) - длина строки между ;

; внешними скобками ;

; Рабочие( используемые ) регистры: ;

; ECX - счётчик ;

; EDX - длина строки ;

; EDI - адрес исходной строки ;

; ESI - адрес новой (под)строки ; ;

; BL - позиция первой/последней скобки ( ( временно ) ;

; BH - позиция первой/последней скобки ) ( временно ) ;

;-----------------------------------------------------------;

ParseString PROC C old_str:DWORD, new_str:DWORD, \

first_br_pos:DWORD, last_br_pos:DWORD

LOCAL str_len ; Длина строки

LOCAL first_br ; Позиция первой скобки

LOCAL last_br ; Позиция последней скобки

cld ; Поиск в направлении возрастания адресов

; Определение длины строки

mov ecx, -1 ; В ECX - максимальное беззнаковое целое

mov edi, old_str ; В EDI - адрес строки

mov al, 0 ; В AL - терминатор строки

repne scasb ; Поиск конца строки

not ecx ; В ECX -

dec ecx ; длина строки

test ecx, ecx ; Если ECX = 0

jz err1 ; - на err1

mov str_len, ecx ; Сохраняем длину строки

; Поиск первых скобок

; Поиск первой скобки (

mov edi, old_str ; В EDI - адрес строки

mov al, '(' ; Символ для поиска

mov ecx, str_len ; Длина строки

repne scasb ; Ищем

jne err2 ; Если ZF=0, то символ ( не найден

mov bl, cl ; Сохраняем позицию найденного символа

; Поиск первой скобки )

mov edi, old_str ; Берём адрес строки

mov al, ')' ; Символ для поиска

mov ecx, str_len ; Длина строки

repne scasb ; Ищем

jne err3 ; Если ZF=0, т осимвол ) не найден

mov bh, cl ; Сохраняем позицию найденного символа

cmp bh, bl ; Сравниваем позиции первых скобок

jg err4 ; Если первая скобка ) то порядок скобок перепутан

mov ah, bl ; Сохраняем в AH позицию первой скобки

; Поиск последних скобок

std ; Теперь ищем с конца

; Поиск последней скобки (

mov edi, old_str ; Вычисляем

add edi, str_len ; указатель

dec edi ; на конец строки

mov al, '(' ; Символ для поиска

mov ecx, str_len ; Длина строки

repne scasb ; Ищем

jne err2 ; Если ZF=0, то символ ( не найден

mov bl, cl ; Сохраняем позицию найденного символа

; Поиск последней скобки )

mov edi, old_str ; Вычисляем

add edi, str_len ; указатель

dec edi ; на конец строки

mov al, ')' ; Символ для поиска

mov ecx, str_len ; Длина строки

repne scasb ; Ищем

jne err3 ; Если ZF=0, т осимвол ) не найден

mov bh, cl ; Сохраняем позицию найденного символа

cmp bh, bl ; Сравниваем позиции последних скобок

jl err4 ; Если последняя скобка ( то порядок скобок перепутан

; Подготовка к копированию

movzx eax, ah ; Расширяем до 32 бит

mov edx, str_len ; Вычисляем и сохраняем

sub edx, eax ; позицию

mov first_br, edx ; первой скобки

movzx eax, bh ; Расширяем до 32 бит

inc eax ; Вычисляем и сохраняем позицию

mov last_br, eax ; последней скобки

cld ; Копируем строку слева направо

; Копируем начало строки

mov ecx, first_br ; Берём длину первого куска

mov esi, old_str ; Откуда копировать

mov edi, new_str ; Куда копировать

rep movsb ; Копируем

; Копируем подстроку между скобками в обратном порядке

mov ecx, last_br ; Вычисляем

sub ecx, first_br ; длину подстроки

dec ecx ; между скобками

add edi, ecx ; Устанавливаем указатель

dec edi ; на конец подстроки

r_cpy:

lodsb ; Загружаем символ в AL

std ; Сохранять будем в обратном порядке

stosb ; Сохраняем

cld ; Меняем направление

loop r_cpy ; Повторяем для всей подстроки

; Копируем конец строки

mov ecx, str_len ; Вычисляем длину куска

sub ecx, last_br ; начиная с последней

inc ecx ; скобки

mov edi, new_str ; Вычисляем

add edi, last_br ; куда

dec edi ; копировать

rep movsb ; Копируем

; Закончили копировать

mov esi, first_br_pos ; Берём адрес переменной

mov eax, first_br ; Берём позицию первой скобки

mov [esi], eax ; Сохраняем

mov esi, last_br_pos ; Берём адрес переменной

mov eax, last_br ; Берём позицию последней скобки

mov [esi], eax ; Сохраняем в неё позицию последней скобки

mov eax, last_br ; Оставляем в EAX

sub eax, first_br ; размер

dec eax ; подстроки

ret

IRPC I,1234

err&I: mov user_errno, I

ret

ENDM

ParseString ENDP

END

protocol.txt

Строка: bweyfgwejfg

Ошибка: в строке нет открывающей круглой скобки

Строка: fewufg(fhiuwffue

Ошибка: в строке нет закрывающей круглой скобки

Строка: efhiwue(kfuehwifu(hfeuwf

Ошибка: в строке нет закрывающей круглой скобки

Строка: fhewfh(fjief)()()fjeifj(feif

Ошибка: порядок скобок перепутан

Строка: efuie(fefowfho)fjeoifwi

Новая строка: efuie(ohfwofef)fjeoifwi

Позиции скобок ( и ): 6 15

Длина подстроки 8

Строка: ()))()(()()(()())

Новая строка: ()()(()()(()())))

Позиции скобок ( и ): 1 17

Длина подстроки 15

размер кода программы

Start Length Name Class

0002:00000000 00014e89H .text CODE

адрес переменной user_errno

из карты памяти

Address Publics by Value Rva+Base Lib:Object

0004:000018f4 _user_errno 0042b8f4 <common>

из дебаггера

&user_errno 0x0042b8f4 _user_errno int *

стековый кадр

ESP 0x0012FD40 00000007 - last_br

EBP-8 0x0012FD44 00000003 - first_br

EBP-4 0x0012FD48 0000000b - str_len

EBP 0x0012FD4C 0012fedc - старое EBP

EBP+4 0x0012FD50 00411c44 - адрес возврата из ParseString

EBP+8 0x0012FD54 0042b900 - old_str

EBP+C 0x0012FD58 0042b860 - new_str

EBP+10 0x0012FD5C 0012fe5c - first_br_pos

EBP+14 0x0012FD60 0012fe50 - last_br_pos

Соседние файлы в предмете Статистика