Федеральное агентство связи
ФГОБУ ВПО «СибГУТИ»
Кафедра вычислительных систем
Практические задания по дисциплинам
«Программирование» и «Языки программирования»
семестр 2
2012/2013 учебный год
Преподаватели:
Доцент Кафедры ВС, к. т.н. –
Старший преподаватель Кафедры ВС –
Лабораторная работа №1
Обработка строковых данных
ЦЕЛЬ РАБОТЫ
Получение навыков проектирования программ методом «сверху вниз», а также опыта программной обработки строковых данных.
МЕТОДИЧЕСКИЕ УКАЗАНИЯ
В рамках лабораторной работы необходимо реализовать обработку строковой информации в соответствии с заданием. В качестве обрабатываемых данных рассматриваются пути к файлам в операционных системах (ОС) Windows и GNU/Linux.
Путь (англ. path) – набор символов, описывающий расположение файла в файловой системе. В UNIX-подобных операционных системах разделительным знаком при записи пути является символ "/" (слэш), в ОС Windows – символ "\" (обратный слэш).
Файловые пути в ОС Windows
Полное имя файла в Windows-системах состоит из буквы диска, после которого ставится двоеточие и обратная наклонная черта (обратный слеш), затем через обратные слеши перечисляются подкаталоги, в конце пишется имя файла. Наример:
C:\Windows\System32\calc. exe
Полное имя файла (включая расширение) в Windows может содержать до 260 символов, данное значение определено константой MAX_PATH.
Граф структуры файлов ОС Windows представляет собой лес деревьев, корнями каждого из которых являются дисковые разделы:

Рис. 1 – Пример графа структуры файлов ОС GNU/Linux
Для описания пути к файлам, расположенных на удаленных узлах вычислительной сети используется стандарт UNC (Universal Naming Convention). Описание файлового пути в формате UNC имеет следующий формат:
\\<Имя или IP адрес узла>\<Путь к ресурсу на указанном узле>
Например:
\\192.168.1.2\Share\file. txt
\\windows-machine.com\Share\file. txt
IP адрес представляет собой набор из четырех целых чисел, разделенных точкой:
IP = x1.x2.x3.x4,
где 0 ≤ xi ≤ 255, например: 192.168.1.1, 93.158.134.3, 173.194.47.164, 91.196.245.216.
Имя узла представляет собой доменное имя (http://ru. wikipedia. org/wiki/Доменное_имя) состоит из непосредственного имени домена и далее имён всех доменов, в которые он входит, разделённых точками. Например, полное имя "ru. wikipedia. org" обозначает домен третьего уровня "ru", который входит в домен второго уровня ".wikipedia", который входит в домен верхнего уровня ".org". В рамках данной лабораторной работы будем считать, что существует только три домена верхнего уровня: ru, com и org. Использование любых других доменов недопустимо и считается ошибкой.
Файловые пути в UNIX-подобных ОС
В UNIX-подобных операционных системах (например, GNU/Linux) полный путь состоит из слеша ("/"), обозначающего корневой каталог, после которого идет перечисление каталогов и подкаталогов, разделенных также символом "/", в конце указывается имя файла. Наример:
/usr/local/bin/gcc
Пути, начинающиеся не с символа "/", считаются относительными и отсчитываются относительно рабочего каталога. Пример:
Пусть текущий каталог – /home/alex/video тогда относительный путь prog/c_manual. avi соответствует абсолютному пути /home/alex/video/prog/c_manual. avi
|
Особое значение имеют пути, которые начинаются со знака тильда ("~"). Тильда обозначает домашнюю директорию текущего или указанного пользователя.
Если после знака тильда ("~") следует слэш ("/"), то речь идет о пути относительно домашнего каталога текущего пользователя:
Пусть текущий пользователь – alex Домашний каталог пользователя alex – /home/alex/ тогда путь ~/video/prog/c_manual. avi соответствует абсолютному пути /home/alex/video/prog/c_manual. avi
|
Если после знака тильда ("~") следуют любой другой символ, то подстрока, содержащая символы, расположенные между знаком "~" и первым знаком "/" рассматриваются как имя пользователя в данной ОС, а подстрока, расположенная справа от первого знака "/" трактуется как путь относительно домашнего каталога этого пользователя ОС. При этом текущий пользователь значения не имеет. Например:
Пусть текущий пользователь – alex Домашние каталоги пользователей находятся в /home/ тогда путь ~jack/video/prog/c_manual. avi соответствует абсолютному пути /home/jack/video/prog/c_manual. avi
|
Граф структуры файлов ОС GNU/Linux представляет собой единое дерево, корнем которого является один из доступных дисковых разделов. Остальные разделы монтируются (присоединяются) к основному дереву ниже первого уровня иерархии:
Рис. 2 – Пример графа структуры файлов ОС GNU/Linux |
Для описания пути к файлам, расположенным на удаленных узлах вычислительной сети используется два варианта записи (в зависимости от используемой программы). Формат записи, который применяемый в таких распространенных программах, как scp, rcp, rsync, выглядит следующим образом:
<Имя или IP адрес узла>:<Путь к ресурсу на указанном узле>
Например:
192.168.1.2:/Share/file. txt
linux-machine.com:/Share/file. txt
Также распространено использование формата URL (Universal Resource Location), синтаксис которого выглядит следующим образом:
<протокол>://<Имя или IP адрес узла>/<Путь к ресурсу на узле>
Например:
http://192.168.1.2/Share/file. txt
smb://linux-machine.com/Share/file. txt
В рамках данной лабораторной работы будем рассматривать следующие протоколы: http, ftp, rsync, smb. Использование любых других протоколов недопустимо и считается ошибкой.
Обозначение текущего и родительского каталогов
В операционных системах Windows и GNU/Linux существуют специальные обозначения для текущего каталога (строка ".") и каталога, который является родительским для текущего (строка ".."). Например:
Пусть текущий каталог – /home/alex/video тогда относительный путь./prog/c_manual. avi соответствует абсолютному пути /home/alex/video/prog/c_manual. avi а относительный путь../projects/lab1/lab1.c соответствует абсолютному пути /home/alex/projects/lab1/lab1.c Абсолютному пути /home/alex/video/./prog/c_manual. avi соответствует минимальный путь /home/alex/video/prog/c_manual. avi Абсолютному пути /home/alex/video/../projects/lab1/lab1.c соответствует минимальный путь: /home/alex/projects/lab1/lab1.c |
Преобразование путей ОС Windows в пути ОС GNU/Linux в эмуляторе Cygwin
Эмулятор Linux-окружения Сygwin (http://www. / ) предоставляет пользователю возможность работы в Linux-подобной среде из операционной системы Windows. В связи с различиями между графами файловых структур в ОС GNU/Linux и Windows для доступа к файлам ОС Windows из Linux-окружения выполняется преобразование их путей. Преобразование леса деревьев к дереву заключается в подключении (монтировании) его корней к заранее определенному каталогу /cygdrive (как показано на рис. 3). Таким образом, путь "C:\somedir\somefile" транслируется в "/cygdrive/c/somedir/somefile".

Рис. 3 – Пример графа структуры файлов ОС GNU/Linux
Запрещенные символы
Многие операционные системы запрещают использование некоторых служебных символов. Запрещенные символы Windows:
Таблица 1
\ | разделитель подкаталогов |
/ | ключи командного интерпретатора |
: | отделяет букву диска в Windows-путях |
* | заменяющий символ (маска "любое количество любых символов") |
? | заменяющий символ (маска "один любой символ") |
" | используется для указания путей, содержащих пробелы |
< | обозначение перенаправления ввода |
> | обозначение перенаправления вывода |
| | обозначение программного конвейера |
В UNIX и UNIX-подобных ОС запрещен слеш ("/") – разделитель подкаталогов – и символ конца строки (\0). Остальные перечисленные выше символы (кроме слеша) использовать можно, но из соображений совместимости их лучше избегать.
В рамках данной лабораторной работы выдвигается требование совместимости файловых путей в ОС Windows и GNU/Linux. Поэтому использование символов, приведенных в табл. 1, не допускается ни в Windows-путях ни в Linux-путях. Длина пути также не должна превышать ограничение, установленное в ОС Windows (MAX_PATH = 260 символов).
Ввод строковых данных c клавиатуры
Для ввода входных данных с клавиатуры необходимо использовать функцию:
char *fgets(char *s, int size, FILE *stream);
Первый аргумент (s) – имя символьного массива, в который будет помещена входная строка, второй аргумент (size) – это максимальное количество вводимых символов (не должно превышать размера массива), в качестве третьего аргумента необходимо указать стандартный поток ввода – stdin. Функция выполняет чтение до обнаружения символа ‘\n’ (перевод на новую строку). Таким образом, ввод строки может выглядеть следующим образом:
int main() { char path[1024]; fgets(path, 1024, stdin); . . . } |
Разработка подпрограмм в языке СИ
Функция – это совокупность объявлений и операторов, предназначенная для решения некоторой задачи. Для обращения к функции используется ее имя. В любой программе, написанной на языке СИ, должна быть функция с именем main (главная функция или точка входа в программу), с которой начинается выполнение программы.
С использованием функций в языке СИ связаны три понятия:
§ определение функции – описание действий, выполняемых функцией;
§ объявление (прототип) функции – задание формы обращения к функции;
§ вызов функции;
Определение функции
Расширенная форма Бэкуса-Наура, описывающая определение функции выглядит следкующим образом:
ОпределениеФункции =
ТипРезультата Имя "(" СписокФормПарам ")" "{" {ОператорОписания} {Оператор} "}".
ТипРезультата = ТипДанного.
Имя = Идентификатор.
СписокФормПарам =
[ТипДанного Идентиф {"," ТипДанного Идентиф }].
Пример: int sum_count(int quant, int nums[]) { int i, sum = 0; for(i=0;i<quant;i++){ sum += nums[i]; } return sum; } |
Формальные параметры – локальные переменные, используемые внутри тела функции и получающие значение при вызове функции путем копирования в них значений соответствующих фактических параметров. Даже если функция не имеет формальных параметров, наличие круглых скобок обязательно. Идентификаторы формальных параметров не могут быть переопределены в блоке, образующем тело функции (нельзя описать переменную, имя которой совпадает с именем формального параметра).
Тело функции – это составной оператор, содержащий операторы, определяющие алгоритм ее работы. Все переменные, объявленные в теле функции по умолчанию являются локальными.
При вызове функции локальным переменным отводится память в стеке и производится их инициализация. Управление передается первому оператору тела функции и начинается выполнение функции, которое продолжается до тех пор, пока не встретится оператор return или последний оператор тела функции.
После завершения функции управление возвращается в точку, следующую за точкой вызова. Локальные переменные при этом становятся недоступными и занимаемая ими память освобождаются. При новом вызове функции для локальных переменных память распределяется вновь.
Параметры функции передаются по значению и могут рассматриваться как локальные переменные, для которых выделяется память при вызове функции и производится инициализация значениями фактических параметров. При выходе из функции значения этих переменных теряются.
При таком подходе к передаче параметров изменение их значений в теле функции не влияет на значения фактических параметров в вызывающей функции. Для изменения значений фактических параметров используются указатели.
Вызов функции
Вызов функции имеет следующий формат:
ВызовФункции = [Идентиф=] Имя "(" СписокФактПарам ")"";".
Идентиф = Идентификатор
Имя = Идентификатор
СписокФактПарам = [ Идентиф {"," Идентиф } ]
ТипДанного = БазовыйТип | ПользовательскийТип
Выполнение вызова функции происходит следующим образом:
1. Вычисляются значения формальных параметров (например, sizeof(mas)/sizeof(int)), далее полученные значения приводятся к типу соответствующих формальных параметров. Если приведение выполнить невозможно или количество фактических и формальных параметров не совпадает, то формируется сообщение об ошибке.
2. Происходит присваивание значений фактических параметров соответствующим формальным параметрам.
3. Управление передается на первый оператор функции.
4. Выполнение оператора return в теле функции возвращает управление и возможно, значение в вызывающую функцию. При отсутствии оператора return управление возвращается после выполнения последнего оператора тела функции, а возвращаемое значение не определено.
Пример: int sum_count(int quant, int nums[]) { int i, sum = 0; for(i=0;i<quant;i++){ sum += nums[i]; } return sum; } int main(){ int mas[] = {1,2,3,4,5,6,7}; int sum = sum_count(sizeof(mas)/sizeof(int),nums); return 0; } |
Объявление (прототип) функции
Если требуется вызвать функцию до ее определения в рассматриваемом файле, или определение функции находится в другом исходном файле, то вызов функции следует предварять объявлением этой функции. Объявление (прототип) функции имеет следующий формат:
Прототип = ТипРезультата Имя "(" СписокФормПарам ")"";".
ТипРезультата = ТипДанного.
Имя = Идентификатор.
СписокФормПарам = [ТипДанного Идентиф {"," ТипДанного Идентиф }].
ТипДанного = БазовыйТип | ПользовательскийТип.
Пример: int sum_count(int quant, int nums[]); // прототип int main(){ int mas[] = {1,2,3,4,5,6,7}; int sum = sum_count(sizeof(mas)/sizeof(int),nums); // вызов return 0; } int sum_count(int quant, int nums[]) // определение { int i, sum = 0; for(i=0;i<quant;i++){ sum += nums[i]; } return sum; } |
В отличие от определения функции, в прототипе за заголовком сразу же следует точка с запятой, а тело функции отсутствует.
Прототип – это явное объявление функции, которое предшествует определению функции. Тип возвращаемого значения при объявлении функции должен соответствовать типу возвращаемого значения в определении функции. Порядок и типы формальных параметров должны быть одинаковыми в определении функции и во всех ее объявлениях.
Наличие в прототипе полного списка типов аргументов параметров позволяет выполнить проверку соответствия типов фактических параметров при вызове функции типам формальных параметров, и, если необходимо, выполнить соответствующие преобразования.
Способы передачи параметров, требующих изменения, в функцию
1. С использованием глобальных переменных #include <stdio. h> float a, b,c; float x0,x1,D; int sq_equation_glob() { D = b*b - 4*a*c; if( D < 0 ){ return 0; }else if( D == 0 ){ x0 = - b/(2*a); return 1; }else if( D > 0 ){ x0 =(-b + sqrt(D))/(2*a); x1 =(-b - sqrt(D))/(2*a); return 2; } } int main() { int roots; printf("Input a, b, c\n"); scanf("%f%f%f",&a,&b,&c); roots = sq_equation_glob(); if( roots == 0 ){ printf("No real roots\n"); }else if( roots == 1 ){ printf("x0 = %f\n", x0); }else if( roots == 2 ){ printf("x0 = %f\n", x0); printf("x1 = %f\n", x1); } } |
2. С использованием указателей. #include <stdio. h> int sq_equation(float a, float b, float c, float *x0, float *x1) { float D = b*b - 4*a*c; if( D < 0 ){ return 0; }else if( D == 0 ){ *x0 = - b/(2*a); return 1; }else if( D > 0 ){ *x0 =(-b + sqrt(D))/(2*a); *x1 =(-b - sqrt(D))/(2*a); return 2; } } int main() { float a, b,c; float a1,b1,c1; float x10,x11; float x20,x21; int roots = 0; printf("Input a, b, c\n"); scanf("%f%f%f",&a,&b,&c); roots = sq_equation(a, b,c,&x10,&x11); if( !roots ){ printf("No real roots\n"); }else if( roots == 1 ){ printf("x10 = %f\n", x10); }else{ printf("x10 = %f\n", x10); printf("x11 = %f\n", x11); } printf("Input a1, b1 ,c1\n"); scanf("%f%f%f",&a1,&b1,&c1); roots = sq_equation(a1,b1,c1,&x20,&x21); if( !roots ){ printf("No real roots\n"); }else if( roots == 1 ){ printf("x20 = %f\n", x20); }else{ printf("x20 = %f\n", x20); printf("x21 = %f\n", x21); } } |
3. С использованием массива #include <stdio. h> int sq_equation_arr(float a, float b, float c, float x[2]) { float D = b*b - 4*a*c; if( D < 0 ){ return 0; }else if( D == 0 ){ x[0] = - b/(2*a); return 1; }else if( D > 0 ){ x[0] =(-b + sqrt(D))/(2*a); x[1] =(-b - sqrt(D))/(2*a); return 2; } } int main() { float a, b,c; float a1,b1,c1; float x[2], x1[2]; int roots = 0, i; printf("Input a, b, c\n"); scanf("%f%f%f",&a,&b,&c); roots = sq_equation(a, b,c,x); for( i=0;i<roots;i++){ printf("x%d = %f\n",i, x[i]); } printf("Input a1, b1 ,c1\n"); scanf("%f%f%f",&a1,&b1,&c1); roots = sq_equation(a1,b1,c1,x1); for( i=0;i<roots;i++){ printf("x%d = %f\n",i, x1[i]); } } |
ЗАДАНИЯ
Общая информация
Выполнение лабораторной работы предполагает выполнение задания либо первого либо второго уровня сложности. Если студент претендует на отличную оценку на экзамене по результатам работы в семестре необходимо выбирать задание второго уровня сложности.
Номер варианта выбирается в соответствии с номером студента в журнале преподавателя (необходимо уточнить) согласно следующему выражению на языке СИ: (n%(S+1)) + ((n/(S+1))>0), где n – номер студента по журналу, S – количество заданий.
При разработке подпрограмм в соответствии с заданием следует учитывать, что:
1. Исходная задача должна быть разбита на подзадачи, которые в свою очередь, при необходимости, представляются в виде подзадач. Разбиение производится до тех пор, пока задачи не становятся тривиальными. Например, вычисление длины строки.
2. Каждая подзадача оформляется в виде подпрограммы.
3. Не допускается использования стандартных функций обработки строк. Все операции над строками должны быть реализованы самостоятельно в виде отдельных подпрограмм. Примерами типичных функций, которые должны присутствовать в каждой программе являются:
1) функция вычисления длины строки (slen);
2) функция разбиения строки на элементы (stok), разделенные заданным символом (например, символ “/” при анализе пути или символ “.”, при разборе IP-адресов или доменных имен);
3) функция проверки символа на принадлежность заданному множеству символов (sspn), необходимая для проверки допустимости используемых символов.
4) функция сравнения строк (scmp);
5) функция копирования строк (scpy).
Разрабатываемая программа должна иметь структуру, показанную на рис. 4. Ввод и вывод данных необходимо осуществлять в отдельных подпрограммах. Функция input() осуществляет взаимодействие с пользователем и возвращает строку, содержащую входные данные (путь).
Рис. 4 – Структура разрабатываемой программы |
Функция check() отвечает за проверку входных данных на корректность: проверку допустимой длины, а также используемых символов. Значения, возвращаемые функцией check(), должны позволять определить тип ошибки и (если нужно) номер символа, в которой она обнаружена.
Функция process() осуществляет обработку строки согласно заданию.
Функция output() выполняет отображение полученных результатов или сообщений об ошибке на экране.
В отчете о лабораторной работе должен присутствовать список тестовых данных, на которых проверялась корректность работы программы, и соответствующие результаты работы программы.
Набор тестов должен обеспечивать проверку поведения программы для всех классов входных данных:
1) некорректный файловый путь;
2) превышение допустимой длины пути;
3) допустимый путь, который не удовлетворяет указанным в задании условиям;
4) допустимый путь, удовлетворяющий условиям.
I уровень сложности
Входными данными для всех подпрограмм данного раздела является путь к одному файлу. Варианты заданий, имеющие первый уровень сложности:
1. Разработать программу, определяющую тип ОС, использующий данный вид путей, а также глубину вложенности конечного файла в структуру каталогов (количество каталогов, начиная с корневого, которое необходимо пройти, чтобы получить доступ к файлу).
2. Разработать программу, определяющую тип ОС, использующий данный вид путей, а также количество символов в имени конечного файла (длина файла без учета каталогов).
3. Разработать программу, определяющую тип ОС, использующий данный вид путей, а также максимальную длину (количество символов в имени) каталога среди каталогов, расположенных в пути к файлу, поданному в качестве входных данных.
4. Разработать программу, определяющую тип ОС, использующий данный вид путей, а также выполняющую преобразование всех символов в имени конечного файла (без учета каталогов) к верхнему регистру.
5. Разработать программу, определяющую тип ОС, использующий данный вид путей, а также преобразование всех символов в имени каталога, содержащего конечный файл, к нижнему регистру.
6. Разработать программу, выполняющую проверку, что входные данные соответствуют формату сетевого пути, используемому в ОС Windows. Необходимо проверять допустимость IP-адресов, доменных имен и протоколов.
7. Разработать программу, выполняющую проверку, что входные данные соответствуют формату сетевого пути, используемому в ОС GNU/Linux программой scp. Необходимо проверять допустимость IP-адресов, доменных имен и протоколов.
8. Разработать программу, выполняющую проверку того, что входные данные соответствуют формату сетевого пути формата URL. Необходимо проверять допустимость IP-адресов, доменных имен и протоколов.
9. Разработать программу, определяющую тип ОС, использующий данный вид путей. Если это GNU/Linux, то определить соответствуют ли входные данные относительному пути в каталоге текущего или указанного пользователя. В последнем случае необходимо вернуть имя указанного пользователя.
10. Разработать программу, определяющую тип ОС, использующий данный вид путей. Если это GNU/Linux, то дополнительно проверить соответствует ли входной путь разделу ОС Windows, представленному в эмуляторе Cygwin.
11. Разработать программу, определяющую тип ОС, использующий данный вид путей. Если это Windows, то определить номер раздела, в котором расположен конечный файл (согласно рис.).

12. Разработать программу, определяющую тип ОС, использующий данный вид путей. Если это GNU/Linux, то определить номер раздела, в котором расположен конечный файл (согласно рис.).

II уровень сложности
Входными данными для всех подпрограмм данного раздела является строка, содержащая пути к файлам, разделенные указанным видом разделителей (может быть пробел, двоеточие, "+"). На вход могут также поступать дополнительные данные, определяемые вариантом задания.
Варианты заданий, имеющие второй уровень сложности:
1. Файлы, расположенные в каталоге dir1 были перемещены в каталог dir2. Для заданных с клавиатуры dir1 и dir2 обновить список входных файловых путей. dir1 и dir2 должны относиться к одной и той же ОС.
2. Для заданного имени текущего пользователя обновить список входных файлов, преобразовав пути, заданные относительно его домашнего каталога (вида ~/somedir), к абсолютным путям. Считать, что домашние каталоги пользователей находятся в директории /home/.
3. Считая, что домашние каталоги пользователей находятся в директории /home/, преобразовать все пути входного списка, заданные относительно домашних каталогов указанных пользователей (вида ~alex/somedir), к абсолютным путям.
4. Преобразовать все пути, содержащие служебные каталоги: текущий каталог (".") и родительский каталог (".."); к минимально возможным путям. Например:
/home/alex/video/../progs/./test. c -> /home/alex/progs/test. c
5. Преобразовать все Windows пути во входном списке к Linux-путям, используя формат эмулятора Cygwin.
6. Преобразовать все Windows-пути формата Cygwin к оригинальным Windows-путям.
7. На сетевых узлах была выполнена замена ОС Windows на ОС GNU/Linux. Сетевые ресурсы (файлы) были перенесены без изменения иерархии. В ОС GNU/Linux доступ к файлам осуществляется с помощью программы scp. Обновить все сетевые пути входного списка. Необходимо проверять допустимость всех IP-адресов, доменных имен и протоколов в списке путей.
8. На сетевых узлах была выполнена замена ОС Windows на ОС GNU/Linux. Файлы были перенесены без изменения иерархии. В ОС GNU/Linux доступ к файлам будет осуществляться по протоколу http (формат пути – URL). Обновить все сетевые пути входного списка. Необходимо проверять допустимость всех IP-адресов, доменных имен и протоколов в списке путей.
9. Файлы из входного списка, расположенные на сетевом узле, работающем под управлением ОС GNU/Linux, были перенесены на новый узел под управлением ОС Windows. Иерархия каталогов не изменялась. Доступ к файлам осуществлялся по протоколам smb и http (формат пути – URL). По заданным именам или IP адресам исходного и нового узлов обновить входной список файлов. Необходимо проверять допустимость всех IP-адресов, доменных имен и протоколов в списке путей.
10. Файлы из входного списка, расположенные на сетевом узле, работающем под управлением ОС GNU/Linux, были перенесены на новый узел под управлением ОС Windows. Иерархия каталогов не изменялась. Доступ к файлам осуществлялся с помощью программы scp. По заданным именам или IP адресам исходного и нового узлов обновить входной список файлов. Необходимо проверять допустимость всех IP-адресов, доменных имен и протоколов в списке путей.
11. Файлы из входного списка, расположенные на сетевом узле, работающем под управлением ОС Windows, были перенесены на новый узел под управлением ОС GNU/Linux. Иерархия каталогов не изменялась. Доступ к файлам осуществляется по протоколу smb (формат пути – URL). По заданным именам или IP адресам исходного и нового узлов обновить входной список файлов. Необходимо проверять допустимость всех IP-адресов, доменных имен и протоколов в списке путей.
12. Файлы из входного списка, расположенные на сетевом узле, работающем под управлением ОС Windows, были перенесены на новый узел под управлением ОС GNU/Linux. Иерархия каталогов не изменялась. Доступ к файлам осуществляется с помощью программы scp. По заданным именам или IP адресам исходного и нового узлов обновить входной список файлов. Необходимо проверять допустимость всех IP-адресов, доменных имен и протоколов в списке путей.






