МУ_ЛР7_ОП (1079938), страница 5
Текст из файла (страница 5)
fclose( pF );
};
…
// Прототипы для WR – fwrite –fread
void StudMasToFileWR( const char * FileName , Student * pMas , int Razm);
void StudPrintFileWR( const char * FileName)ж
…
// Определение размера файла
FILE * pF;
Student * pStudMas;
Student SMas[] ={{"Первый" , 1 , 1000.0}, {"Второй" , 2 , 2000.0}, {"Третий" , 3 , 3000.0}, {"Четвертый" , 4 , 4000.0}};
…
RazmS = sizeof(SMas)/ sizeof(Student);
// Вызов функции , RazmS тоже д.б. известен
StudMasToFileWR( "BDStud4.bin" , SMas, RazmS);
StudPrintFileWR( "BDStud4.bin");
Результат работы программы:
Запись: Имя = Первый Номер = 1 Стипендия = 1000,00
Запись: Имя = Второй Номер = 2 Стипендия = 2000,00
Запись: Имя = Третий Номер = 3 Стипендия = 3000,00
Запись: Имя = Четвертый Номер = 4 Стипендия = 4000,00
Пример низкоуровневой перезаписи массива в файл приведен в приложении.
31 Запись из файла в массив (структуры).
В нашем случае используется функция печати файла (StudPrintMas), структуры (PrintStudent) и функция перезаписи файл в массив (StudFileToMasWR). Для примера используем структуру Student:
// Структура для демонстрации
struct Student {
char Name[20];
int Num;
float Oklad;
};
// Выборка из файла в динамический массив WR
void StudFileToMasWR( const char * FileName , Student ** pMas , int * pRazm)
{
FILE * pF;
pF = fopen( FileName , "rb"); // Открытие файла для чтения
*pRazm = _filelength(pF ->_file) /sizeof(Student);
Student SBuf;
int i = 0;
while (!feof(pF) ) // Проверка конца файла
{
fread( &SBuf, sizeof(Student) , 1, pF); // чтение одной записи
if ( !feof(pF) )
{ memcpy( *pMas + i , &SBuf , sizeof(Student)); i++; };
};
// Закрытие файла
fclose( pF );
};
// Распечатка отдельной структурной переменной студента
void PrintStudent(Student * pS)
{
printf( "Запись: Имя = %-15s Номер = %2d Стипендия = %8.2lf \n",
pS->Name , pS->Num, pS->Oklad );
};
// Печать массива структур
void StudPrintMas( Student * pMas , int Razm)
{
for (int i = 0 ; i < Razm ; i++ )
{
PrintStudent(pMas + i);
};
};
//
…
// Прототипы
void StudPrintMas( Student * pMas , int Razm);
void StudFileToMasWR( const char * FileName , Student ** pMas , int * pRazm);
…
// Если файл защищен от записи (после низкоуровневой записи!), то изменим его атрибут
system("attrib -R BDStud.bin ");
// Временное открытие файла для определение размера файла
FILE * pF;
pF = fopen( "BDStudbin", "r+b"); // Открытие файла для записи
// Вычисление числа записей через функцию _filelength
int RazmS = _filelength(pFBin)/sizeof(Student); // число записей в файле!
fclose(pF);
…
///// Функция файл в массив структур Student
StudFileToMasWR( "BDStud.bin" , &pStudMas , &RazmS);
StudPrintMas( pStudMas , RazmS);
Результат работы программы:
Запись: Имя = Первый Номер = 1 Стипендия = 1000,00
Запись: Имя = Второй Номер = 2 Стипендия = 2000,00
Запись: Имя = Третий Номер = 3 Стипендия = 3000,00
Запись: Имя = Четвертый Номер = 4 Стипендия = 4000,00
Пример низкоуровневой перезаписи файла в массив приведен в приложении.
32 Распечатка массива структур.
В нашем случае используется функции печати файла (StudPrintMas) и печати одной структуры (PrintStudent).
// Распечатка отдельной структурной переменной студента
void PrintStudent(Student * pS)
{
printf( "Запись: Имя = %-15s Номер = %2d Стипендия = %8.2lf \n",
pS->Name , pS->Num, pS->Oklad );
};
// Функция распечатки массива струтур
void StudPrintMas( Student * pMas , int Razm)
{
for (int i = 0 ; i < Razm ; i++ )
{
PrintStudent(pMas + i);
};
};
// …
// Функция распечатки массива струтур
StudPrintMas( pStudMas , RazmS);
Запись: Имя = Первый Номер = 1 Стипендия = 1000,00
Запись: Имя = Второй Номер = 2 Стипендия = 2000,00
Запись: Имя = Третий Номер = 3 Стипендия = 3000,00
Запись: Имя = Четвертый Номер = 4 Стипендия = 4000,00
33 Распечатка файла структур.
В нашем случае используется функция печати файла (StudPrintFileWR):
// Печать файла для структуры Student
void StudPrintFileWR( const char * FileName)
{
FILE * pF;
pF = fopen( FileName , "rb"); // Открытие файла для чтения
Student SBuf;
while (!feof(pF) ) // Проверка конца файла
{
fread( &SBuf, sizeof(Student) , 1, pF); // чтение одной записи
if ( !feof(pF) )
PrintStudent(&SBuf);
};
// Закрытие файла
fclose( pF );
};
…
// Прототип функции
void StudPrintFileWR( const char * FileName);
…
// Печать файла по имени файла
StudPrintFileWR( "BDStud4.bin");
В нашем случае используется функция печати файла (StudPrintFileWR), структуры
Запись: Имя = Первый Номер = 1 Стипендия = 1000,00
Запись: Имя = Второй Номер = 2 Стипендия = 2000,00
Запись: Имя = Третий Номер = 3 Стипендия = 3000,00
Запись: Имя = Четвертый Номер = 4 Стипендия = 4000,00
34 Сортировка строк в массиве.
Сортировка выполняется на основе функции обмена записей (SwapStudent):
// обмен на основе адресов структурных переменных (возможет только без динамики!!)
void SwapStudent ( Student * pA , Student * pB )
{
Student Temp;
Temp = *pA;
*pA = *pB;
*pB = Temp;
/* можно и так
memcpy( Temp , *pA, sizeof(Student) );
memcpy( *pA , *pB, sizeof(Student) );
memcpy( *pB , Temp, sizeof(Student) );
*/
};
Сортировка выполняется на основе функции обмена записей (SwapStudent):
Сортировка в массиве pStudMas:
for (int i = 0 ; i < RazmS - 1 ; i++ )
for (int k = 0 ; k < RazmS - 1 ; k++ )
// Сортировка разные режимы!!!!!!!!!!!!!!!!!!!!!!!!!!!
// if ( ((Student *)(pStudMas + k))->Num < ((Student *)(pStudMas + k +1))->Num ) // Убывание курс
// if ( ((Student *)(pStudMas + k))->Num < ((Student *)(pStudMas + k +1))->Num ) // Убывание курс
if ( strcmp(((Student *)(pStudMas + k))->Name , ((Student *)(pStudMas + k +1))->Name) > 0 ) // Убывание имя
{ SwapStudent ( pStudMas + k , pStudMas + k+1 ); };
//
StudPrintMas( pStudMas , RazmS);
Результат сортировки массива:
Запись: Имя = Второй Номер = 2 Стипендия = 2000,00
Запись: Имя = Первый Номер = 1 Стипендия = 1000,00
Запись: Имя = Третий Номер = 3 Стипендия = 3000,00
Запись: Имя = Четвертый Номер = 4 Стипендия = 4000,00
35 Сортировка строк в файле по номеру.
Сортировка файла может быть выполнена так (см. предыдущие примеры):
-
Взять из файла в массив
-
Сортировка массива
-
Запись новая в файл
-
Распечатка файла
В программе это будет с использованием функций выглядеть так:
// СОРТИРОВКА
printf( "ДО СОРТИРОВКИ (по номеру)!\n" ); //
StudPrintFileWR( "BDStud4.bin");
StudFileToMasWR( "BDStud4.bin" , &pStudMas , &RazmS);
// Сортировка пузырьковая
// Сортировка массива по имени и номеру курса по убыванию/возрастанию
for (int i = 0 ; i < RazmS - 1 ; i++ )
for (int k = 0 ; k < RazmS - 1 ; k++ )
if ( ((Student *)(pStudMas + k))->Num < ((Student *)(pStudMas + k +1))->Num ) // Убывание { SwapStudent ( pStudMas + k , pStudMas + k+1 ); };
// В файл
StudMasToFileWR( "BDStud4.bin" , pStudMas, RazmS);
// Печать файла
printf( "ПОСЛЕ СОРТИРОВКИ!\n" ); //
StudPrintFileWR( "BDStud4.bin");
Результат сортировки файла:
ДО СОРТИРОВКИ (по номеру)!
Запись: Имя = Первый Номер = 1 Стипендия = 1000,00
Запись: Имя = Второй Номер = 2 Стипендия = 2000,00
Запись: Имя = Третий Номер = 3 Стипендия = 3000,00
Запись: Имя = Четвертый Номер = 4 Стипендия = 4000,00
ПОСЛЕ СОРТИРОВКИ!
Запись: Имя = Четвертый Номер = 4 Стипендия = 4000,00
Запись: Имя = Третий Номер = 3 Стипендия = 3000,00
Запись: Имя = Второй Номер = 2 Стипендия = 2000,00
Запись: Имя = Первый Номер = 1 Стипендия = 1000,00
36 Поиск и чтение записи по номеру.
Для поиска нужно проконтролировать номер записи (nFind):
// Поиск и чтение записи по номеру.
StudPrintFileWR( "BDStud.bin");
int nFind = 2 ;
int Pos1;
pF = fopen( "BDStud.bin" , "rb"); // Открытие файла для чтения
// Перемещение указателя
if (filelength(pF->_file)/sizeof(Student) >= nFind )
{
Pos1 = fseek( pF, (nFind - 1)*sizeof(Student), SEEK_SET); // Перемещение указателя на нужную запись для чтения
fread( &SBuf, sizeof(Student) , 1, pF); // чтение одной записи
PrintStudent(&SBuf);
}
else
printf( "Ошибка номера записи- %d !\n" , nFind ); // Ошибка номера
// Закрытие файла
fclose( pF );
Результат работы фрагмента текста (nFind = 2):
1 - Запись: Имя = Второй Номер = 2 Стипендия = 2000,00
2 - Запись: Имя = Первый Номер = 1 Стипендия = 1000,00
3 - Запись: Имя = Третий Номер = 3 Стипендия = 3000,00
4 - Запись: Имя = Четвертый Номер = 4 Стипендия = 4000,00
Запись: Имя = Первый Номер = 1 Стипендия = 1000,00
Результат работы фрагмента текста (nFind = 10):
1 - Запись: Имя = Второй Номер = 2 Стипендия = 2000,00
2 - Запись: Имя = Первый Номер = 1 Стипендия = 1000,00
3 - Запись: Имя = Третий Номер = 3 Стипендия = 3000,00
4 - Запись: Имя = Четвертый Номер = 4 Стипендия = 4000,00
Ошибка номера записи- 10 !
37 Удаление записи по номеру.
Для удаления одной записи из файла: считываем файл в массив, удаляем запись(номер удаляемой записи считается с 1-цы - NumDel), а затем перезаписываем массив в файл.
printf( "ДО УДАЛЕНИЯ (по номеру)!\n" ); //
StudPrintFileWR( "BDStud.bin");
Student * pMas;
int RazmF;
int NumDel = 2;
StudFileToMasWR( "BDStud.bin" , &pMas , &RazmF);
///
for ( int i = 0, k = 0 ; i < RazmF ; i++)
{
if ( (NumDel - 1) != i )
{ memcpy( pMas + k , pMas + i , sizeof(Student)); k++;}
};
///
StudMasToFileWR( "BDStud.bin" , pMas , ( RazmF > NumDel ) ? RazmF - 1 : RazmF );
printf( "ПОСЛЕ УДАЛЕНИЯ (по номеру)!\n" ); //
StudPrintFileWR( "BDStud.bin");
Результат работы фрагмента текста (NumDel = 2):
ДО УДАЛЕНИЯ (по номеру)!
Запись: Имя = Второй Номер = 2 Стипендия = 2000,00
Запись: Имя = Первый Номер = 1 Стипендия = 1000,00
Запись: Имя = Третий Номер = 3 Стипендия = 3000,00
Запись: Имя = Четвертый Номер = 4 Стипендия = 4000,00
ПОСЛЕ УДАЛЕНИЯ (по номеру)!
Запись: Имя = Второй Номер = 2 Стипендия = 2000,00
Запись: Имя = Третий Номер = 3 Стипендия = 3000,00
Запись: Имя = Четвертый Номер = 4 Стипендия = 4000,00
38 Добавление записи по номеру.
Для добавления записи в файл по номеру: считываем файл в массив, добавляем в массив запись (номер добавляемой записи считается с 1-цы - NumAdd), а затем перезаписываем массив в файл. Массив создаем по размеру на единицу больше чем размер файла.
//Добавление записи по номеру
printf( "ДО ДОБАВЛЕНИЯ (по номеру)!\n" ); //
StudPrintFileWR( "BDStud.bin");
int NumAdd = 2;
Student SAdd = {"ADDED" , 33 , 15.00};
StudFileToMasWR( "BDStud.bin" , &pMas , &RazmF);
Student * pMasNew;
pMasNew = ( Student * ) calloc( RazmF + 1 , sizeof(Student));
int p = 0;
int m =0 ;
for ( m = 0 ; m < RazmF ; m++ , p++)
{
if ( (NumAdd - 1) != p )
{ memcpy( pMasNew + p , pMas + m , sizeof(Student)); }
else
{ memcpy( pMasNew + p , &SAdd , sizeof(Student)); m--;}
};
if ( p == m )















