/* =========================================================================
* Από: migf1
* Πρόγραμμα παρουσίασης απλών λειτουργιών σε πίνακα, γραμμένο σε C.
* =========================================================================
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_ELEMENTS 10 // μέγιστο πλήθος στοιχείων
#define EMPTY_ELEMVAL (-1) // τιμή κενών στοιχείων
#define MAX_INBUF 256 // μέγιστο μήκος γραμμής εισόδου
#define MAX_COMMANDS 11 // μέγιστο πληθος εντολών
#define MAX_CMDLEN (5+1) // μέγιστο μήκος εντολής
#define MAX_TOKENS (MAX_ELEMENTS+1) // μέγιστο πλήθος παραμέτρων σε
// μια εντολή + την εντολή
#define SET_ISEMPTY(set) ( (set).len == 0 ) // έλέγχος για κενή λίστα
// έλέγχος για γεμάτη λίστα
#define SET_ISFULL(set) ( (set).len == (set).maxlen )
typedef enum { FALSE=0, TRUE } Bool; // ο δικός μας τύπος boolean
typedef enum { // κωδικοί εντολών
CMD_INVALID = -1,
CMD_INS_APPEND,
CMD_INS_PREPEND,
CMD_INS_ASCEND,
CMD_INS_DESCEND,
CMD_DELETE,
CMD_SRT_ASCEND,
CMD_SRT_DESCEND,
CMD_RESET,
CMD_PRINT,
CMD_HELP,
CMD_EXIT
}CmdIndex;
typedef struct set { // δομή για τη λίστα ακεραίων
int maxlen; // μέγιστο μήκος λίστας
int len; // τρέχον μήκος λίστας
int elem[MAX_ELEMENTS]; // η λίστα (πίνακας)
} Set;
// -------------------------------------------------------------------------------------
// Διάσπαση του c-string s σε έως maxtokens τμήματα, κι αποθήκευσή τους στον πίνακα
// tokens (η διάσπαση γίνεται σύμφωνα με οποιονδήποτε από του χαρακτήρες στο c-string
// delimiters). Επιστρέφει το πλήθος των τμημάτων που προέκυψαν από την διάσπαση.
// -------------------------------------------------------------------------------------
int s_tokenize(char *s, char *tokens[], const int maxtokens, const char *delimiters)
{
register int i=0;
tokens
[0] = strtok(s
, delimiters
); if (tokens[0] == NULL)
return 0;
for (i
=1; i
< maxtokens
&& (tokens
[i
]=strtok(NULL
, delimiters
)) != NULL
; i
++) ;
return i;
}
// -------------------------------------------------------------------------------------
// Μετατροπή εντολής από c-string σε κωδικό εντολής (επιστρέφει τον κωδικό της εντολής)
// ΣΗΜΑΝΤΙΚΟ:
// ο κωδικός εντολής ισοδυναμεί με τη θέση της στον πίνακα των εντολών (δείτε
// στην αρχή της main() )
// -------------------------------------------------------------------------------------
CmdIndex cmd_getindex( const char *cmd, const char *commands[], const int maxcommands )
{
register int i;
for (i
=0; i
< maxcommands
&& strcmp(cmd
, commands
[i
]); i
++) ;
return i == maxcommands ? -1 : i;
}
// -------------------------------------------------------------------------------------
// Διάβασμα γραμμής εισόδου, διάσπασή της σε εντολή με παραμέτρους κι αποθήκευσή τους
// στον πίνακα tokens[] (επιστρέφει τον κωδικό της εντολής)
// -------------------------------------------------------------------------------------
int get_input( int *ntokens, char *tokens[], const int maxtokens, const char *commands[], const int maxcommands)
{
char inbuf[ MAX_INBUF ] = ""; // η γραμμή εισόδου
CmdIndex cmdcode; // κωδικός εντολής
do {
cmdcode = CMD_INVALID; // αρχικοποίηση
printf("> "); // εμφάνιση prompt fgets(inbuf
, MAX_INBUF
, stdin
); // διάβασμα γραμμής εισόδου // διάσπαση σε εντολή & παραμέτρους
*ntokens = s_tokenize(inbuf, tokens, maxtokens, "\t \n");
if ( *ntokens > 0 ) // μετατροπήυ σε κωδικό εντολής
cmdcode = cmd_getindex(tokens[0], commands, maxcommands);
if (cmdcode == CMD_INVALID) // ανύπαρκτη εντολή
puts("\tunrecognized command\n"); } while( cmdcode == CMD_INVALID); // απαίτηση υπαρκτής εντολής
return cmdcode; // επιστροφή κωδικού εντολής
}
// -------------------------------------------------------------------------------------
// Αρχικοποίηση της λίστας
// -------------------------------------------------------------------------------------
void set_init( Set *set )
{
register int i;
set->maxlen = MAX_ELEMENTS;
for (i=0; i < set->maxlen; i++)
set->elem[i] = EMPTY_ELEMVAL;
set->len = 0;
return;
}
// -------------------------------------------------------------------------------------
// Εμφάνιση όλων των στοιχείων της λίστας (επιστρέφει FALSE αν η λίστα είναι κενή,
// αλλιώς επιστρέφει TRUE)
// -------------------------------------------------------------------------------------
Bool set_print( Set set )
{
register int i;
for (i=0; i < set.len; i++)
return i == 0 ? FALSE : TRUE;
}
// -------------------------------------------------------------------------------------
// Επιστρέφει 0 αν τα n1 και n2 είναι ίσα, 1 αν το n1 > n2 ή -1 αν το n1 < n2
// ( χρησιμοποιείται στη στάνταρ συνάρτηση qsort() παρακάτω )
// -------------------------------------------------------------------------------------
int set_elemcmp(const void *n1, const void *n2)
{
const int *a = (const int *) n1;
const int *b = (const int *) n2;
return (*a > *b) - (*a < *b);
}
// -------------------------------------------------------------------------------------
// Εισαγωγή νέου στοιχείου με τιμή val στο τέλος της λίστας (επιστρέφει είτε τη
// θέση στην οποία εισήχθη το νέο στοιχειο, είτε -1 σε περίπτωση που η λίστα ήταν
// ήδη γεμάτη, είτε -2 αν η τιμή val ισούται με την τιμή μηδενισμού EMPTY_ELEMVAL)
// -------------------------------------------------------------------------------------
int set_append( Set *set, const int val )
{
if ( val == EMPTY_ELEMVAL ) // η μηδενική τιμή δεν εισάγεται
return -2; // επιστροφή αποτυχίας
if ( SET_ISFULL(*set) ) // σε γεμάτο πίνακα...
return -1; // επιστροφή αποτυχίας
set->elem[ set->len ] = val;
return (set->len)++; // επιστροφή θέσης εισαγωγής
}
// -------------------------------------------------------------------------------------
// Εισαγωγή νέου στοιχείου με τιμή val στην αρχή της λίστας (επιστρέφει είτε 0 σε
// περίπτωση που η λίστα ήταν ήδη γεμάτη, ειτε -1 αν η τιμή val ισούται με την τιμή
// μηδενισμού EMPTY_ELEMVAL, είτε 1 αν όλα πήγαν καλά)
// -------------------------------------------------------------------------------------
int set_prepend( Set *set, const int val )
{
if ( val == EMPTY_ELEMVAL ) // η μηδενική τιμή δεν εισάγεται
return -1; // επιστροφή αποτυχίας
if ( SET_ISFULL(*set) ) // σε γεμάτη λίστα
return 0; // επιστροφή αποτυχίας
if ( SET_ISEMPTY(*set) ) { // σε κενή λίστα
set->elem[0] = val; // εισαγωγή νέου στοιχείου
(set->len)++; // ενημέρωση τρέχοντος μήκους
return 1; // επιστροφή επιτυχίας
}
// μετακίνηση των στοιχείων μια θέση προς τα δεξιά, ξεκινώντας από το 1ο
memmove( &(set
->elem
[1]), &(set
->elem
[0]), (set
->len
) * sizeof(int) ); set->elem[0] = val; // εισαγωγή νέου στοιχείου
(set->len)++; // ενημέρωση τρέχοντος μήκους
return 1; // επιστροφή επιτυχίας
}
// -------------------------------------------------------------------------------------
// Εισαγωγή νέου στοιχείου με τιμή val απευθείας στη σωστή θέση, σε λίστα που είναι
// ήδη ταξινομημένη με αύξουσα σειρά
// -------------------------------------------------------------------------------------
int set_insascend( Set *set, const int val )
{
if ( val == EMPTY_ELEMVAL ) // η μηδενική τιμή δεν εισάγεται
return -2; // επιστροφή αποτυχίας
if ( SET_ISFULL(*set) ) // σε γεμάτη λίστα
return -1; // επιστροφή αποτυχίας
if ( SET_ISEMPTY(*set) ) { // σε κενή λίστα...
set->elem[0] = val; // εισαγωγή στην αρχή της
set->len = 1; // ενημέρωση τρέχοντος μήκους
return 0; // επιστροφή 1ης θέσης
}
register int i;
for (i=0; val > set->elem[i] && i < set->len; i++)
;
// μετακίνηση των στοιχείων μια θέση προς τα δεξιά, ξεκινώντας από το στοιχείο i
memmove( &(set
->elem
[i
+1]), &(set
->elem
[i
]), (set
->len
-i
) * sizeof(int) );
set->elem[i] = val; // εισαγωγή νέου στοιχείου
(set->len)++; // ενημέρωση τρέχοντος μήκους
return i; // επιστροφή θέσης εισαγωγής
}
// -------------------------------------------------------------------------------------
// Εισαγωγή νέου στοιχείου με τιμή val απευθείας στη σωστή θέση, σε λίστα που είναι
// ήδη ταξινομημένη με φθίνουσα σειρά
// -------------------------------------------------------------------------------------
int set_insdescend( Set *set, const int val )
{
if ( val == EMPTY_ELEMVAL ) // η μηδενική τιμή δεν εισάγεται
return -2; // επιστροφή αποτυχίας
if ( SET_ISFULL(*set) ) // σε γεμάτη λίστα
return -1; // επιστροφή αποτυχίας
if ( SET_ISEMPTY(*set) ) { // σε κενή λίστα...
set->elem[0] = val; // εισαγωγή στην αρχή της
set->len = 1; // ενημέρωση τρέχοντος μήκους
return 0; // επιστροφή 1ης θέσης
}
register int i;
for (i=0; val < set->elem[i] && i < set->len; i++)
;
// μετακίνηση των στοιχείων μια θέση προς τα δεξιά, ξεκινώντας από το i στοιχείο
memmove( &(set
->elem
[i
+1]), &(set
->elem
[i
]), (set
->len
-i
) * sizeof(int) );
set->elem[i] = val; // εισαγωγή νέου στοιχείου
(set->len)++; // ενημέρωση τρέχοντος μήκους
return i; // επιστροφή θέσης εισαγωγής
}
// -------------------------------------------------------------------------------------
// Αναζήτηση του στοιχείου με τιμή val στη λίστα (επιστρέφει τη θέση στην οποία
// βρέθηκε το στοιχείο, αλλιώς επιστρέφει -1)
// -------------------------------------------------------------------------------------
int set_elemindex( const Set *set, const int val )
{
if ( SET_ISEMPTY(*set) || val == EMPTY_ELEMVAL )
return -1;
register int i;
for (i=0; set->elem[i] != val && i < set->len; i++)
;
return i == set->len ? -1 : i; // τέλειωσαν τα στοιχεία ? -1 αλλιώς i
}
// ------------------------------------------------------------------------------------
// Διαγραφή του στοιχείου με τιμή val από τη λίστα (επιστρέφει FALSE αν το στοιχείο
// δεν βρέθηκε στη λίστα, αλλιώς το διαγράφει κι επιστρέφει TRUE)
// -------------------------------------------------------------------------------------
Bool set_delete( Set *set, const int val )
{
register int i;
// εύρεση στοιχείου με τιμή val
int elem = set_elemindex( set, val);
if ( elem == -1 ) // το στοιχείο δεν βρέθηκε...
return FALSE; // επιστροφή αποτυχίας
// μετακίνηση στοιχείων μια θέση προς τα αριστερά,
// ξεκινώντας από τη θέση που βρέθηκε το στοιχείο
for (i=elem; set->elem[i+1] != EMPTY_ELEMVAL && i < set->len-1; i++)
set->elem[i] = set->elem[i+1];
set->elem[i] = EMPTY_ELEMVAL; // μηδενισμός του τέως τελευταίου στοιχείου
(set->len)--; // ενημέρωση τρέχοντος μήκους
return TRUE; // επιστροφή επιτυχίας
}
// -------------------------------------------------------------------------------------
// Ταξινόμηση σε φθίνουσα σειρά των στοιχείων του πίνακα elem, ξεκινώντας από το στοιχείο
// lo έως το στοιχείο hi (η ταξινόμηση γίνεται με απλή υλοποίηση του αναδρομικού
// αλγόριθμου quick-sort)
// -------------------------------------------------------------------------------------
void qsort_descend(int elem[], int lo, int hi )
{
int i=lo, j=hi, temp;
int pivot = elem[ (lo+hi)/2 ]; // επιλογή του στοιχείου pivot
do { // διάσπαση του πίνακα
while (elem[i] > pivot)
i++;
while (elem[j] < pivot)
j--;
if ( i <= j)
{
temp = elem[i];
elem[i] = elem[j];
elem[j] = temp;
i++;
j--;
}
} while (i <= j);
if (lo < j) // αναδρομή
qsort_descend(elem, lo, j);
if (i < hi)
qsort_descend(elem, i, hi);
return;
}
// -------------------------------------------------------------------------------------
// Εμφάνιση του μενού των εντολών
// -------------------------------------------------------------------------------------
void do_help( const char *commands[] )
{
printf("SAMPLE OPERATIONS ON A LIST OF %d ELEMENTS\n", MAX_ELEMENTS
); puts("------------------------------------------"); printf("%s n1 n2 ...\tappend (up to %d numbers)\n", commands
[0], MAX_ELEMENTS
); printf("%s n1 n2 ...\tprepend(up to %d numbers)\n", commands
[1], MAX_ELEMENTS
); printf("%s n1 n2 ...\tinsert in ascending order\n", commands
[2]); printf("%s n1 n2 ...\tinsert in descending order\n", commands
[3]); printf("%s n\t\tdelete n\n", commands
[4]); printf("%s \t\tsort in ascending order\n", commands
[5]); printf("%s \t\tsort in descending order\n", commands
[6]); printf("%s \t\treset\n", commands
[7]); printf("%s \t\tprint\n", commands
[8]); printf("%s \t\thelp\n", commands
[9]); printf("%s \t\texit\n", commands
[10]); puts("------------------------------------------"); puts(" ONLY POSITIVE INTEGERS ARE ALLOWED"); puts("------------------------------------------");
return;
}
// -------------------------------------------------------------------------------------
// Εκτέλεση της εντολής "app n1 n2 ..." που εισαγάγει τα n1 n2 ... στο τέλος της λίστας
// (επιστρέφει FALSE σε περίπτωση σφάλματος, αλλιώς επιστρέφει TRUE)
// -------------------------------------------------------------------------------------
Bool do_append( const int ntokens, char *tokens[], Set *set )
{
if ( ntokens < 2 ) { // ελλιπείς παράμετροι
puts("\tspecify what to append\n"); // ... return FALSE; // επιστροφή αποτυχίας
}
Bool warn1=FALSE, warn2=FALSE;
register int i, temp, val;
for (i=1; i < ntokens; i++) // για κάθε n1, n2, ...
{ // ...
val
= atoi( tokens
[i
] ); // μετατροπή σε ακέραιο if ( val < 0 ) { // αρνητική τιμή...
warn2 = TRUE; // ενεργοποίηση προειδοποίησης #2
continue;
}
temp = set_append( set, val ); // εισαγωγή νέου στοιχείου
if ( temp == -2 ) // ήταν τιμή μηδενισμού...
warn1 = TRUE; // ενεργοποίηση προειδοποίησης #1
else if ( temp == -1 ) { // η λίστα ήταν γεμάτη...
printf("\t%d was not appended (array is full)\n", val
); return FALSE; // επιστροφή αποτυχίας
}
}
if ( warn1 ) // τύπωμα προειδοποίησης #1
printf( "\t(values equal to the zero-value: %d were ignored)\n", EMPTY_ELEMVAL);
if ( warn2 ) // τύπωμα προειδοποίησης #2
puts("\t(negative values were ignored)");
return TRUE; // επιστροφή επιτυχίας
}
// -------------------------------------------------------------------------------------
// Εκτέλεση της εντολής "pre n1 n2 ..." που εισαγάγει τα n1 n2 ... στην αρχή της λίστας
// (επιστρέφει FALSE σε περίπτωση σφάλματος, αλλιώς επιστρέφει TRUE)
// -------------------------------------------------------------------------------------
Bool do_prepend( const int ntokens, char *tokens[], Set *set )
{
if ( ntokens < 2 ) { // ελλιπείς παράμετροι
puts("\tspecify what to prepend\n"); // ... return FALSE; // επιστροφή αποτυχίας
}
Bool warn1=FALSE, warn2=FALSE;
register int i, temp, val;
for (i=1; i < ntokens; i++) // για κάθε n1, n2, ...
{ // ...
val
= atoi( tokens
[i
] ); // μετατροπή σε ακέραιο if ( val < 0 ) { // αρνητική τιμή...
warn2 = TRUE; // ενεργοποίηση προειδοποίησης #2
continue;
}
temp = set_prepend( set, val ); // εισαγωγή νέου στοιχείου
if ( temp == -1 ) // ήταν τιμή μηδενισμού...
warn1 = TRUE; // ενεργοποίηση προειδοποίησης #1
else if ( temp == 0 ) { // η λίστα ήταν γεμάτη...
printf("\t%d was not prepended (array is full)\n", val
); return FALSE; // επιστροφή αποτυχίας
}
}
if ( warn1 ) // τύπωμα προειδοποίησης #1
printf( "\t(values equal to the zero-value: %d were ignored)\n", EMPTY_ELEMVAL);
if ( warn2 ) // τύπωμα προειδοποίησης #2
puts("\t(negative values were ignored)");
return TRUE; // επιστροφή επιτυχίας
}
// -------------------------------------------------------------------------------------
// Εκτέλεση της εντολής "id n1 n2 ..." που εισαγάγει τα n1 n2 ... στη λίστα,
// ταξινομημένα σε αύξουσα σειρά (επιστρέφει FALSE σε περίπτωση σφάλματος,
// αλλιώς επιστρέφει TRUE)
// -------------------------------------------------------------------------------------
Bool do_insascend( const int ntokens, char *tokens[], Set *set )
{
if ( ntokens < 2 ) { // ελλιπείς παράμετροι
puts("\tspecify what to insert\n"); // ... return FALSE; // επιστροφή αποτυχίας
}
Bool warn1=FALSE, warn2=FALSE;
register int i, temp, val;
for (i=1; i < ntokens; i++) // για κάθε n1, n2, ...
{ // ...
val
= atoi( tokens
[i
] ); // μετατροπή σε ακέραιο if ( val < 0 ) { // αρνητική τιμή...
warn2 = TRUE; // ενεργοποίηση προειδοποίησης #2
continue;
}
temp = set_insascend( set, val ); // εισαγωγή νέου στοιχείου
if ( temp == -2 ) // ήταν τιμή μηδενισμού...
warn1 = TRUE; // ενεργοποίηση προειδοποίησης #1
else if ( temp == -1 ) { // η λίστα ήταν γεμάτη...
printf("\t%d was not inserted (array is full)\n", val
); return FALSE; // επιστροφή αποτυχίας
}
}
if ( warn1 ) // τύπωμα προειδοποίησης #1
printf( "\t(values equal to the zero-value: %d were ignored)\n", EMPTY_ELEMVAL);
if ( warn2 ) // τύπωμα προειδοποίησης #2
puts("\t(negative values were ignored)");
return TRUE; // επιστροφή επιτυχίας
}
// -------------------------------------------------------------------------------------
// Εκτέλεση της εντολής "id n1 n2 ..." που εισαγάγει τα n1 n2 ... στη λίστα,
// ταξινομημένα σε φθίνουσα σειρά (επιστρέφει FALSE σε περίπτωση σφάλματος,
// αλλιώς επιστρέφει TRUE)
// -------------------------------------------------------------------------------------
Bool do_insdescend( const int ntokens, char *tokens[], Set *set )
{
if ( ntokens < 2 ) { // ελλιπείς παράμετροι
puts("\tspecify what to insert\n"); // ... return FALSE; // επιστροφή αποτυχίας
}
Bool warn1=FALSE, warn2=FALSE;
register int i, temp, val;
for (i=1; i < ntokens; i++) // για κάθε n1, n2, ...
{ // ...
val
= atoi( tokens
[i
] ); // μετατροπή σε ακέραιο if ( val < 0 ) { // αρνητική τιμή...
warn2 = TRUE; // ενεργοποίηση προειδοποίησης #2
continue;
}
temp = set_insdescend( set, val ); // εισαγωγή νέου στοιχείου
if ( temp == -2 ) // ήταν τιμή μηδενισμού...
warn1 = TRUE; // ενεργοποίηση προειδοποίησης #1
else if ( temp == -1 ) { // η λίστα ήταν γεμάτη...
printf("\t%d was not inserted (array is full)\n", val
); return FALSE; // επιστροφή αποτυχίας
}
}
if ( warn1 ) // τύπωμα προειδοποίησης #1
printf( "\t(values equal to the zero-value: %d were ignored)\n", EMPTY_ELEMVAL);
if ( warn2 ) // τύπωμα προειδοποίησης #2
puts("\t(negative values were ignored)");
return TRUE; // επιστροφή επιτυχίας
}
// -------------------------------------------------------------------------------------
// Εκτέλεση της εντολής "d n1" που διαγράφει το n από τη λίστα (επιστρέφει FALSE σε
// περίπτωση σφάλματος, αλλιώς επιστρέφει TRUE)
// -------------------------------------------------------------------------------------
Bool do_delete( const int ntokens, char *tokens[], Set *set )
{
if ( ntokens < 2 ) { // ελλιπείς παράμετροι
puts("\tspecify what to delete\n"); // ... return FALSE; // επιστροφή αποτυχίας
}
int val
= atoi( tokens
[1] ); // μετατροπή n σε ακέραιο if ( !set_delete( set, val ) ) // το στοιχείο δεν βρέθηκε
printf("\t%d was not found\n", val
); else // επιτυχής διαγραφή στοιχείου
printf("\t%d deleted successfully\n", val
);
return TRUE; // επιστροφή επιτυχίας
}
// -------------------------------------------------------------------------------------
// Εκτέλεση της εντολής "p" που τυπώνει τα περιεχομενα της λίστας
// -------------------------------------------------------------------------------------
void do_print( Set set )
{
printf("\tlist (%d) : ", set.
len); if ( !set_print( set ) )
else
return;
}
// -------------------------------------------------------------------------------------
// Εκτέλεση της επιλεγμένης από τον χρήστη εντολής
// -------------------------------------------------------------------------------------
void do_command( const CmdIndex cmdcode, const char *commands[], const int ntokens, char *tokens[], Set *set )
{
switch ( cmdcode )
{
case CMD_INS_APPEND:
if ( do_append( ntokens, tokens, set ) )
do_print( *set );
break;
case CMD_INS_PREPEND:
if ( do_prepend( ntokens, tokens, set ) )
do_print( *set );
break;
case CMD_INS_ASCEND:
if ( do_insascend( ntokens, tokens, set ) )
do_print( *set );
break;
case CMD_INS_DESCEND:
if ( do_insdescend( ntokens, tokens, set ) )
do_print( *set );
break;
case CMD_DELETE:
if ( do_delete( ntokens, tokens, set ) )
do_print( *set );
break;
case CMD_SRT_ASCEND:
qsort( set
->elem
, set
->len
, sizeof(int), set_elemcmp
); do_print( *set );
break;
case CMD_SRT_DESCEND:
qsort_descend( set->elem, 0, set->len-1 );
do_print( *set );
break;
case CMD_RESET:
set_init( set );
puts("\tarray was reset successfully\n"); break;
case CMD_PRINT:
do_print( *set );
break;
case CMD_HELP:
do_help( commands );
break;
default:
break;
}
return;
}
// -------------------------------------------------------------------------------------
int main( void )
{
const char *commands[MAX_COMMANDS ] = { // πίνακας εντολών
"app", "pre", "ia", "id", "d", "sa", "sd", "r", "p", "h", "x"
};
CmdIndex cmdcode; // κωδικός επιλεγμένης εντολής
char *tokens[ MAX_TOKENS ]; // παράμετροι εντολής + εντολή
int ntokens; // πλήθος εντολής + παραμέτρων
Set set = { MAX_ELEMENTS, 0, {-1} }; // η λίστα μας
set_init( &set ); // ΣΗΜΑΝΤΙΚΗ αρχικοποίηση
do_help( commands ); // εμφάνιση μενού εντολών
do { // ανάγνωση εντολής
cmdcode = get_input( &ntokens, tokens,MAX_TOKENS, commands,MAX_COMMANDS);
// εκτέλεση εντολής
do_command(cmdcode, commands, ntokens, tokens, &set);
} while( cmdcode != CMD_EXIT );
exit( EXIT_SUCCESS
); // επιτυχής τερματισμός }