Программа практических занятий по курсу: "Языки программирования высокого уровня"

Учебник по языку Си: ВВЕДЕНИЕ В ЯЗЫК СИ

План занятий. Cроки выполнения и Сдачи Лабораторных работ. Семестр I

04.09-Lab N1. "Перевод чисел между системами счисления на языке C"
18.09-Lab N2. "Обработка данных внешних команд (конвейер командной строки) на C" + отчет по Lab N1
02.10-Lab N3. "Работа с многомерными массивами, позиционированным выводом на экран и генератором случайных чисел" + отчет по Lab N2
23.10-Lab N4. "Реализация алгоритма бегущей строки" + отчет по Lab N3
13.11-Lab N5. "Работа с файлами. Сортировка строк по алфавиту"+ отчет по Lab N4
27.11-Lab N6. "Работа с файлами. Обработка нажатий клавиш. Скроллинг текста по экрану" + отчет по Lab N5
18.12-Lab N6. Отчет по Lab N6

Все программы выполняем на языке C (не C++)

Лабораторная работа N1. "Перевод чисел между системами счисления на языке C"

Примеры (Ввод/Вывод, аргументы командной строки):

Ввод/Вывод в стиле С:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
char s[40];
if (argc>1) { printf("Argument: %d\n",atoi(argv[1])); }
printf("Input your name: ");
scanf("%s",s);
printf("Hello: %s \n",s);
return 0;
}
Для компиляции используем gcc:
> gcc -Wall -o ex_prog_1 ex_prog.c
Ввод/Вывод в стиле С++ (пример только для понимания отличия от языка C):
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
char s[40];
if (argc>1) { cout << "Argument: " << atoi(argv[1]) << endl; }
cout << "Input your name: ";
cin >> s;
cout << "Hello: " << s << endl;
return 0;
}
Для компиляции используем g++:
> g++ -Wall -o ex_prog_2 ex_prog.cpp

 1.Откомпилировать и разобраться в примерах программ представленных выше, обратить внимание на Вввод/Вывод в различных стилях языка С и С++. Вспомнить раздел: 4.ФУНКЦИИ - "Аргументы функции main()" онлайн-учебника.

 2.В удобном текстовом редакторе (mc editor, gedit, kwrite и т.д.) набрать код программы на языке С, реализующей следующее:

      Для подгруппы 1: Используя агрументы командной строки - входные параметры функции main (argc и argv) реализовать программу производящую преобразование систем счисления из любой системы счисления в любую (до Шестнадцатеричной) при этом указывая в качестве параметров командной строки конкретные системы - исходной и той в которую нужно преобразовать число (сами системы счисления указывать в десятичной системе). Для преобразования массива char в число можно использовать atoi(argv[1]); из библиотеки: stdlib.h .

Примеры вызова программы из командной строки и результат ее выполнения:
> convertsyst fe 16 2
11111110

> convertsyst 45 10 2
101101

> convertsyst 101 2 10
5
      Для подгруппы 2: Используя агрументы командной строки - входные параметры функции main (argc и argv) реализовать программу производящую преобразование систем счисления из Десятичной, Двоичной и Шестнадцатеричной в Десятичную, Двоичную и Шестнадцатеричную при этом указывая в качестве параметров командной строки сокращенное обозначение конкретных систем счисления (d, b, h) - исходной и той в которую нужно преобразовать число (где: d - dec, b - bin, h - hex). Для преобразования массива char в число можно использовать atoi(argv[1]); из библиотеки: stdlib.h .

Примеры вызова программы из командной строки и результат ее выполнения:
> convertsyst 1ab h b
110101011

> convertsyst 47 d b
101111

> convertsyst 10110 b d
22
 3.Представить Результат работы преподавателю. Готовиться к выполнению небольшого дополнительного задания по программе.

Лабораторная работа N2. "Обработка данных внешних команд (конвейер командной строки) на C"

Пример обработки данных, переданных программе посредством конвейера (pipline - обозначается символом "|") командой:
> date "+%T" | ./ex_pipline
Пример программы ex_pipline:
#include <stdio.h>
int main(void)
{
int n,h,m,s;
n=scanf("%d:%d:%d",&h,&m,&s);
printf("Arguments: %d\n",n);
printf("Hours: %d, minutes: %d, seconds: %d\n",h,m,s);
return 0;
}
 1.Откомпилировать и разобраться в примере программы представленном выше, обратить внимание на команду для передачи данных в программу через конвейер (команда: date "+%T" выдает время в формате: HH:MM:SS) и на значение возвращаемое функцией: scanf() (возвращает количество значений, которые действительно были присвоены переменным).

 2.Разработать программу (код на языке С), реализующую следующее:

      Используя операторы чтения со стандартного входного потока, считать параметры передаваемые через конвейер командой: traceroute -m 5 -q 1 -w 2 sampo.ru и вывести на экран:

      Для подгруппы 1: имя узла (2-ой столбец) с самым долгим времением получения ответа. Можно использовать операторы работы со строками из библиотеки функций: string.h .

      Для подгруппы 2: переданные программе через конвейер строки в обратном порядке.

Пример вызова разработанной программы из командной строки:
> traceroute -m 5 -q 1 -w 2 sampo.ru | ./ex_pipline
 3.Представить Результат работы преподавателю. Готовиться к выполнению небольшого дополнительного задания по программе.

Лабораторная работа N3. "Работа с многомерными массивами, позиционированным выводом на экран и генератором случайных чисел"

Пример программы с выводом текста указанным цветом, в заданные координаты:
#include <stdio.h>

void gotoxy(int x, int y)
{ printf("%c[%d;%df", 0x1b, y, x); }

void txt_color(int text_color, int background, int attributes)
{ printf("%c[%d;%d;%dm", 0x1b, attributes, background, text_color); }

int main(void)
{
  printf("\x1b[0d\x1b[2J");  //очистка экрана в терминале (linux)
  txt_color(35,44,0);        //указание цвета вывода текста
  gotoxy(9,3);               //указание координат вывода текста: x,y
  printf("Hello!\n");
  txt_color(37,40,0);        //возвращение обратно цветов консоли
return 0;
}
Пример программы генерирующей случайное число:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
  srand(time(NULL));         //инициализация генератора случайных чисел от времени
  printf("%d\n",rand()%100); //генерация и вывод случайного числа
return 0;
}
 1.Откомпилировать и разобраться в примерах программ представленных выше. Обратите внимание, что в первом примере в функциях: gotoxy и txt_color достаточно было и объявления типов параметров unsigned char вместо int.

 2.Разработать программу (код на языке С), осуществляющую вывод текущего времени в формате: HH:MM:SS в произвольное место терминала, произвольным цветом (linux) без использования библиотеки time.h. Для инициализации генератора случайных чисел, в аргументе командной строки должно передаваться время в секундах (использовать команду: `date +%s`), а текущее время в формате: HH:MM:SS передать со стандартного входного потока, используя команду: date "+%T".

Пример периодической передачи (раз в секунду) текущего времени через конвейер командной строки в программу, а также времени в секундах в качестве аргумента командной строки:
> while true; do date "+%T"; sleep 1; done | ./lab_n3 `date +%s`
где: lab_n3 имя вашей программы. В место, где обратные апострофы (`date +%s`) подставляется результат выполнения команды, которая находится между ними.

Для установки цвета использовать следующий двумерный массив, состоящий из 10 элементов:
const int colors[10][3]={{37,40,0},{31,40,0},{35,44,0},{31,40,0},{36,40,0},{32,40,1},{30,47,0},{34,40,0},{35,40,0},{33,40,0}};
по 3 параметра для установки цвета функцией: txt_color (пример функции выше). Для получения произвольного цвета необходимо выбирать один из этих 10 наборов параметров случайным образом с помощью оператора: rand() (из библиотеки: stdlib.h).

      Для подгруппы 1: Вывод времени осуществить большими цифрами, состоящими из символов "#" в матрице размером не менее чем (ШxВ): 3x5, также добавить разделитель часов, минут и секунд - ":". Двумерный массив представить в тексте программы так, чтобы была видна форма цифр: (в виде: 0123456789: ).

Пример отображения цифр в терминале:


      Для подгруппы 2: Вывод времени осуществить в виде: HH:MM:SS

Пример отображения цифр в терминале:


 3.Проанализировать и ответить на вопрос: Чем отличается выполнение команды:
> while true; do date "+%T"; sleep 1; done | ./lab_n3 `date +%s`
от:
> while true; do date "+%T"; sleep 1; done | ./lab_n3 1
где lab_n3 - имя вашей программы.

 4.Представить Результат работы преподавателю. Готовиться к выполнению небольшого дополнительного задания по программе.

Лабораторная работа N4. "Реализация алгоритма бегущей строки"

Пример программы с выводом текста в заголовок окна терминала (linux):
#include <stdio.h>
int main(void)
{
char s[]="Hello Linux!";
printf("\x1b[1A\x1b]2;%s\x7\n",s);     //вывод строки s в заголовок окна терминала
return 0;
}
 1.Откомпилировать и разобраться в примере представленном выше.

 2.Разработать программу (код на языке С), реализующую алгоритм сдвигающий строку (массив символов) на один символ влево (при этом первый символ помещать в конец этой же строки). Реализовать вывод этой строки в определенную позицию терминала (1,1). По аналогии с командами из предыдущей лабораторной работы, текст для строки получать со стандартного входного потока, воcпользовавшись командами:

      Для подгруппы 1: выдающей время в формате: HH:MM:SS и выдающей путь в текущую папку и периодически (раз в секунду) передающей результаты выполнения этих команд через конвейер командной строки - в вашу программу.

      Для подгруппы 2: выдающей путь в текущую папку и периодически (раз в секунду) передающей результаты выполнения этой команды через конвейер командной строки - в вашу программу.

 3.Переделать программу так, чтобы бегущая строка отображалась в заголовке окна терминала (воспользоваться примером представленым выше).

 4.Представить Результат работы преподавателю. Готовиться к выполнению небольшого дополнительного задания по программе.

Лабораторная работа N5. "Работа с файлами. Сортировка строк по алфавиту"

int strcmp( const char * string1, const char * string2 );  //библиотека string.h
strcmp - сравнивает символы двух строк: string1 и string2. Начиная с первых символов сравнивается поочередно каждая пара символов, сравнение продолжается до тех пор, пока не будут найдены различные символы или не будет достигнут конец строки.

Возвращаемое значение:
Функция числовое значение, которое указывает на отношение строк - если значение:
0 - значит обе строки равны;
>0 - значит, что строка string1 больше строки string2;
<0 - свидетельствует об обратном.

 1.Вспомнить разделы: РАЗДЕЛ 3. СТРУКТУРИРОВАННЫЕ ТИПЫ ДАННЫХ" - "Строки символов" и РАЗДЕЛ 5. ФАЙЛЫ онлайн-учебника.

 2.В текстовом файле baza.txt (кодировка Unicode) содержится база по долгам студентов в следующем в формате:
Фамилия Имя Отчество, курс, группа, количество_долгов
Петров Артем Семенович, 2, 21212, 6

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

      Для подгруппы 1: Произвести сортировку считанных строк по алфавиту по одному из 3-ех выбранных параметров:
Реализовать Меню выбора параметра по которому сортировать:
1.Cортировка по ФИО
2.Cортировка по номеру группы
3.Cотрировка по количеству долгов

Результат сортировки вывести на экран и сохранить в другой файл.

      Для подгруппы 2: Произвести сортировку считанных строк по алфавиту. Результат вывести на экран и сохранить в другой файл.

 3.Представить Результат работы преподавателю. Готовиться к выполнению небольшого дополнительного задания по программе.

Лабораторная работа N6. "Работа с файлами. Обработка нажатий клавиш. Скроллинг текста по экрану"

#include <stdio.h>
#include <termios.h>
#include <unistd.h>

int getch(void)
{   struct termios oldattr, newattr;
    int ch;
    tcgetattr( STDIN_FILENO, &oldattr );
    newattr = oldattr;
    newattr.c_lflag &= ~( ICANON | ECHO );
    tcsetattr( STDIN_FILENO, TCSANOW, &newattr );
    ch = getchar();
    tcsetattr( STDIN_FILENO, TCSANOW, &oldattr );
    return ch;
}

int main()
{ char ch;
  do {
    ch=getch();
  } while (ch!='q');
  return 0;
}
      В языке Си для считывания нажатых клавиш есть функция getch() , которая описана в библиотеке conio.h однако под Linux эта библиотека по умолчанию отсутствует. В связи с этим есть несколько решений для считывания нажатых клавиш клавиатуры под Linux. Можно подключить библиотеку ncurses.h в которой есть getch(), а можно воспользоваться вышеприведенным примером с описанием и использованием функции getch().

 1.Откомпилировать и разобраться в примере представленном выше.

 2.Разработать программу (код на языке С), реализующую алгоритм скроллинга (сдвига текста по экрану) по нажатию соответсвующей клавиши:
Пример:
Лабораторная работа N6.
"Работа с файлами. Обработка нажатий клавиш. Скроллинг текста по экрану".
Содержимое текстового файла по нажатию клавиши перемещается по экрану терминала.
При смещении вверх - верхняя строка исчезает, а вниз добавляется новая из файла.


      Для подгруппы 1: реализовать вывод части текста помещающейся на экран терминала из текстового файла, а также реализующей алгоритм сдвига текста вверх и вниз (с добавлением по одной новой строке) по нажатию клавиш: s (к концу файла) и w (к началу файла). При достижении конца и начала, останавливать вывод текста. Имя файла должно указываться в качестве аргумента командной строки.

      Для подгруппы 2: реализовать вывод текста из текстового файла по одной строке (друг за другом) по нажатию на клавишу Пробел на экран терминала.

 3.Представить Результат работы преподавателю. Готовиться к выполнению небольшого дополнительного задания по программе.

Информация по экзамену для подгруппы 2
Консультация перед экзаменом по "ЯПВУ" - 18.01.2024 (ЧТ) в 11:30 в библиотеке УЛК-5

На экзамене будет два вопроса:
1) Беседа по одной из лабораторных работ 3-6 по выбору студента (студент на экзамен приносит с собой распечатанный листинг выбранной им работы).
2) Написать экспресс-код по выданному мной заданию.

Варианты заданий:

Написать функцию, определяющую, является ли число A простым (возвращает 0, если число непростое, и 1, если число простое):

int is_prime(unsigned A);

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

void sort(size_t N, int* A);

Написать функцию, определяющую, является ли указанное число A палиндромом (напр, 123321, 49094, ...). Возвращает 1, если число - палиндром, 0 - в противном случае.

int is_palindrome(unsigned long A);

Написать функцию, которая с помощью функции генерации случайного числа получает четырёхзначное число, все цифры которого различны:

unsigned int generate_number(void);

Написать функцию, определяющую, равна ли сумма трёх первых цифр заданного шестизначного числа A сумме трёх его последних цифр. Возвращает 1, если билетик "счастливый", 0 - в противном случае.

int is_lucky(unsigned long A);

Написать функцию, которая возвращает индекс максимального значения в целочисленном массиве A(N):
int get_max(size_t N, int* A);