Σημειώσεις όγδοης εβδομάδας Για να την δημιουργία σειριακών αρχείων, χρησιμοποιείται η fopen(filename, w ). Το αρχείο δημιουργείται στον ίδιο φάκελο που τρέχει το εκτελέσιμο πρόγραμμα. Το παρακάτω πρόγραμμα, δημιουργεί το αρχείο myaccounts.dat, το οποίο περιέχει έναν ακέραιο, ένα όνομα και ένα float σε κάθε γραμμή, τα οποία διαβάζονται από το πληκτρολόγιο. Για να σταματήσει το πρόγραμμα και να εισαχθεί το EOF από το πληκτρολόγιο, δηλαδή το stdin, σε περιβάλλον Microsoft ο χρήστης πρέπει να πληκτρολογήσει Crtl-Z και enter, ενώ σε περιβάλλον Unix-Linux, Ctrl-D. int main(void){ int account; char name[30]; double balance; FILE *cfptr; if((cfptr=fopen("myaccounts.dat","w"))==null) printf("file could not be opened.\n"); printf("enter account,name,balance.\n"); printf("enter EOF to end input.\n"); scanf("%d%s%lf",&account,name,&balance); while(!feof(stdin)){ fprintf(cfptr,"%d %s %.2f\n", account,name,balance); scanf("%d%s%lf",&account,name,&balance); fclose(cfptr); Για να γραφτεί το αρχείο χρησιμοποιείται η fprintf και για να διαβαστεί η fscanf. Το πρόγραμμα αυτό διαβάζει το αρχείο: int main(void){ int account; char name[30]; double balance; FILE *cfptr; if((cfptr=fopen("myaccounts.dat","r"))==null) printf("file could not be opened.\n"); printf("%-10s%-13s%s\n","account", "Name","Balance"); fscanf(cfptr,"%d%s%lf",&account,name,&balance); Σημειώσεις Εργαστηρίου Δομών και Αλγορίθμων Week8 1 costis@teicrete.gr
while(!feof(cfptr)){ printf("%-10d%-13s%7.2f\n", account,name,balance); fscanf(cfptr,"%d%s%lf",&account,name,&balance); fclose(cfptr); Η δομή στοίβας (stack), είναι ειδική μορφή της λίστας, με βασικό χαρακτηριστικό ότι η εισαγωγή και η εξαγωγή κόμβων γίνεται πάντα στην και από την κεφαλή της στοίβας. Οι βασικές λειτουργίες είναι push και pop: /* * Stack Example from Deitel & Deitel */ #include <stdlib.h> struct stacknode { int data; struct stacknode *nextptr; ; typedef struct stacknode StackNode; typedef StackNode* StackNodePtr; void push(stacknodeptr *topptr, int info); int pop(stacknodeptr *topptr); int isempty(stacknodeptr sptr); void printstack(stacknodeptr currentptr); void instructions(void); int main(int argc, char** argv) { StackNodePtr stackptr = NULL; /* Stack top */ int choice; int value; instructions(); scanf("%d", &choice); while (choice!= 3) { switch (choice) { case 1: /* push */ printf("enter a integer: "); scanf("%d", &value); push(&stackptr, value); printstack(stackptr); case 2: /* pop */ if (!isempty(stackptr)) printf("the popped value is: %d.\n", pop(&stackptr)); printstack(stackptr); default: Σημειώσεις Εργαστηρίου Δομών και Αλγορίθμων Week8 2 costis@teicrete.gr
printf("invalid choice.\n\n"); instructions(); scanf("%d", &choice); printf("end of run.\n"); return (EXIT_SUCCESS); void instructions(void) { printf("enter your choice:\n" " 1 to push a value on the stack.\n" " 2 to pop a value off the stack.\n" " 3 to end.\n"); void push(stacknodeptr *topptr, int info) { StackNodePtr newptr; newptr=malloc(sizeof(stacknode)); if(newptr!=null) { newptr->data=info; newptr->nextptr=*topptr; *topptr=newptr; else printf("%d not inserted. No " "memory.\n", info); int pop(stacknodeptr *topptr) { StackNodePtr tempptr; int popvalue; tempptr=*topptr; popvalue=(*topptr)->data; *topptr=(*topptr)->nextptr; free(tempptr); return popvalue; int isempty(stacknodeptr topptr) { return topptr == NULL; void printstack(stacknodeptr currentptr) { if (currentptr == NULL) { printf("stack is empty.\n\n"); printf("the stack is:\n"); while (currentptr!= NULL) { printf("%d --> ", currentptr->data); printf("null\n\n"); Σημειώσεις Εργαστηρίου Δομών και Αλγορίθμων Week8 3 costis@teicrete.gr
Το παρακάτω παράδειγμα συνδέει δύο λίστες χρησιμοποιώντας συναρτήσεις: /* Concatenate Lists */ /* Deitel & Deitel */ #include <stdlib.h> struct ListNode { char data; struct ListNode *nextptr; ; typedef struct ListNode ListNode; typedef ListNode *ListNodePtr; void concatenate(listnodeptr a, ListNodePtr b); void insert(listnodeptr *sptr, char value); void printlist(listnodeptr currentptr); int main() { ListNodePtr list1ptr = NULL; ListNodePtr list2ptr = NULL; char i; for (i = 'A'; i <= 'C'; i++) { insert(&list1ptr, i); printf("list 1 is: "); printlist(list1ptr); for (i = 'D'; i <= 'F'; i++) { insert(&list2ptr, i); printf("list 2 is: "); printlist(list2ptr); concatenate(list1ptr, list2ptr); printf("the concatenated list is: "); printlist(list1ptr); /* Concatenate two lists */ void concatenate(listnodeptr a, ListNodePtr b) { ListNodePtr currentptr; /* temporary pointer */ currentptr = a; while (currentptr->nextptr!= NULL) { currentptr->nextptr = b; /* concatenate both lists */ /* Insert a new value into the list in sorted order */ void insert(listnodeptr *sptr, char value) { ListNodePtr newptr; Σημειώσεις Εργαστηρίου Δομών και Αλγορίθμων Week8 4 costis@teicrete.gr
/* new node */ ListNodePtr previousptr; /* previous node */ ListNodePtr currentptr; /* current node */ /* dynamically allocate memory */ newptr = malloc(sizeof ( ListNode)); /* if newptr does not equal NULL */ if (newptr) { newptr->data = value; newptr->nextptr = NULL; previousptr = NULL; currentptr = *sptr; /* set currentptr to start of list */ /* loop to find correct location in list */ while (currentptr!= NULL && value > currentptr->data) { previousptr = currentptr; /* insert at beginning of list */ if (previousptr == NULL) { newptr->nextptr = *sptr; *sptr = newptr; /* insert node between previousptr and currentptr */ previousptr->nextptr = newptr; newptr->nextptr = currentptr; printf("%c not inserted. No memory available.\n", value); void printlist(listnodeptr currentptr) { if (!currentptr) { printf("list is empty.\n\n"); while (currentptr) { printf("%c ", currentptr->data); printf("*\n\n"); Σημειώσεις Εργαστηρίου Δομών και Αλγορίθμων Week8 5 costis@teicrete.gr