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

Лабораторная работа №2 Вариант 10

.doc
Скачиваний:
16
Добавлен:
20.06.2014
Размер:
164.35 Кб
Скачать

2

ФЕДЕРАЛЬНОЕ АГЕНТСТВО ПО ОБРАЗОВАНИЮ

ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ

ВЫСШЕГО ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ

ЛИПЕЦКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ

КАФЕДРА АВТОМАТИЗИРОВАННЫХ СИСТЕМ УПРАВЛЕНИЯ

Лабораторная работа №2

по дисциплине

«Операционные системы»

на тему:

«Реализация интерпретатора командной строки»

Студент

Филатов А.А.

подпись, дата

фамилия, инициалы

Группа

АС-09-1

Принял

Журавлева М.Г.

ученая степень, звание

подпись, дата

фамилия, инициалы

Липецк 2011

1.Задание

Реализовать на языке C/C++ интерпретатор командной строки (shell) для ОС Windows.

Вариант 10. Написать программу попарного переименования файлов, названия которых заданы первыми 2n параметрами командной строки (1  n  4), и вывода всех строк полученных файлов, соответствующих шаблону, заданному последним 2n+1-ым параметром командной строки. Все файлы, заданные нечетными параметрами, необходимо переименовать соответственно в файлы, заданные четными параметрами (без учета названия программы).

2.Алгоритм

1. Считываем команду.

2. Анализируем ее – при совпадении символов, использующихся для обозначения перенаправления, изменяем потоки ввода-вывода на введенные.

3. Для выполнения функции считываем аргументы, начиная со следующего после названия функции, в память, выполняем функцию.

3. Листинг

#define UNICODE

#define _UNICODE

#include <stdio.h>

#include <conio.h>

#include <windows.h>

#include <iostream>

#include <string.h>

#include <tchar.h>

#include <io.h>

#include <stdlib.h>

#include <fcntl.h>

#define BUF_SIZE 0x100

int IsWriteLine(WCHAR*, WCHAR*);

void func(int argc, WCHAR* argv []);

int console(void)

{

_wsetlocale(LC_ALL, _T("Rus"));

DWORD read;

ZeroMemory(&read, sizeof(read));

WCHAR cmd[255], **cParseCmd, **argv;

int dNumWhite, i, argc, k=0,j,newDescr, old;

HANDLE oFile;

HANDLE hOldStdOut;

STARTUPINFO si = {sizeof(STARTUPINFO)};

PROCESS_INFORMATION pi;

wprintf(_T("\n>"));

fflush( stdout );

ReadConsole(GetStdHandle(STD_INPUT_HANDLE), cmd, 254, &read, NULL);

cmd[read-2]=0;

i=0;

dNumWhite=0;

bool Output;

while(cmd[i]!='\0')

{

if(cmd[i]==' ')

dNumWhite++;

i++;

}

cParseCmd=(WCHAR**)malloc(sizeof(WCHAR*)*(dNumWhite+1));

for(i=0;i<dNumWhite+1;i++)

cParseCmd[i]=(WCHAR*)malloc(sizeof(WCHAR*)*(256));

//парсер строки команды

for (i=0; i<dNumWhite+1; i++)

{

j=0;

while ((cmd[k]!=' ') && (cmd[k]!='\0'))

{

cParseCmd[i][j]=cmd[k];

j++;

k++;

}

cParseCmd[i][j]=WCHAR(0);

k++;

}

if(wcsstr(cParseCmd[0],_T("exit")))

return 0;

//если установлен флаг -о вывода в файл

if(wcsstr(cParseCmd[dNumWhite],_T("-o")))

{

oFile = CreateFile(_T("output.txt"), GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);

argc=dNumWhite;

//запоминаем старый handle (консоли)

hOldStdOut = GetStdHandle(STD_OUTPUT_HANDLE);

//переназначаем handle вывода

SetStdHandle(STD_OUTPUT_HANDLE, oFile);

//запоминаем старый дескриптор (консоли)

old = _dup(1);

// Открываем существующий HANDLE как дескриптор (файла)

newDescr = _open_osfhandle((intptr_t)oFile, _O_APPEND );

// Переназначаем файловый дескриптор

_dup2(newDescr, 1);

Output=true;

}

else

{

argc=dNumWhite+1;

Output=false;

}

if(wcsstr(cParseCmd[0],_T("func")))

{

//формирование параметров

argv=(WCHAR**)malloc(sizeof(WCHAR*)*argc);

for(i=0;i<argc;i++)

argv[i]=(WCHAR*)malloc(sizeof(WCHAR*)*(256));

for(i=0;i<argc;i++)

argv[i]=cParseCmd[i];

func(argc,argv);

}

else

{

ZeroMemory(&si, sizeof(si));

ZeroMemory(&pi, sizeof(pi));

CreateProcess(NULL, cmd, NULL, NULL, Output, CREATE_UNICODE_ENVIRONMENT, NULL, NULL, NULL, &pi);

WaitForSingleObject(pi.hProcess, INFINITE);

CloseHandle(pi.hProcess);

CloseHandle(pi.hThread);

}

fflush( stdout );

if(Output)

{

// Сбрасываем поток (возвращаем вывод в консоль)

CloseHandle(oFile);

SetStdHandle(STD_OUTPUT_HANDLE, hOldStdOut);

_dup2(old, 1 );

}

return 1;

}

void main(void)

{

while(console());

}

//поиск и вывод строк соответствующих шаблону

void func(int argc, WCHAR* argv [])

{

//попарное переименование и поиск для каждого файла начиная с конца списка

int err;

for(int i=argc;i>3;i-=2)

{

if(err=IsWriteLine(argv[i-3], argv[argc-1]))

{

printf("No hits. Error: %d \n", err);

}

if(!MoveFile(argv[i-3],argv[i-2]))

{

wprintf(_T("Error: %x \n\n"), GetLastError());

wprintf(_T("Cannot rename %s to %s \n"), argv[i-3],argv[i-2]);

}

else

wprintf(_T("File %s renamed в %s \n\n"), argv[i-3],argv[i-2]);

}

}

int IsWriteLine(WCHAR* filename, WCHAR* str)

{

HLOCAL local;

HANDLE fp;

DWORD dread, size;

WCHAR *buf;

// открываем файл

fp = CreateFile((LPCWSTR)filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

if(fp == INVALID_HANDLE_VALUE)

{

wprintf(_T("file '%s' not found\n"),filename);

return 1;

}

// получаем кол-во байт в файле

size = SetFilePointer(fp, 0L, NULL, FILE_END);

if(! size)

{

CloseHandle(fp);

return 2;

}

SetFilePointer(fp, 0L, NULL, FILE_BEGIN);

local = LocalAlloc(LPTR, size + 1u); // выделяем память в локал-области

if(local == NULL)

{

CloseHandle(fp);

return 3;

}

buf = (LPTSTR) LocalLock(local); // блокируем выделенную память для записи

ReadFile(fp, (LPVOID)buf, size, &dread, NULL); // читаем весь файл разом

CloseHandle(fp);

buf[dread] = WCHAR(0); // завершить строку нулем

// поиск по совпаддению

int i=0, dNum=0, j=0, k=0;

WCHAR **cParseBuf;

while(buf[i]!=WCHAR(0))

{

if(buf[i]=='\n')

dNum++;

i++;

}

buf[0]=_T(' ');

cParseBuf=(WCHAR**)malloc(sizeof(WCHAR*)*(dNum+1));

for(i=0;i<dNum+1;i++)

cParseBuf[i]=(WCHAR*)malloc(sizeof(WCHAR*)*(256));

//парсер строки команды

for (i=0; i<dNum+1; i++)

{

j=0;

while ((buf[k]!='\n') && (buf[k]!=WCHAR(0)))

{

cParseBuf[i][j]=buf[k];

j++;

k++;

}

cParseBuf[i][j]=WCHAR(0);

k++;

}

for(int i=0;i<dNum+1;i++)

{

if(wcsstr(cParseBuf[i],str))

wprintf(_T(" %d: %s\n "),i,cParseBuf[i]);

}

LocalUnlock(local);

LocalFree(local); // освободить занимаемую память

local = NULL;

return 0;

}

4.Контрольный пример

5.Список используемой литературы

  1. Харт, Джонсон, М. Системное программирование в среде Windows, 3-е издание. : Пер. с англ. – М. : Издательский дом «Вильямс», 2005. – 592с. ил.