следующий предложенный код:
- безупречная компиляция
- выполняет желаемую функциональность
- правильно проверяет ошибки
- сообщает
main()
функция о том, сколько экземпляров struct tickets
было прочитано - информирует пользователя при возникновении любой ошибки
- убирает за собой
- устраняет один из вызовов
malloc()
- использует функцию:
fread()
, чтобы избежать проблем с little/big Endian
- документами, почему каждый заголовочный файл включен
- предполагает количество заявок (первые 4 байта файла) в двоичном формате
- содержит соответствующие горизонтальные и вертикальные интервалы для удобства чтения
предостережение: поскольку ни один пример входного файла не опубликован, этот код не тестируется
, и теперь предлагаемый код:
#include <stdio.h> // perror(), NULL, FILE*, EOF,
// fopen(), fclose(), fread()
#include <stdlib.h> // malloc(), free(), exit(), EXIT_FAILURE
#define MAX_PLANE_LEN 7
#define MAX_ZONA_LEN 13
#define COUNT_LEN 4
struct tickets
{
char plane [ MAX_PLANE_LEN ];
char zona [ MAX_ZONA_LEN ];
int rate;
int cost;
};
struct tickets* load( char * filename, size_t * ticketCount )
{
FILE * fp;
if ( ! (fp = fopen( filename, "r" )) )
{
perror( "Error occured while opening file" );
exit( EXIT_FAILURE );
}
size_t bytesRead = fread( ticketCount, 1, COUNT_LEN, fp );
if( bytesRead != COUNT_LEN )
{
fprintf( stderr, "failed to read count of number of instances of 'struct tickets'\n" );
fclose( fp );
exit( EXIT_FAILURE );
}
struct tickets* ptr = malloc( *ticketCount * sizeof( struct tickets ) );
if( ! ptr )
{
perror( "malloc failed" );
fclose( fp );
exit( EXIT_FAILURE );
}
for( size_t i = 0; i < *ticketCount; i++ )
{
size_t numBytes = fread( &(ptr[i]), 1, sizeof( struct tickets ), fp );
if( numBytes != sizeof( struct tickets ) )
{
perror( "read of a struct ticket failed" );
fclose( fp );
free( ptr );
exit( EXIT_FAILURE );
}
}
fclose( fp );
return ptr;
}
int main( void )
{
char * filename = "p.dat";
size_t ticketCount = 0;
struct tickets* ticket = load( filename, &ticketCount );
// ...
free( ticket );
}