В реализации использована функция getch(), которая возвращает код нажатой пользователем клавиши и не отображает символ на экране. В случае нажатия функциональных или курсорных клавиш, эта функция возвращает 0 или 0xE0 в зависимости от компилятора и ее повторный вызов позволяет получить расширенный код клавиши.
void main()
{
int key, scan=0;
setlocale(LC_ALL, "RUS"); // для переключения русской кодировки
printf("Нажмите одну из курсорных клавиш\n ");
key=_getch(); //key=getch();
if (key>=0xe0) scan=_getch();
switch (scan)
{
case 77:
printf("стрелка вправо\n");
break;
case 75:
printf("стрелка влево\n");
break;
case 72:
printf("стрелка вверх\n");
break;
case 80:
printf("стрелка вниз\n");
break;
default:
printf("Не стрелка");}
}
Рис. Блок-схема меню программы с использованием бесконечного цикла и многоальтернативного выбора
int click, size;
char filename[N];
int fh, fm;
struct kinoseans *kino;
while (1) {
puts("Программа для работы с киносеансами\n Для ввода данных -1\n Для чтения данных из файла -2 \n Вывод всех данных на экран - 3 \nПоиск данных - 4 \nСортировка данных -5 \nЗапись в файл - 6\n Завершить - 0\nВаш выбор - ");
scanf("%d\n", &click);
switch (click) {
case 0: return -1;
case 1:
puts("Сколько записей?"); scanf("%d", &size);
kino = (kinoseans *)malloc(size * sizeof(kinoseans));
init(kino, size);//вызов функции заполнения сеансов
putkino(kino, size);//вызов функции печати сеансов
break;
case 2:
puts("Укажите имя файла данных"); scanf("%s", filename);
kino = readfile(filename, &size);//чтение сеансов из файла
break;
case 3:
putkino(kino, size);//печать всех сеансов
break;
case 4:
puts("Укажите время начала сеанса в формате часы:минуты");
scanf("%d:%d", &fh, &fm);
int k = findtime(fh, kino, size);//поиск сеанс по заданному времени
if (k >= 0) printf(" Имя:%10s; Жанр:%10s; Дата:%2d:%2d:%2d; Время:%2d:%2d; Бюджет:%2d\n ", kino[k].nazv, kino[k].ganr, kino[k].data1, kino[k].data2, kino[k].data3, kino[k].vremya1, kino[k].vremya2, kino[k].budg);
else puts("Сеанс не найден");
break;
case 5:
temp = sorttime(kino, size);//сортировка сеансов по времени
if (temp) putkino(temp, size); //печать всех сеансов
else puts("отсортировать не удалось");
break;
case 6:
puts("\nУкажите имя файла для записи данных"); scanf("%s", filename);
writefile(filename, kino, size);//запись сеансов в файл
break;
default:
puts("Выполнить невозможно");
}
}
}
Допустим у нас имеется структура данных "киносеанс"
и организована запись в файл массива структур вида:
В результате файл данных имеет вид:
1) строка записи по каждому спецификатору %s не должна содержать пробелы (например, "Домик_в_лесу")
2) после спецификатора %s должен следовать разделитель (пробел, перевод строки, табуляция) , иначе символ считается в строку, а в буфере останется не интерпретируемый набор символов.
3) в конце каждой записи должен быть конец строки ('\n') или собственный разделитель
Для чтения собственного формата управляющая строка fscanf должна быть идентичной fprintf
НО при заданной ширине поля "длинное число" запишется правильно, а считается только заданное в спецификаторе формата число цифр, поэтому без уверенности в размере ширину лучше не задавать!
Математическая модель решения – разложение функции синус в ряд Тейлора имеет вид:
k-й элемент последовательности определяется по рекуррентной формуле: a[k] = q[k-1] * (-1) * x * x/ (2*k)/(2k - 1)
Для решения этой задачи следует использовать метод накопления, когда формирование следующего члена ряда осуществляется на основе предшествующего. В данном случае для получение k-го члена ряда нужно (k-1)-й член умножить на x*x, разделить на k*(k-1). Это позволяет исключить использование функции возведения в степень и явное вычисление факториала в каждой итерации.
При решении важно понимать, что чем больше членов ряда будет просуммировано, тем точнее будет вычислен синус. Так, если приемлемая точность равна eps, то достаточно суммировать члены ряда до тех пор, пока очередной член ряда не окажется меньше eps.
Следует также обратить внимание, что ряд – знакопеременный, т. е. в одной итерации значение прибавляется, а в следующей вычитается. Для такого случая применим прием, известный как «мерцающий счетчик», когда выделяется переменная и ее значение в каждой итерации умножается на (-1), таким образом чередуются отрицательные и положительные значения.
А) Оформите приглашение к вводу значения eps и инициализацию значения:
double eps=1e-5;
Б) Организуйте цикл вычислений (ak – член ряда, sum – текущее значение ряда, k – счетчик итераций)
Инициализация:
ak=x; sum=ak; k=1;
Проверка условия:
fabs(ak)<eps;
Модификация:
k+=2; ak*=(-1)*x*x/(k*(k-1));
Тело цикла:
sum+=ak;
Для данной задачи можно выбирать любые конструкции построения цикла вычислений, но при выборе do-while будет иная инициализация переменных.
Задача А. Работа со строками
#include <stdio.h>
#include <locale.h>
#include <string.h>
#include <windows.h>
#define N 100
int main(){
FILE *file;
char arr[N], key[10];
char *a;
file = fopen("text.txt", "r");
setlocale(LC_ALL, "RUS");
puts("Введите слово");
//setlocale(LC_ALL, ".20866");
//setlocale(LC_ALL, " ");
setlocale(LC_ALL, "utf-8");
fgets (key, 9, stdin);
while (fgets (arr, N, file) != NULL) {
if((a=strstr(arr, key))!=NULL) {
printf("11%s", a);
printf("\n");
}
else printf("%s", arr);
}
fclose(file);
getchar();
getchar();
return 5;
}
#include <stdio.h>
void main(){
int m, d = 1;
for (int i = 0; i<9; i++) {
for (int l = 0; l < 9 - d; l++) { printf(" ");
}
for (int j = 0; j<d; j++) {
printf("%5d", count(j,i));
}
puts("\n"); d++;
}
int count(int t, int b) {
int h = b - t;
if (t == 0 || t==b) return 1;
for (int i = t-1; i > 1; i--) {
t *= i;
}
for (int i = b-1; i > 1; i--) {
b *= i;
}
for (int i = h-1; i > 1; i--) {
h *= i;
}
return b /(h* t);
}