Лабораторная работа №1 Вариант 17
.doc
МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РФ
ГОСУДАРСТВЕННОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ
ВЫСШЕГО ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ
ЛИПЕЦКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
КАФЕДРА АВТОМАТИЗИРОВАННЫХ СИСТЕМ УПРАВЛЕНИЯ
Лабораторная работа №1
по дисциплине
«Программирование на языке высокого уровня»
на тему:
«Указатели, динамическое выделение памяти, работа с файлом»
|
Студент |
|
|
|
|
|
||||||||
|
|
|
подпись, дата |
|
фамилия, инициалы |
|
||||||||
|
Группа |
|
|
|
|
|
|
|||||||
|
|
|
|
|
|
|
||||||||
|
Принял |
|
|
|
|
|
||||||||
|
|
|
|
|
Тищенко А.Д. |
|
||||||||
|
ученая степень, звание |
|
подпись, дата |
|
фамилия, инициалы |
|
Липецк 2011
-
Задание
Задание
Программа должна предоставлять возможность нескольким пользователям работать с числовыми данными. Сведения о пользователях должны храниться в отдельном текстовом файле пользователей: для каждого пользователя указывается имя пользователя и пароль (пароль в файле должен храниться задом наперед). Числовые данные всех пользователей хранятся в одном файле данных.
-
При запуске программы необходимо запросить имя пользователя и его пароль (при вводе пароля на экране отображать символы «*» вместо реально вводимых символов).
-
Если имя пользователя найдено в файле пользователей и введенный пароль верен, то загружаются пользовательские числовые данные. В противном случае должно выдаваться сообщение об ошибке и завершение программы.
-
Программа должна предоставлять пользователю следующие возможности по работе с числовыми данными:
-
Вывод элементов массива X
-
Добавление нового элемента в конец массива X
-
Удаление элемента из массива X
-
Расчет заданной функции F(X) над элементами массива X и вывод значения функции пользователю.
-
Расчет элементов массива Y по формуле Yi=G(Xi) и вывод их пользователю в виде
y[1] = 3.543
y[2] = 6.422
y[3] = -14.223
…………
При выводе округлять значения Yi до 3-х знаков после запятой.
№ |
F |
G |
17 |
Среднее |
-
Блок-схема
-
Листинг программы
main.cpp:
#include <locale.h>
#include <stdio.h>
#include <conio.h>
#include <malloc.h>
#include "funcs.h"
void main()
{
setlocale(LC_ALL, "Russian");
char*username=0;
username=(char*)malloc(sizeof(char)*50);
printf("Введите имя пользователя: ");
scanf("%s", &*username);
char*password=0;
password=(char*)malloc(sizeof(char)*50);
printf("Введите пароль: ");
password = GetPass();
ReversePass(password);
printf("\nПароль перевёрнутый: %s", password);
CheckUnamePass(username, password);
free(username);
free(password);
return;
}
func.h:
int GetNumber (char*f);
int* Getmas(char* fname);
char*GetPass();
void ReversePass(char *Pass);
void CheckUnamePass(char *uname, char *pass);
void Menu(int n);
void ArrOutput (int *arr);
void ArrAddItem(int *arr, int n_user);
void ArrDelItem(int *arr, int n_user);
void CountMasX (int *arr);
void CountMasY (int *arr);
void WriteData(int * userarr, int number_digits, int usernumber);
func.cpp:
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <math.h>
#include <windows.h>
#include "funcs.h"
//ф-ция считающая кол-во чисел в файле
int GetNumber (char*f)
{
FILE*f_point=fopen(f, "r");
int cnt=0;
while (!feof(f_point))
{
int val=0;
fscanf (f_point, "%i_", &val);
cnt++;
}
fclose(f_point);
return (cnt - 1);
}
//ф-ция получающая массив из файла
int* Getmas(char* fname)
{
int* mas = 0;
int x = GetNumber(fname);
mas = (int*)malloc(sizeof(int)*x);
FILE*fp=fopen(fname, "r");
for (int i = 0; i < x; i++ )
{
fscanf(fp,"%i_",&mas[i]);
}
fclose(fp);
return mas;
}
//функция, реализующая ввод пароля и отображение "*"
char* GetPass()
{
char* pass = (char*) malloc ( sizeof ( char ) * 255);
char tempch = '\0';
int i = 0;
while ( tempch != '\r' )
{
tempch = getch();
if (tempch=='\r') break;
printf ("*");
pass[i] = tempch;
i++;
}
pass[i] = '\0';
printf("\nПароль: %s", pass);
return pass;
}
//ф-ция выполняющая переворот введённого пароля
void ReversePass(char *Pass)
{
char* temp = (char*) malloc ( sizeof ( char ) * 255);
strcpy(temp, Pass);
int length=strlen(Pass);
for (int i = length-1; i >= 0; i--) //переворачиваем пароль
{
Pass[length - 1 - i] = temp[i];
}
Pass[length] = '\0';
free(temp);
return;
}
//ф-ция выполняющая проверку логина и пароля и идентификацию пользователя
void CheckUnamePass(char *uname, char *pass)
{
int flag=1; //объявляем переменную-флаг, которая будет служить индикатором ошибок и инициализируем ошибкой
int counter=0; //объявляем переменную-счётчик строк с данными
FILE* users=fopen("users.txt", "r"); //открываем файл с учетными данными в режиме чтения
if (users==0) //если файл не открывается, то выводим на экран ошибку
{
printf ("\nНевозможно открыть файл с учётными данными!");
flag=4;
return;
}
int i=0;
int j=0;
char str_file[255][255]; //заводим двумерный символьный массив для хранения учётных данных
char*temp=(char*)malloc(sizeof(char)*255); //заводим временную переменную для переноса учётных данных из файла в массив str_file
//посимвольно переносим данные из файла в массив str_file
while (feof(users)==0)
{
fscanf(users, "%c", &temp[i]);
i++;
if (temp[i-1]=='\n')
{
temp[i-1]='\0';
strcpy(str_file[j], temp);
i=0;
j++;
counter++;
}
}
fclose(users); //закрываем файл
free(temp);
counter--; //убираем лишнюю строку о_О (огрехи переноса данных из файла users.txt в массив str_file)
int n_str=0; //объявляем переменную-идентификатор данных пользователя (т.н. номер пользователя)
for (int k=0; k<=counter; k++) //сравниваем введённые данные с теми, что хранились в текстовом файле
{
if (k%2==0)
{
if (strcmp(str_file[k], uname)==0) {flag=0;}
else if (strcmp(str_file[k], uname)!=0) {flag=1;}
}
else
{
if (strcmp(str_file[k], pass)==0&&flag==0) {n_str=k/2; break;}
else if (strcmp(str_file[k], pass)==0&&flag==1) {continue;}
else if (strcmp(str_file[k], pass)!=0&&flag==1) {continue;}
}
}
if (flag==0)
{
printf("\n\nChecking username - OK\nChecking password - OK\n\nДобро пожаловать, пользователь №%d\n", n_str);
Menu(n_str);
}
else
{
printf("\nНеверный логин или неверный пароль!");
getch();
}
return;
}
void Menu(int n) //ф-ция, отвечающая за вывод меню и обработку введённой команды
{
int * mas=(int*)malloc(sizeof(int)*50); //объявляем массив целых чисел, в котором будут храниться числовые данные пользователя
Load_data:
FILE* data=fopen("data.txt", "r"); //открываем файл с числовыми данными пользователей в режиме чтения
if (data==NULL) //если файл не открывается, то выводим на экран ошибку
{
printf ("\nНевозможно открыть файл с числовыми данными!");
return;
}
int i=0; //счётчик строк в файле данных
char temparr[255];
//загружаем данные пользователя в целочисленный одномерный массив
while (feof(data)==0)
{
fgets(temparr, 255, data);
FILE*tempfile=fopen("tempfile.txt", "w");
fprintf(tempfile, "%s", temparr);
fclose(tempfile);
if (i==n) {mas=Getmas("tempfile.txt"); break;}
i++;
}
fclose(data); //закрываем файл
//выводим меню на экран
Menu:
printf("\n\n * * * Что Вы хотите сделать? * * *");
printf("\n\n1. Вывод элементов массива X");
printf("\n2. Добавление нового элемента в конец массива X");
printf("\n3. Удаление элемента из массива X");
printf("\n4. Расчитать и вывести среднее арифметическое элементов массива X");
printf("\n5. Расчёт элементов массива Y по формуле Yi=G(Xi) и вывод их пользователю");
printf("\n6. Выход");
printf("\n\nВведите номер требуемого действия: ");
Action:
char item=getch();
if (item=='1')
{
printf("1");
ArrOutput(mas);
system("cls");
goto Menu;
}
else if (item=='2')
{
printf("2");
ArrAddItem(mas, n);
system("cls");
goto Load_data;
}
else if (item=='3')
{
printf("3");
ArrDelItem(mas, n);
system("cls");
goto Load_data;
}
else if (item=='4')
{
printf("4");
CountMasX(mas);
system("cls");
goto Menu;
}
else if (item=='5')
{
printf("5");
CountMasY(mas);
system("cls");
goto Menu;
}
else if (item=='6')
{
printf("6");
}
else goto Action;
remove("tempfile.txt");
free(mas);
}
//ф-ция, выполняющая поиск массива конкретного пользователя в файле и его вывод
void ArrOutput (int *arr)
{
int n=GetNumber("tempfile.txt");
printf("\n\nМассив X[%d]:", n);
for (int i=0; i<n; i++)
{
printf("\nX[%d]=%i", i, arr[i]);
}
printf("\n");
getch();
return;
}
//ф-ция, выполняющая добавление нового элемента в конец массива Х
void ArrAddItem(int *arr, int n_user)
{
int n=GetNumber("tempfile.txt"); //кол-во чисел
int add_elem=0;
printf("\n\nВведите добавляемый элемент: ");
scanf("%i", &add_elem);
arr[n]=add_elem;
n++;
WriteData(arr, n, n_user);
getch();
return;
}
//ф-ция, выполняющая удаление элемента из массива Х
void ArrDelItem(int *arr, int n_user)
{
int*arr_temp=(int*)malloc(sizeof(int)*255);
int n=GetNumber("tempfile.txt"); //кол-во чисел
int del_elem=-1;
ArrOutput(arr);
while (del_elem<0||del_elem>(n-1))
{
printf("\n\nВведите индекс удаляемого элемента: ");
scanf("%i", &del_elem);
}
for (int k=0; k<n; k++)
{
if (k==del_elem) continue;
else
{
arr_temp[k]=arr[k];
}
}
n--;
WriteData(arr_temp, n, n_user);
getch();
free(arr_temp);
return;
}
//подсчёт и вывод среднего арифметического
void CountMasX (int *arr)
{
int n=GetNumber("tempfile.txt");
float sred=0;
for (int i=0; i<n; i++)
{
sred+=arr[i];
}
sred=sred/n;
printf("\n\nСреднее арифметическое элементов массива X[%i]: %f\n", n, sred);
getch();
return;
}
//расчёт и вывод элементов массива Y
void CountMasY (int *arr)
{
int n = GetNumber("tempfile.txt");
double masY[50];
double temp=0;
printf("\n\nМассив Y[%i]:", n);
for (int i=0; i<n; i++)
{
temp=arr[i];
if (temp>0&&temp<=50) masY[i]=1. - (31./temp);
else if (temp>50) masY[i]=sqrt(temp)/(temp-5);
else masY[i]=(-3)*temp*temp + 19*temp;
printf ("\nY[%i]=%.3lf", i, masY[i]);
}
getch();
return;
}
//ф-ция, выполняющая перезапись файла с пользовательскими данными
void WriteData(int * userarr, int number_digits, int usernumber)
{
FILE * data=fopen("data.txt", "r"); //открываем файл с числовыми данными пользователей в режиме чтения
if (data==NULL) //если файл не открывается, то выводим на экран ошибку
{
printf ("\nНевозможно открыть файл с числовыми данными!");
return;
}
int i=0; //счётчик строк в файле данных
char temparr[255][255]; //двумерный массив для хранения данных из файла
//заполняем весь массив символами конца строки, т.к. fgets() их не добавляет
//начало фрагмента быдло-кода
for (int a=0; a<255; a++)
{
for (int b=0; b<255; b++)
{
temparr[a][b]='\0';
}
}
//конец фрагмента быдло-кода
//считываем содержимое файла "data.txt" в промежуточный двумерный символьный массив
while (feof(data)==0)
{
fgets(temparr[i], 255, data);
i+=1;
}
fclose(data); //закрываем файл
remove("data.txt"); //удаляем файл data.txt
data=fopen("data.txt", "w");
int j=0;
int k=0;
while (k<=i)
{
if (k==usernumber) //если номер рассматриваемой строки массива temparr совпадает с номером пользователя
//тогда записываем в файл data.txt строку из чисел из вещественного массива пользователя
{
while (j<number_digits)
{
fprintf(data,"%i_", userarr[j]);
j++;
}
fprintf(data, "\n");
}
else //если номер рассматриваемой строки не совпадает с номером пользователя
//тогда записываем в файл data.txt соответствующую строку из массива temparr
{
fprintf(data, "%s", temparr[k]);
}
fprintf(data, "\r");
k++;
}
fclose(data);
printf("\nСделано");
return;
}
-
Контрольный пример
Cодержимое файла «users.txt»:
admin
54321
sasha
321
alex
543
Cодержимое файла «users.txt»:
1_-4_3_5_7_-9_15_60_-4_-8_
16_17_-3_16_1_75_5_2_3_4_7_0_12_
27_-7_1_8_-3_97_6_
6_0_-1_-3_4_-4_-2_3_4_
12_-8_-3_4_-4_-2_3_4_5_7_-6_
-
Выводы о проделанной работе
При выполнении данной лабораторной работы мной были приобретены навыки работы с файлами, считывать и записывать информацию. Кроме того, мной были получены навыки работы с динамическими массивами и указателями.
-
Список использованной литературы
-
Шилдт Г. Искусство программирования на C++. БХВ.2005
-
Шилдт Г. C++ Руководство для начинающих. Вильямс.2005
-
Страуструп Б. Язык программирования С++. Специальное издание, 3-изд. Бином.2004