Record File

Source Code in C


1:Record File

 2: /* main.c
 3:  This program contains several calls to function PrintWhere to find
 4:  various records of interest from several files
 5: */
 6: 
 7: #include <stdio.h>
 8: #include <stdlib.h>
 9: #include <string.h>
 10: 
 11: #define TRUE   1
 12: #define FALSE  0
 13:  
 14: #define INTEGER 'i'
 15: #define FLOAT   'f'
 16: #define STRING  'c'
 17:  
 18: #define LESS    '<'
 19: #define EQUAL   '='
 20: #define GREATER '>'
 21:  
 22: 
 23:  
 24: int GetRec(
 25:   FILE *fileDesc,    /* αναγνωριστικό αρχείου */
 26:   int recNum,        /* αύξον αριθμός της προς ανάγνωση εγγραφής */
 27:   int recSize,        /* μήκος εγγραφής σε bytes */
 28:   void *bufPtr        /* δείκτης στο σημείο της μνήμης που αποθηκεύεται μία εγγραφή */
 29: );
 30: 
 31: void PrintField(
 32:   char fieldType,    /* τύπος πεδίου: 'i', 'f', ή 'c' */
 33:   int fieldOffset,    /* απόσταση πεδίου από την αρχή της εγγραφής σε bytes */
 34:   void *bufPtr        /* δείκτης στο σημείο της μνήμης που αποθηκεύεται μία εγγραφή */
 35: );
 36: 
 37: int TestRec(
 38:   char fieldType,    /* τύπος πεδίου: 'i', 'f', ή 'c' */
 39:   int fieldOffset,    /* απόσταση πεδίου από την αρχή της εγγραφής σε bytes */
 40:   char compareOp,    /* τύπος σύγκρισης: '<', '=', ή '>' */
 41:   void *valPtr,        /* δείκτης στην σταθερά σύγκρισης */
 42:   void *bufPtr        /* δείκτης στο σημείο της μνήμης που αποθηκεύεται μία εγγραφή */
 43: );
 44: 
 45: int PrintWhere(
 46:   char *fileName,    /* όνομα αρχείου */
 47:   int recSize,        /* μέγεθος εγγραφών αρχείου */
 48:   char fieldType1,    /* τύπος 1ου πεδίου: 'i', 'f', ή 'c' */
 49:   int fieldOffset1,    /* απόσταση 1ου πεδίου από την αρχή της εγγραφής σε bytes */
 50:   char fieldType2,    /* τύπος 2ου πεδίου: 'i', 'f', ή 'c' */
 51:   int fieldOffset2,    /* απόσταση 2ου πεδίου από την αρχή της εγγραφής σε bytes */
 52:   char fieldType3,    /* τύπος 3ου πεδίου: 'i', 'f', ή 'c' */
 53:   int fieldOffset3,    /* απόσταση 3ου πεδίου από την αρχή της εγγραφής σε bytes */
 54:   char compareOp,    /* τύπος σύγκρισης: '<', '=', ή '>' */
 55:   void *valPtr        /* δείκτης στην σταθερά σύγκρισης */
 56: );
 57:  
 58: 
 59:  
 60: 
 61:  
 62: int main(int argc, char** argv)
 63: {
 64: float minGpa = 7.5;
 65: int entyear = 1993;
 66: int age = 20;
 67: char *dept = "FYSIKO";
 68: 
 69: /********************************************************************************
 70:  * This query calls PrintWhere to find in file "student2" *
 71:  * the names and grades of students with grade greater than 7.5 *
 72:  ********************************************************************************/
 73:  
 74: switch(PrintWhere("student2.dat",64,STRING,8,FLOAT,60,FLOAT,60,
 75:                   GREATER,(void *) &minGpa))
 76:      {
 77:      case 0:  printf("\nSuccessful Termination on 1st Query\n");
 78:               break;
 79:      case -1: printf("\n1st Query Execution Failure \n");
 80:               break;
 81:      default: printf("\nSevere error in PrintWhere call for 1st Query\n");
 82:               exit(1);
 83:      }
 84: 
 85: /********************************************************************************
 86:  * This query calls PrintWhere to find in file "student1" *
 87:  * the names and grades of students with grade greater than 7.5 *
 88:  ********************************************************************************/
 89:  
 90: switch(PrintWhere("student1.dat",68,STRING,24,FLOAT,16,FLOAT,16,
 91:                    GREATER,(void *) &minGpa))
 92:      {
 93:      case 0:  printf("\nSuccessful Termination on 2nd Query\n");
 94:               break;
 95:      case -1: printf("\n2nd Query Execution Failure \n");
 96:               break;
 97:      default: printf("\nSevere error in PrintWhere call for 2nd Query\n");
 98:               exit(1);
 99:      }
 100: 
 101: /********************************************************************************
 102:  * This query calls PrintWhere to find in file "student3" *
 103:  * the names and grades of students with grade greater than 7.5 *
 104:  ********************************************************************************/
 105:  
 106: switch(PrintWhere("student3.dat",100,STRING,36,FLOAT,80,FLOAT,80,
 107:                    GREATER,(void *) &minGpa))
 108:      {
 109:      case 0:  printf("\nSuccessful Termination on 3rd Query\n");
 110:               break;
 111:      case -1: printf("\n3rd Query Execution Failure \n");
 112:               break;
 113:      default: printf("\nSevere error in PrintWhere call for 3rd Query\n");
 114:               exit(1);
 115:      }
 116: 
 117: /********************************************************************************
 118:  * This query calls PrintWhere to find in file "student1" *
 119:  * the names and ages of students who entered in 1998 *
 120:  ********************************************************************************/
 121:  
 122: switch(PrintWhere("student1.dat",68,STRING,24,INTEGER,20,INTEGER,0,
 123:                    EQUAL,(void *) &entyear))
 124:      {
 125:      case 0:  printf("\nSuccessful Termination on 4th Query\n");
 126:               break;
 127:      case -1: printf("\n4th Query Execution Failure \n");
 128:               break;
 129:      default: printf("\nSevere error in PrintWhere call for 4th Query\n");
 130:               exit(1);
 131:      }
 132: 
 133: /********************************************************************************
 134:  * This query calls PrintWhere to find in file "student1" *
 135:  * the department name and id number of students who are 20 years old *
 136:  ********************************************************************************/
 137:  
 138: switch(PrintWhere("student1.dat",68,STRING,4,INTEGER,64,INTEGER,20,
 139:                    EQUAL,(void *) &age))
 140:      {
 141:      case 0:  printf("\nSuccessful Termination on 5th Query\n");
 142:               break;
 143:      case -1: printf("\n5th Query Execution Failure \n");
 144:               break;
 145:      default: printf("\nSevere error in PrintWhere call for 5th Query\n");
 146:               exit(1);
 147:      }
 148: 
 149: /********************************************************************************
 150:  * This query calls PrintWhere to find in file "student1" *
 151:  * the id number and name of students who are in FYSIKO *
 152:  ********************************************************************************/
 153:  
 154: switch(PrintWhere("student1.dat",68,INTEGER,64,STRING,24,STRING,4,
 155:                    EQUAL,(void *) dept))
 156:      {
 157:      case 0:  printf("\nSuccessful Termination on 6th Query\n");
 158:               break;
 159:      case -1: printf("\n6th Query Execution Failure \n");
 160:               break;
 161:      default: printf("\nSevere error in PrintWhere call for 6th Query\n");
 162:               exit(1);
 163:      }
 164:    return 0;
 165: }
 166: 
 167: /********************************************************************************************/
 168: 
 169: /********************************************************************************************
 170:  * H ρουτίνα PrintWhere τυπώνει τις τιμές δύο πεδίων (καθορισμένων από τις παραμέτρους *
 171:  * με ονόματα που καταλήγουν σε 1 και 2,αντίστοιχα) για όλες τις εγγραφές των οποίων η *
 172:  * τιμή σε ένα τρίτο πεδίο (καθορισμένου από τις παραμέτρους με ονόματα που καταλήγουν *
 173:  * σε 3) ικανοποιεί μια απλή συνθήκη. Η PrintWhere ανοίγει το καθορισμένο αρχείο για * 
 174:  * διάβασμα, διαβάζει μία μία τις εγγραφες, για κάθε εγγραφή ελέγχει κατάλληλα την τιμή *
 175:  * του πεδίου 3 και τυπώνει τα πεδία 1 και 2 αν ο έλεγχος αποβεί θετικός και κλείνει το *
 176:  * αρχείο.Σε περίπτωση αποτυχίας επιστρέφει την τιμή -1,υποδεικνύοντας ότι υπήρξε πρόβλημα *
 177:  * ενώ αν τερματίσει επιτυχώς, επιστρέφει την τιμή 0. *
 178:  ********************************************************************************************/
 179: int PrintWhere(char *fileName,int recSize,char fieldType1,int fieldOffset1,char fieldType2,int fieldOffset2,char fieldType3,int fieldOffset3,char compareOp,void *valPtr)
 180: {
 181:     FILE *file;         /*Αναγνωριστικό αρχείου.*/
 182:     void *recordbuf; /*Δείκτης στο σημείο της μνήμης που αποθηκεύεται μία εγγραφή.*/
 183:     int getvalue;    /*Ακέραια μεταβλητή για την αποθήκευση της τιμής που επιστρέφει η συνάρτηση GetRec()*/
 184:     int recNum=0;    /*Θέτουμε αρχική τιμή 0 στον αριθμό των εγγραφών.*/
 185:  
 186:     recordbuf=malloc(recSize); /*Δεσμεύουμε μνήμη όσο το μέγεθος της εγγραφής για τον δείκτη *recordbuf.*/
 187:     
 188:     if( (file = fopen( fileName, "rb" )) == NULL ) /*Ανοίγουμε το δυαδικό αρχείο για διάβασμα και εξετάζουμε την*/
 189:     {                                              /*τιμή που επιστρέφει η συνάρτηση fopen για τυχόν λάθη στην διαδικασία.*/
 190:         printf( "The file %s was not opened\n",fileName );    /*Σε περίπτωση λάθους κατά το άνοιγμα του αρχείου η συνάρτηση*/
 191:         return -1;                                            /*επιστρέφει την τιμή -1.*/                                            
 192:     }
 193:     else
 194:     {
 195:         while(!feof(file))   /*Μέχρι να φτάσουμε στο τέλος του αρχείου*/
 196:         {
 197:             getvalue=GetRec(file,recNum,recSize,recordbuf);  /*Διαβάζουμε μία-μία τις εγγραφές από το αρχείο.*/
 198: 
 199:             if(getvalue==0) /*Αν η εγγραφή διαβαστεί με επιτυχία*/
 200:             {
 201:                 if(TestRec(fieldType3,fieldOffset3,compareOp,valPtr,recordbuf)==TRUE) /*Ελέγχουμε για την εγγραφή*/
 202:                 {                                                                /*την τιμή του πεδίου 3 και αν ο έλεγχος*/
 203:                     printf("--------------------------------------------------\n");/*αποβεί θετικός*/
 204:                     PrintField(fieldType1,fieldOffset1,recordbuf); /*Τυπώνουμε το πεδίο 1 της εγγραφής*/
 205:                     PrintField(fieldType2,fieldOffset2,recordbuf); /*Τυπώνουμε το πεδίο 2 της εγγραφής*/
 206:                     printf("\n");
 207:                 }
 208:             }
 209:             if(getvalue==-1) /*Αν αποτύχει το διάβασμα της εγγραφής*/
 210:             {
 211:                 printf("--------------------------------------------------\n");
 212:                 printf("Attempt to Read After the End-Of-File!\n");
 213:                 if( fclose( file) )                            /*Κλείνουμε το αρχείο με έλεγχο για την επιτυχία κλεισίματος.*/
 214:                     printf( "The file %s was not closed\n",fileName );
 215:                 return -1;        /*Σε περίπτωση αποτυχίας στο κλείσιμο του αρχείου η συνάρτηση επιστρέφει την τιμή -1.*/
 216:             }
 217:             if(getvalue==-2)/*Eάν διάβασε ημιτελή εγγραφή στο τέλος του αρχείου.*/
 218:             {
 219:                 printf("--------------------------------------------------\n");
 220:                 printf("***Half-Record Found in the End-Of-File!***\n");
 221:                 if( fclose( file) )                            /*Κλείνουμε το αρχείο με έλεγχο για την επιτυχία κλεισίματος.*/
 222:                     printf( "The file %s was not closed\n",fileName );
 223:                 return -1;        /*Σε περίπτωση αποτυχίας στο κλείσιμο του αρχείου η συνάρτηση επιστρέφει την τιμή -1.*/
 224:             }
 225:             recNum++; /*Αυξάνουμε κάθε φορά τον αριθμό των εγγραφών κατά 1.*/
 226:         }
 227:     }
 228:     if( fclose( file) )    /*Κλείνουμε το αρχείο με έλεγχο για την επιτυχία κλεισίματος.*/
 229:     {
 230:         printf( "The file %s was not closed\n",fileName );
 231:         return -1;    /*Σε περίπτωση αποτυχίας στο κλείσιμο του αρχείου η συνάρτηση επιστρέφει την τιμή -1.*/
 232:     }
 233:     printf("**************************************************\n");
 234:     free(recordbuf);   /*Αποδεσμεύουμε μνήμη για τον δείκτη *recordbuf.*/
 235:     recordbuf=NULL;
 236:     return 0; /*Αν η συνάρτηση τερματίσει επιτυχώς, επιστρέφει την τιμή 0.*/
 237: }
 238: 
 239:  
 240: /********************************************************************************************
 241:  * Η ρουτίνα GetRec διαβάζει μία συγκεκριμένη εγγραφή από το αρχείο. Αναλυτικά υπολογίζει *
 242:  * την απόσταση από την αρχή του αρχείου της εγγραφής που αναζητούμε, τοποθετεί τον δρομέα *
 243:  * (cursor) του αρχείου στο σωστό σημείο και διαβάζει την εγγραφή εκεί όπου δείχνει ο *
 244:  * bufPtr.Ελέγχει εάν ο αριθμός των χαρακτήρων που διάβασε συμφωνεί με το μήκος της *
 245:  * εγγραφής και επιστρέφει την τιμή 0 εάν τερματίσει επιτυχώς, την τιμή -1 εάν επιχείρησε *
 246:  * να διαβάσει πέραν του τέλους του αρχείου και την τιμή -2 αν βρήκε ημιτελή εγγραφή στο *
 247:  * τέλος του αρχείου. *
 248:  ********************************************************************************************/
 249: int GetRec(FILE *fileDesc,int recNum,int recSize,void *bufPtr)
 250: {
 251:     int apostasi, /*Ακέραια μεταβλητή για την απόσταση της εγγραφής από την αρχή του αρχείου*/
 252:         result,      /*Ακέραια μεταβλητή για την αποθήκευση της επιστρεφόμενης τιμής της συνάρτησης fseek.*/
 253:         numread; /*Ακέραια μεταβλητή για την αποθήκευση της επιστρεφόμενης τιμής της συνάρτησης fread.*/
 254: 
 255:     apostasi=recNum*recSize; /*Υπολογίζουμε την απόσταση της εγγραφής πολλαπλασιάζοντας τον αριθμό της εγγραφής */
 256:                              /*με το μεγεθός της.*/
 257:     result = fseek(fileDesc,apostasi, SEEK_SET); /*Τοποθετούμε τον δρομέα(cursor) του αρχείου στο σωστό σημείο.*/
 258:     if( result ) /*Έλεγχος για την σωστή μετακίνηση και τοποθέτηση του δρομέα του αρχείου.*/
 259:     {
 260:         perror( "Fseek Failed!" );
 261:         return -1; /*Σε περίπτωση αποτυχίας στην μετακίνηση του δρομέα η συνάρτηση επιστρέφει την τιμή -1.*/
 262:     }
 263:     else
 264:     {
 265:         if(!feof(fileDesc)) /*Έλεγχος για το εάν βρισκόμαστε στο τέλος του αρχείου.*/
 266:         {
 267:             numread = fread(bufPtr,1,recSize, fileDesc ); /*Διαβάζουμε 1 εγγραφή με μέγεθος recSize και την αποθηκεύουμε*/
 268:             if( ferror( fileDesc ) )                     /*στον bufPtr.*/
 269:             {
 270:                 perror( "Read Error!" ); /*Έλεγχος για την επιτυχία του διαβάσματος.*/
 271:                 return -1;                /*Σε περίπτωση αποτυχίας η συνάρτηση επιστρέφει την τιμή -1.*/
 272:             }
 273:         }
 274:         else /*Εαν η συνάρτηση επιχειρήσει να διαβάσει πέραν του τέλους του αρχείου επιστρέφει την τιμή -1.*/
 275:         {
 276:             return -1;
 277:         }
 278:         if(numread==recSize)/*Έλεγχος για το εάν η συνάρτηση διάβασε πραγματικά τόσα bytes όσα το μέγεθος της εγγραφής(recSize).*/
 279:         {
 280:             return 0; /*Σε περίπτωση επιτυχίας η συνάρτηση επιστρέφει την τιμή 0.*/
 281:         }
 282:         else if(numread!=recSize && numread!=0)
 283:         {
 284:             return -2; /*Αλλιώς εάν διάβασε ημιτελή εγγραφή στο τέλος του αρχείου επιστρέφει την τιμή -2.*/
 285:         }
 286:     }
 287:     return -1; /*Σε οποιαδήποτε άλλη περίπτωση η συνάρτηση επιστρέφει την τιμή -1.*/
 288: }
 289:  
 290: 
 291: /******************************************************************************************
 292:  * Η ρουτίνα TestRec ελέγχει εάν μια εγγραφή ικανοποιεί μία απλή συνθήκη της μορφής *
 293:  * "πεδίο<τιμή","πεδίο=τιμή","πεδίο>τιμή". Αν ναι τότε η TestRec επιστρέφει TRUE ,ειδ΄ *
 294:  * αλλοιώς επιστρέφει FALSE.Η τιμή του καθορισμένου από την fieldOffset πεδίου χρησιμο- *
 295:  * ποιείται στα αριστερά της σύγκρισης, ενώ η καθορισμένη σταθερά χρησιμοποιείται στα *
 296:  * δεξιά της σύγκρισης. *
 297:  ******************************************************************************************/
 298: int TestRec(char fieldType,int fieldOffset,char compareOp,void *valPtr,void *bufPtr)
 299: {
 300:     char *strptr,*strptr2; /*Δείκτες τύπου χαρακτήρα για την αποθήκευση του δείκτη *bufPtr και *valPtr αντίστοιχα*/
 301:     int *intptr,*intptr2; /*Δείκτες τύπου ακεραίου για την αποθήκευση της ακέραιας τιμής που δείχνουν οι δείκτες *strptr και *strptr2 αντιστοιχα */
 302:     float *floatptr,*floatptr2; /*Δείκτες τύπου πραγματικού αριθμού για την αποθήκευση της πραγματικής αριθμητικής τιμής που δείχνουν οι δείκτες *strptr και *strptr2 αντιστοιχα.*/
 303:  
 304:     strptr=(char *)bufPtr; /*Μετατροπή του δείκτη *bufPtr στον δείκτη χαρακτήρων *strptr.*/
 305:     strptr2=(char *)valPtr; /*Μετατροπή του δείκτη *valPtr στον δείκτη χαρακτήρων *strptr2.*/
 306: 
 307:     strptr=strptr+fieldOffset; /*Μετατόπιση του δείκτη στο σημείο που βρίσκεται το πεδίο.*/
 308: 
 309:     switch(fieldType) /*Εξετάζουμε τον τύπο του πεδίου.*/
 310:     {
 311:     case INTEGER: /*Εαν είναι ακέραιος αριθμός.*/
 312: 
 313:         intptr=(int *)strptr; /*Μετατροπή του δείκτη *strptr σε δείκτη τύπου ακεραίων αριθμών(*intptr).*/
 314:         intptr2=(int *)strptr2; /*Μετατροπή του δείκτη *strptr2 σε δείκτη τύπου ακεραίων αριθμών(*intptr2).*/
 315:  
 316:         switch(compareOp) /*Εξετάζουμε τον τύπο σύγκρισης.*/
 317:         {
 318:         case LESS: /*Εάν '<'.*/
 319:             if(*intptr<*intptr2) /*Αν "πεδίο<τιμή" η συνάρτηση επιστρέφει TRUE αλλιώς FALSE.*/
 320:             {
 321:                 return TRUE;
 322:             }
 323:             else
 324:                 return FALSE;
 325:         case EQUAL: /*Εάν '='.*/
 326:             if(*intptr==*intptr2) /*Αν "πεδίο=τιμή" η συνάρτηση επιστρέφει TRUE αλλιώς FALSE.*/
 327:             {
 328:                 return TRUE;
 329:             }
 330:             else
 331:                 return FALSE;
 332:         case GREATER: /*Εάν '>'.*/
 333:             if(*intptr>*intptr2) /*Αν "πεδίο>τιμή" η συνάρτηση επιστρέφει TRUE αλλιώς FALSE.*/
 334:             {
 335:                 return TRUE;
 336:             }
 337:             else
 338:                 return FALSE;
 339:         default:  /*Σε οποιαδήποτε άλλη περίπτωση η συνάρτηση επιστρέφει την τιμή -1 και τυπώνει το λάθος στην οθόνη.*/
 340:             perror("Compare Symbol Error!");
 341:             return -1;
 342:         }
 343:         
 344:     case FLOAT: /*Εαν είναι πραγματικός αριθμός.*/
 345:  
 346:         floatptr=(float *)strptr; /*Μετατροπή του δείκτη *strptr σε δείκτη τύπου πραγματικών αριθμών(*floatptr).*/
 347:         floatptr2=(float *)strptr2; /*Μετατροπή του δείκτη *strptr2 σε δείκτη τύπου πραγματικών αριθμών(*floatptr2).*/
 348: 
 349:         switch(compareOp) /*Εξετάζουμε τον τύπο σύγκρισης.*/
 350:         {
 351:         case LESS: /*Εάν '<'.*/
 352:             if(*floatptr<*floatptr2) /*Αν "πεδίο<τιμή" η συνάρτηση επιστρέφει TRUE αλλιώς FALSE.*/
 353:             {
 354:                 return TRUE;
 355:             }
 356:             else
 357:                 return FALSE;
 358:         case EQUAL: /*Εάν '='.*/
 359:             if(*floatptr==*floatptr2) /*Αν "πεδίο=τιμή" η συνάρτηση επιστρέφει TRUE αλλιώς FALSE.*/
 360:             {
 361:                 return TRUE;
 362:             }
 363:             else
 364:                 return FALSE;
 365:         case GREATER: /*Εάν '>'.*/
 366:             if(*floatptr>*floatptr2) /*Αν "πεδίο>τιμή" η συνάρτηση επιστρέφει TRUE αλλιώς FALSE.*/
 367:             {
 368:                 return TRUE;
 369:             }
 370:             else
 371:                 return FALSE;
 372:         default:   /*Σε οποιαδήποτε άλλη περίπτωση η συνάρτηση επιστρέφει την τιμή -1 και τυπώνει το λάθος στην οθόνη.*/
 373:             perror("Compare Symbol Error!");
 374:             return -1;
 375:         }
 376: 
 377:     case STRING: /*Εαν είναι συμβολοσειρά.*/
 378:         switch(compareOp) /*Εξετάζουμε τον τύπο σύγκρισης.*/
 379:         {
 380:         case LESS: /*Εάν '<'.*/
 381:             if(strcmp(strptr,valPtr)<0) /*Αν "πεδίο<τιμή" η συνάρτηση επιστρέφει TRUE αλλιώς FALSE.*/
 382:             {
 383:                 return TRUE;
 384:             }
 385:             else
 386:                 return FALSE;
 387:         case EQUAL: /*Εάν '='.*/
 388:             if(strcmp(strptr,valPtr)==0) /*Αν "πεδίο=τιμή" η συνάρτηση επιστρέφει TRUE αλλιώς FALSE.*/
 389:             {
 390:                 return TRUE;
 391:             }
 392:             else
 393:                 return FALSE;
 394:         case GREATER: /*Εάν '>'.*/
 395:             if(strcmp(strptr,valPtr)>0) /*Αν "πεδίο>τιμή" η συνάρτηση επιστρέφει TRUE αλλιώς FALSE.*/
 396:             {
 397:                 return TRUE;
 398:             }
 399:             else
 400:                 return FALSE;
 401:         default:  /*Σε οποιαδήποτε άλλη περίπτωση η συνάρτηση επιστρέφει την τιμή -1 και τυπώνει το λάθος στην οθόνη.*/
 402:             perror("Compare Symbol Error!");
 403:             return -1;
 404:         }
 405:         
 406:     default:  /*Σε οποιαδήποτε άλλη περίπτωση η συνάρτηση επιστρέφει την τιμή -1 και τυπώνει το λάθος στην οθόνη.*/
 407:         perror("Field Type Error!");
 408:         return -1;
 409:     }
 410:     perror("TestRec Error!");
 411:     return -1;    /*Σε οποιαδήποτε άλλη περίπτωση η συνάρτηση επιστρέφει την τιμή -1 και τυπώνει το λάθος στην οθόνη.*/
 412: }
 413:  
 414: 
 415: /***********************************************************************************
 416:  * Η ρουτίνα PrintField τυπώνει την τιμή ενός συγκεκριμένου πεδίου μιας εγγραφής. *
 417:  * Η PrintField απλά τυπώνει τα περιεχόμενα του καθορισμένου πεδίου. *
 418:  ***********************************************************************************/
 419: void PrintField(char fieldType,int fieldOffset,    void *bufPtr)
 420: {
 421:     char *strptr; /*Δείκτης τύπου χαρακτήρα για την αποθήκευση του δείκτη *bufPtr.*/
 422:     int *intptr; /*Δείκτης τύπου ακεραίου για την αποθήκευση της ακέραιας τιμής που δείχνει ο δείκτης *strptr.*/
 423:     float *floatptr; /*Δείκτης τύπου πραγματικού αριθμού για την αποθήκευση της πραγματικής αριθμητικής τιμής που δείχνει ο δείκτης *strptr.*/
 424: 
 425:     strptr=(char *)bufPtr; /*Μετατροπή του δείκτη *bufPtr στον δείκτη χαρακτήρων *strptr.*/
 426:     strptr=strptr+fieldOffset; /*Μετατόπιση του δείκτη στο σημείο που βρίσκεται το πεδίο.*/
 427:  
 428:     switch(fieldType)  /*Εξετάζουμε τον τύπο του πεδίου.*/
 429:     {
 430:     case INTEGER: /*Εαν είναι ακέραιος αριθμός.*/
 431:         {
 432:             intptr=(int *)strptr; /*Μετατροπή του δείκτη *strptr σε δείκτη τύπου ακεραίων αριθμών(*intptr).*/
 433:             printf("\t%d\t",*intptr); /*Τυπώνουμε στην οθόνη την ακέραια αριθμητική τιμή που δείχνει ο δείκτης *intptr.*/
 434:         }
 435:         break;
 436:     case FLOAT: /*Εαν είναι πραγματικός αριθμός.*/
 437:         {
 438:             floatptr=(float *)strptr; /*Μετατροπή του δείκτη strptr σε δείκτη τύπου πραγματικών αριθμών(floatptr).*/
 439:             printf("\t%.3f\t",*floatptr);  /*Τυπώνουμε στην οθόνη την αριθμητική τιμή που δείχνει ο δείκτης *floatptr.*/
 440:         }
 441:         break;
 442:     case STRING: /*Εαν είναι συμβολοσειρά.*/
 443:         {
 444:             printf("\t%s \t",strptr); /*Τυπώνουμε στην οθόνη την συμβολοσειρά που δείχνει ο δείκτης *strptr.*/
 445:         }
 446:         break;
 447:     default:
 448:         perror("FieldType Error!"); /*Σε οποιαδήποτε άλλη περίπτωση η συνάρτηση τυπώνει το λάθος στην οθόνη.*/
 449:         break;
 450:     }
 451: }