Консультация № 176579
08.02.2010, 21:31
0.00 руб.
0 2 1
Для хранения данных о планшетных сканерах описать структуру вида:
struct scan_info{
char model[25]; // наименование модели
int price: // цена
double x_s1ze: // горизонтальный размер области сканирования
double y__s1ze: // вертикальный размер области сканирования
1nt optr: // оптическое разрешение
int grey: // число градаций серого
}:
Написать функцию, которая записывает в бинарный файл данные о сканере из
приведенной структуры. Структура файла: в первых двух байтах размещается
значение тина int, определяющее количество сделанных в файл записей; далее
без пропусков размещаются записи о сканерах.
Написать функцию, которая сортирует записи в описанном выше бинарном файле
по одной из следующих характеристик: цена либо число градаций серого. Обязательный
параметр — признак, задающий критерий сортировки.
Привести пример программы, создающей файл с данными о сканерах (данные
вводятся с клавиатуры) из не менее восьми записей и осуществляющий его сортировку.
Все необходимые данные для функций должны передаваться им в качестве параметров.
Использование глобальных переменных в функциях не допускается.

Обсуждение

Неизвестный
08.02.2010, 21:55
общий
nasya:
На С или С++? Компилятор имеет значение?
Неизвестный
08.02.2010, 23:58
общий
это ответ
Здравствуйте, nasya.
Ну, приведу один из вариантов решения задачи, записи будем просто считывать в массив (для реально большого количества записей этот метод может оказаться недопустимым из-за объёма памяти). Поскольку ничего по этому поводу не сказано, скомпилировано в Visual Studio 2005.
Во-первых, о количестве записей. В VS тип int имеет размерность 4 байта, поскольку у Вас в задаче требуется использовать два первых байта, то для размерности используется тип short, который имеет размерность 2 байта в этой среде.
Во-вторых, о сортировке. О необходимом методе сортировки в вашей задаче ничего не сказано, в моём примере используется функция из стандартной библиотеки stdlib.h qsort, осуществляющая "быструю сортировку" массива с использованием заданной функции сравнения. Она имеет такой вид:
Код:
void qsort(
void *base, //массив
size_t num, //размер массива
size_t width, //размер одного элемента в массиве
int (__cdecl *compare )(const void *, const void *) //функция сравнения элементов массива
);

Функции сортировки используются две - для сортировки по цене и по градациям серого. Подробнее о самой функции можете почитать в MSDN.
Для выбора направления сортировки создан enum. Для контроля сортировки сделана функция, выводящая часть данных записей.
В остальном можно разобраться по комментариям.
Удачи!

Приложение:
#include <conio.h>
#include <stdlib.h>

struct scan_info {
char model[25]; // наименование модели
int price; // цена
double x_size; // горизонтальный размер области сканирования
double y__size; // вертикальный размер области сканирования
int optr; // оптическое разрешение
int grey; // число градаций серого
};

enum CompareIndicator { //критерии сортировки
CIPrice = 0,
CIGrey = 1
};

void Print (scan_info* si, int count) //вывод записей на экран
{
for (int i=0; i<count; i++)
printf ("\n%i. %s price: %i grey: %i", i+1, si[i].model, si[i].price, si[i].grey);
}

int ComparePrice (const void *arg1, const void *arg2) //сравнение по цене
{
if (((scan_info*)arg1)->price < ((scan_info*)arg2)->price) return -1;
else if (((scan_info*)arg1)->price > ((scan_info*)arg2)->price) return 1;
else return 0;
}

int CompareGrey (const void *arg1, const void *arg2) //сравнение по градациям серого
{
if (((scan_info*)arg1)->grey < ((scan_info*)arg2)->grey) return -1;
else if (((scan_info*)arg1)->grey > ((scan_info*)arg2)->grey) return 1;
else return 0;
}

void Sort (scan_info* si, int count, CompareIndicator ci) //сортировка через qsort
{
switch (ci) {
case CIPrice:
qsort (si, count, sizeof(scan_info), ComparePrice);
break;
case CIGrey:
qsort (si, count, sizeof(scan_info), CompareGrey);
break;
}
}

void SortInFile (char* fname, CompareIndicator ci) //сортировка записей из файла
{
FILE* f = fopen (fname, "r+b"); //открываем файл
if (!f) { //ошибка, если не открылся
printf ("Error");
return;
}
short count; //читаем количество записей
int k = fread (&count, sizeof(short), 1, f);
if (k!=1) { //ошибка, если считалось неверное количество данных
printf ("Error");
return;
}
scan_info* si = new scan_info[count]; //выделяем место под массив
k = fread (si, sizeof(scan_info), count, f); //считываем массив
if (k!=count) {
printf ("Error");
return;
}
Sort (si, count, ci); //сортируем его
Print (si, count); //выводим на экран для контроля
fseek (f, sizeof(short), SEEK_SET); //переходим в начало файла
k = fwrite (si, sizeof(scan_info), count, f); //пишем отсортированный массив
fclose (f); //закрываем файл
}

void CreateFile (char* fname) //создание файла
{
short n = 0; //количество записей
scan_info si;
FILE* f = fopen (fname, "wb");
if (!f) {
printf ("Error");
return;
}
int k = fwrite (&n, sizeof(short), 1, f); //пока пишем 0 в файл
if (k!=1) {
printf ("Error");
return;
}
char c = 'y'; //признак выхода из цикла
while (c=='y') { //вводим записи
printf ("\nInput new record.\nInput model:\n");
scanf ("%s", &si.model);
printf ("\nInput price:\n");
scanf ("%d", &si.price);
printf ("\nInput horizontal size:\n");
scanf ("%f", &si.x_size);
printf ("\nInput vertical size:\n");
scanf ("%f", &si.y__size);
printf ("\nInput optical resolution:\n");
scanf ("%d", &si.optr);
printf ("\nInput shade of grey:\n");
scanf ("%d", &si.grey);
k = fwrite (&si, sizeof(si), 1, f); //пишем запись в файл
if (k!=1) {
printf ("Error");
return;
}
n++; //наращиваем количество
if (n>=8) { //если 8 записей уже введено, то предлагаем прервать ввод
printf ("\nPress \'y\', if you want to continue, or any other key, if you don\'t\n");
c = getch(); //если будет введён не у, то выйдем из цикла
}
}
fclose (f); //переоткрываем файл для дозаписи
f = fopen (fname, "r+b");
if (!f) {
printf ("Error");
return;
}
k = fwrite (&n, sizeof(short), 1, f); //пишем реальное количество записей
if (k!=1) {
printf ("Error");
return;
}
fclose (f); //закрываем файл
}

int _tmain(int argc, _TCHAR* argv[])
{ //пример
CreateFile ("c:\\scans"); //создаём файл
SortInFile ("c:\\scans", CIPrice); //сортируем по цене
getch(); //ожидаем пользователя
return 0;
}
Форма ответа