#include <stdio.h>
#include <string.h> /* για memset() */
#include <stdlib.h> /* για exit(), calloc(), free(), κλπ */
#include <time.h> /* για time() */
#define MAXINBUF (254+1) /* μέγιστο μήκος γραμμής εισόδου */
#define TABLE_BUF_MINLEN 5 /* ελάχιστο πλήθος στοιχείων */
#define TABLE_BUF_EMPTYCELL (-1) /* για μαρκάρισμα κενών στοιχείων */
typedef enum { FALSE=0, TRUE } Bool; /* δικός μας πρόσθετος τύπος boolean */
typedef struct table { /* η βασική δομή του προγράμματος */
int bufmaxlen; /* ... μέγιστο πλήθος στοιχείων */
int buflen; /* ... τρέχον πλήθος στοιχείων */
int bufsize; /* ... μέγεθος στη μνήμη (σε bytes) */
int *buffer; /* ... ο πίνακας με τα στοιχεία */
} Table;
/* --------------------------------------------------------------------------------
* Αρχικοποιεί την δομή table με default τιμές βάσει του ορίσματος maxlen και
* δημιουργεί το buffer της στη μνήμη.
* Επιστρέφει FALSE σε περίπτωση που αποτύχει η δημιουργία του buffer ή αν το όρισμα
* table περαστεί στη συνάρτηση με τιμή NULL, αλλιώς επιστρέφει TRUE.
* --------------------------------------------------------------------------------
*/
Bool table_init( Table *table, const int maxlen )
{
if ( !table ) /* έλεγχος ασφαλείας */
return FALSE; /* ... πρόωρη έξοδος */
/* μέγιστο πλήθος στοιχείων */
table->bufmaxlen = maxlen < TABLE_BUF_MINLEN ? TABLE_BUF_MINLEN : maxlen;
table->buflen = 0; /* τρέχον πλήθος στοιχείων */
table->bufsize = table->bufmaxlen * sizeof(int);/* μεγέθος στη μνήμη σε bytes */
table
->buffer
= malloc( table
->bufsize
); /* δέσμευση μνήμης για buffer */ if ( !table->buffer ) { /* αποτυχία δέσμευσης μνήμης */
table->bufsize = 0; /* ... μηδενισμός μεγέθους */
return FALSE; /* ... επιστροφή αποτυχίας */
}
/* γέμισμα του buffer με TABLE_BUF_EMPTYCELL */
memset( table
->buffer
, TABLE_BUF_EMPTYCELL
, table
->bufsize
);
return TRUE; /* επιστροφή επιτυχίας */
}
/* --------------------------------------------------------------------------------
* Μηδενίζει τα πεδία της δομής table, αποδεσμεύοντας και τη μνήμη του buffer.
* Επιστρέφει FALSE αν το όρισμα table περαστεί στη συνάρτηση με τιμή NULL, αλλιώς
* επιστρέφει TRUE.
* --------------------------------------------------------------------------------
*/
Bool table_cleanup( Table *table )
{
if ( !table ) /* έλεγχος ασφαλείας */
return FALSE; /* ... πρόωρη έξοδος */
if ( table->buffer ) { /* το buffer δεν είναι NULL */
free( table
->buffer
); /* ... αποδέσμευση της μνήμης */ table->buffer = NULL; /* ... μηδενισμός του δείκτη */
}
/* μηδενισμός και των υπόλοιπων*/
table->bufmaxlen = table->buflen = table->bufsize = 0;
return TRUE;
}
/* --------------------------------------------------------------------------------
* Γεμίζει το buffer της δομής table με ψευδοτυχαίες τιμές από 0 έως maxval (από το
* πρώτο κενό στοιχείο έως το τέλος).
* Σε περίπτωση επιτυχίας ενημερώνει το τρέχον μήκος του buffer στη δομή κι επιστρέφει
* TRUE. FALSE επιστρέφει όταν το buffer είναι ήδη γεμάτο ή δεν υπάρχει καν ή όταν το
* όρισμα table περαστεί στη συνάρτηση με τιμή NULL.
* --------------------------------------------------------------------------------
*/
Bool table_fill_randomly( Table *table, const int maxval )
{
/* ********************************************************************
* γράψτε εδώ τον κώδικα της συνάρτησης, σύμφωνα με τα παραπάνω σχόλια!
*/
return TRUE;
}
/* --------------------------------------------------------------------------------
* Τυπώνει στατιστικά σχετικά με το buffer της δομής table: μέγιστη χωρητικότητα σε
* στοιχεία, πλήθος γεμάτων στοιχείων και μέγεθος που καταλαμβάνει σε bytes το buffer
* στη μνήμη.
* Επιστρέφει FALSE αν το όρισμα table περαστεί στη συνάρτηση με τιμή NULL, αλλιώς
* επιστρέφει TRUE.
* --------------------------------------------------------------------------------
*/
Bool table_print_info( Table table )
{
if ( !table.buffer ) { /* έλεγχος ασφαλείας */
puts("Δεν βρέθηκε δημιουργημένος πίνακας!\n"); return FALSE; /* ... πρόωρη έξοδος */
}
printf("\n\tΜέγιστη χωρητικότητα:\t\t%d στοιχεία\n", table.
bufmaxlen ); printf("\tΠλήθος γεμάτων στοιχείων:\t%d\n", table.
buflen ); printf("\tΜέγεθος πίνακα στη μνήμη:\t%d bytes\n", table.
bufsize );
return TRUE;
}
/* --------------------------------------------------------------------------------
* Τυπώνει τα μη κενά στοιχεία του buffer της δομής table.
* Επιστρέφει FALSE αν δεν υπάρχει δημιουργημένο buffer, αλλιώς επιστρέφει TRUE.
* --------------------------------------------------------------------------------
*/
Bool table_print_buffer( Table table )
{
register int i = 0;
if ( !table.buffer ) { /* έλεγχος ασφαλείας */
puts("Δεν βρέθηκε δημιουργημένος πίνακας!\n"); return FALSE; /* ... πρόωρη έξοδος */
}
for (i=0; i < table.buflen; i++) /* τύπωμα των στοιχείων */
printf("%d ", table.
buffer[i
] );
return TRUE;
}
/* --------------------------------------------------------------------------------
* Διαβάζει από την κύρια είσοδο το μέγιστο πλήθος στοιχείων και το επιστρέφει
* (απαιτεί το μέγιστο πλήθος να είναι μεγαλύτερο ή ίσο του TABLE_BUF_MINLEN).
* --------------------------------------------------------------------------------
*/
int askuser_maxlen( void )
{
char inbuf[ MAXINBUF ] = {'\0'}; /* δική μας γραμμή κύριας εισόδου */
int maxlen; /* η τιμή επιστροφής της συνάρτησης */
do { /* απαίτηση πλήθους στοιχείων μεγαλύτερου από TABLE_BUF_MINLEN */
printf("Μέγιστο πλήθος στοιχείων (τουλάχιστον %d): ", TABLE_BUF_MINLEN
); fgets( inbuf
, MAXINBUF
, stdin
); } while ( maxlen < TABLE_BUF_MINLEN );
return maxlen;
}
/* --------------------------------------------------------------------------------
*
* --------------------------------------------------------------------------------
*/
int main( void )
{
Table table; /* η βασική μας δομή */
int maxlen = askuser_maxlen(); /* διάσβασμα μέγιστου πλήθους στοιχείων*/
if ( !table_init( &table, maxlen ) ) /* αποτυχία αρχικοποίησης της δομής */
{ /* ... */
puts("*** αδυναμία δημιουργίας πίνακα, τερματισμός προγράμματος..." ); exit( EXIT_FAILURE
); /* ... τερματισμός αποτυχίας */ }
puts("\nΟ πίνακας δημιουργήθηκε & αρχικοποιήθηκε επιτυχώς!");
srand( time(NULL
) ); /* ενεργοποίηση γεννήτριας ψευδοτυχαίων*/
table_print_info( table ); /* τύπωμα στατιστικών */
#if 0 /* ΠΡΟΣΩΡΙΝΑ ΑΠΕΝΕΡΓΟΠΟΙΗΜΕΝΕΣ ΓΡΑΜΜΕΣ ΚΩΔΙΚΑ */
if ( !table_fill_randomly( &table, 234 ) )
puts("*** σφάλμα τυχαίου γέμισματος του πίνακα ( ήταν ήδη γεμάτος; )\n"); table_print_info( table ); /* τύπωμα στατιστικών */
#endif
table_print_buffer( table ); /* τύπωμα περιεχομένων του buffer */
table_cleanup( &table ); /* μηδενισμός δομής, αποδέσμευση buffer*/
exit( EXIT_SUCCESS
); /* τερματισμός επιτυχίας */ }