Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
отчёт.doc
Скачиваний:
0
Добавлен:
09.07.2019
Размер:
627.2 Кб
Скачать

Министерство образования и науки Российской Федерации

Федеральное агентство по образованию

Государственное образовательное учреждение высшего профессионального образования

«Санкт-Петербургский государственный университет информационных технологий,

механики и оптики»

ИКВО

МиПИУ

ВТИП

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

Использование стандартной библиотеки с

Вариант № 5

Студент: Гусихин А.Д.

Группа: 1750

Преподаватель: Гирик А.В.

Санкт-Петербург

2011

Задание:

Написать программу (язык С), которая выполняет ввод текстовой информации из файла или стандартного потока ввода, осуществляет преобразование информации в соответствии с вариантом задания (см. ниже) и выводит преобразованную информацию в файл или в стандартный поток вывода.

Программа представляет собой консольную утилиту [1, 2]. Настройка работы программы осуществляется путем передачи аргументов в строке запуска. Типичными примерами консольных утилит являются cat, ls, cal (в Unix) или dir, type, copy (в Windows) [3].

Строка запуска программы имеет следующий формат:

имя_программы [опции] [исходный_файл [результирующий_файл]]

где

опции - последовательность ключей, настраивающих поведение программы. Общие для всех вариантов опции перечислены в таблице 1. Некоторые варианты могут предусматривать дополнительные опции. Более подробно о правилах разбора опций можно прочитать в [4]. В большинстве случаев опции являются необязательными (т.е. могут не указываться в командной строке);

исходный_файл - путь к файлу, из которого нужно считывать информацию;

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

Если исходный_файл не задан, то это значит, что строки исходного текста программа должна читать из стандартного потока ввода.

Опция Значение

-b=N Выполнять действия, предусмотренные вариантом программы, начиная со строки номер N исходного текста. Если эта опция не задана, то действия выполняются, начиная с первой строки текста.

-e=M Выполнять действия, предусмотренные вариантом программы, до строки номер M исходного текста включительно. Если эта опция не задана, то действия выполняются до конца текста.

Задание:

Найти все уникальные (то есть встречающиеся в исходном тексте только один раз) строки.

Опции:

-i - не различать строчные и заглавные буквы при сравнении

Программа:

#include <windows.h>

#include <stdlib.h>

#include <stdio.h>

#include <conio.h>

#include <string.h>

int optionB=0; // опция b=

int optionE=0; // опция e=

int optionI=0; // опция -i=0 - нет, -i - да

char *fileNameIn; // наименование входного файла

char *fileNameOut; // наименование результирующего файла

FILE *fileIn, *fileOut; // переменная для файла

const int MaxRow=2048; // Максимальная длина массива arr

const int RowLen=128; // Длина буфера ввода/строк

// Функция предназначена для копирования подстроки

// из src в dest начиная с индекса B по индекс C

// src -исходная строка

// dest - результирующая строка

// b - Начало подстроки

// e - Конец подстроки

void strcpyBE(char *dest, char *src, int b, int e)

{

int j=0; // индекс элемента в строке dest

for(int i=b; (i<=e)&&(i<strlen(src)); i++) // цикл от b до e, но с контролем выхода i за предлы строки str

{

dest[j] = src[i]; // копируем элемент из строки src в строкцу dest

j++;

}

dest[j]=0; // в конце dest завершающий строку нулевой элемент

}

// функция декодирует один ключ

void DecodeOneKey(char *key)

{

char buf[128]; // буфер

// если строка имеет хотя бы два символа и начинается с b=

if ( (strlen(key)>1)&&(key[0]=='b')&&(key[1]=='=') )

{

strcpyBE(buf, key, 2, strlen(key)-1);

optionB = atoi(buf); // включена опция b

}

// если строка имеет хотя бы два символа и начинается с e=

else if( (strlen(key)>1)&&(key[0]=='e')&&(key[1]=='=') )

{

strcpyBE(buf, key, 2, strlen(key)-1);

optionE = atoi(buf); // включена опция e

}

// если строка имеет один символ и этот символ i

else if ( (strlen(key)==1)&&(key[0]=='i') )

{

optionI =1; // включена опция i

}

// иначе что-то не так

else printf("Неверный ключ: %s\n",key);

}

// функция обрабатывает список ключей -b11-e88-i

void DecodeKeys(char *key)

{

char buf[60];

int b=0, e=0; // начало и конец параметра

for (int i=0; i<strlen(key); i++) // проход по строке key

{

if (key[i]=='-' ) // Начало нового ключа

{

if ( (b<=e)&&(b>0) ) // если есть ключ

{

strcpyBE(buf,key,b,e); // копируем найденный ключ в buf

DecodeOneKey(buf); // декодируем ключ

}

b=i+1; // b - начало нового ключа

e=0; // конец пока неизвестен

}

else e=i; // возможный конец ключа

}

if ( (b<=e)&&(b>0) )

{

strcpyBE(buf,key,b,e);

DecodeOneKey(buf);

}

}

// функция печатает строку на экран или в файл если тот открыт

void PrintRow(char* buf)

{

if (buf==NULL)

return;

if ( fileOut==0 ) // если файл открыт

printf("%s\n", buf);

else

fprintf(fileOut,"%s\n", buf);

}

int main(int argc, char* argv[]) // argc - К-во параметров командной строки, argv[] - сами параметры

{

int i;

system("cls");

printf("utilsstr.exe [опции] [исходный_файл [результирующий_файл]]\n");

printf("опции =-i, -b=xxx, -e=xxx\n");

// проходим по списку апарметров командной строки

fileNameIn = NULL; // пока файлы не определены

fileNameOut = NULL; //

int j=0;

for (i=1; i<argc; i++) //при i=0 это имя самой программы, нас не интересует

{

if (argv[i][0]=='-') // это ключ

{

DecodeKeys(argv[i]); // раскодируем

}

else // это имя файла

{

j++; // номер файла в списке

switch(j)

{

// исходный файл

case 1: fileNameIn = new char[80]; // Выделяем память под имя файла

strcpy(fileNameIn, argv[i]); // Копируем из argv имя файла в fileNameIn

break;

// результирующий файл

case 2: fileNameOut = new char[80]; // Выделяем память под имя файла

strcpy(fileNameOut, argv[i]); // Копируем из argv имя файла в fileNameIn

break;

default: printf("Слишком много параметров!\n");

}

}

}

char* arr[MaxRow]; //массив для ввода информации с клавиатуры

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

arr[i] = 0; //обнуляем массив

if (fileNameOut!=NULL) // если определено имя результирующего файла

fileOut = fopen(fileNameOut, "w+");

int rowCount=0; // к-во строк

if (fileNameIn==NULL) // если нет файла то читаем с клавиатуры

{

printf("Введите строки (пусто - конец ввода): \n");

int t = 1; // для организации цикла

while ( t ) // пока t==1

{

char buf[128]; // буфер для ввода данных с клавиатуры

printf("%d=>",rowCount+1); // для больщей информативности

gets(buf); // ввести информацию с клавиатуры в buf

if (buf[0]!=0) // если буфер не пустой

{

arr[rowCount] = new char[strlen(buf)]; // распределить память для строки arr[rowCount]

strcpy(arr[rowCount],buf); // скопировать содержимое буфер в arr[rowCount]

} else t = 0; // конец ввода

rowCount++;

}

rowCount--; // кол-во строк - 1

}

else // если есть файл то читаем из файла

{

fileIn = fopen(fileNameIn, "r"); // Открыть файл

if ( fileIn!=0 ) // Если файл открыт

{

while (!feof(fileIn)) // Пока не конец файла

{

char buf[RowLen]; // Буфер для операций

fgets(buf, sizeof(buf), fileIn); // Читаем из файла в буфер

// Заменяем символ \n сиволом конец строки

for(int j=0; j<RowLen; j++) //

if (buf[j]==10) // \n=10

{

buf[j]=0;

break;

}

arr[rowCount] = new char[RowLen]; // распределить память для строки arr[rowCount]

strcpy(arr[rowCount], buf); // копируем из буфера в arr[rowCount]

rowCount++;

}

}

else printf("Ошибка откртия файла: %s\n", fileNameIn);

fclose(fileIn); // закрываем файл

}

// обработка введенных строк

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

{

if ( ( optionB<=i+1) && ( (i+1<=optionE) || (optionE==0) ) )

{

int rowEq = 0; // кол-во повторений

char buf1[128], buf2[128]; // определение 2-х строк

for (int j=0; j<rowCount; j++) // пройдемся по всем введеным строкам

{

// копирование обрабатываемых строк а буфер 1, 2

strcpy(buf1, arr[i]);

strcpy(buf2, arr[j]);

if (optionI) // если не различать заглавные

{

// преобразуем в заглавные

strupr(buf1);

strupr(buf2);

}

if ( strcmp(buf1, buf2)==0) // сравневаем

rowEq++; // если строки равны то +1

}

if ( rowEq==1 ) // если строка в единственном экземпляре

PrintRow(arr[i]); // печатаем строку

}

}

// осбождаем распреленную память arr[i]

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

if (arr[i]!=NULL) // если память была распределена ранее

delete[] arr[i]; // освобождаем память arr[i]

if (fileOut!=0) // если результирующий файл был открыт

{

printf("Сформирован файл: %s\n", fileNameOut); // ссобщение

fclose(fileOut); // закрытие файла

}

// осбождаем распреленную память

if (fileNameIn!=NULL) delete[] fileNameIn;

// осбождаем распреленную память

if (fileNameOut!=NULL) delete[] fileNameOut;

printf("Press any key to continue...\n");

char c = getch(); // читаем символ с клавиатуры

return 0;

}

Результаты:

Начальный файл: