Εργαστήριο7 Συμβολοσειρές- Ορίσματαστη...

6
Εργαστήριο 7 ο Συμβολοσειρές Ορίσματα στη main() Σκοπός του παρόντος εργαστηρίου είναι η εξοικείωση μας με τις συμβολοσειρές στην ANSI C καθώς και με την χρήση ορισμάτων στην συνάρτηση main(). Θεωρία Συμβολοσειρά (string) είναι μια σειρά αλφαριθμητικών χαρακτή. Με τον όρο σειρά αναφερόμαστε σε διαδοχικές θέσεις μνήμης που μπορούν να αντιμετωπισθούν σαν ένα σύνολο διατεταγμένων στοιχειωδών δεδομένων. Μέχρι στιγμής παραδείγματα συμβολοσειρών έχουμε δει και έχουμε χρησιμοποιήσει κατά τις εκτυπώσεις μηνυμάτων με τη συνάρτηση printf. Στη C η συμβολοσειρά ορίζεται σαν μια σειρά δεδομένων του τύπου char τα οποία τερματίζονται με ένα μηδενικό χαρακτήρα (NULL) ή αλλιώς τερματικό χαρακτήρα ‘\0’. Όταν η C χειρίζεται τη συμβολοσειρά με κάποιο τρόπο, π.χ. να τη συγκρίνει με κάποια άλλη συμβολοσειρά, να την εκτυπώσει, να την αντιγράψει σε μια άλλη συμβολοσειρά, κ.λ.π., οι συναρτήσεις που καλούνται είναι σχεδιασμένες να εκτελούν τη λειτουργία τους μέχρι να συναντήσουν τον μηδενικό χαρακτήρα. Η συμβολοσειρά είναι ένας ειδικός τύπος πίνακα με δεδομένα του τύπου char και με τερματισμό μέσω του μηδενικού χαρακτήρα. char name[5]; /* define a string of characters */ Παρατηρήστε στο παραπάνω παράδειγμα ότι ο τρόπος με τον οποίο δηλώνεται μια συμβολοσειρά είναι σαν ένας πίνακας χαρακτήρων. Η δήλωση μοιάζει με τη δήλωση μεταβλητής χαρακτήρα αλλά μετά το όνομα της μεταβλητής, και χωρίς κενό, ακολουθεί ένα ζεύγος τετράγωνων παρενθέσεων που περιέχει έναν αριθμό ο οποίος καθορίζει το μέγεθος του πίνακα, δηλαδή τον αριθμό των στοιχειωδών δεδομένων που περιέχει ο πίνακας. Στην πιο πάνω δήλωση η συμβολοσειρά μπορεί να έχει το πολύ 5 χαρακτήρες. Η δήλωση μεγέθους είναι απαραίτητη για να δεσμεύσει ο μεταφραστής 5 συνεχόμενες θέσεις μνήμης, όπου η κάθε μια έχει χωρητικότητα ενός χαρακτήρα. Οι θέσεις αυτές έχουν η κάθε μια το δικό της όνομα που καθορίζεται ως συνδυασμός δύο τμημάτων: το όνομα του πίνακα, δηλαδή name, και ο αριθμός σειράς του στοιχείου. Στην C ο αριθμός σειράς ξεκινά από το 0 και φθάνει μέχρι το μέγεθος του πίνακα μείον μια θέση. Έτσι έχουμε τις μεταβλητές name[0], name[1], name[2], name[3], και name[4]. Προσοχή, σε μια συμβολοσειρά τελευταίος χαρακτήρας να είναι ο τερματικός χαρακτήρας ‘\0’, άρα μένουν τέσσερις ωφέλιμες θέσεις χαρακτήρων.

Transcript of Εργαστήριο7 Συμβολοσειρές- Ορίσματαστη...

Page 1: Εργαστήριο7 Συμβολοσειρές- Ορίσματαστη main()¦υλλάδια... · Εργαστήριο7ο! Συμβολοσειρές-–!Ορίσματαστη

 

Εργαστήριο  7ο    Συμβολοσειρές  –  Ορίσματα  στη  main()  Σκοπός  του  παρόντος  εργαστηρίου  είναι  η  εξοικείωση  μας  με  τις  συμβολοσειρές  στην  ANSI  C  καθώς  και  με  την  χρήση  ορισμάτων  στην  συνάρτηση  main().  

Θεωρία  Συμβολοσειρά   (string)   είναι   μια   σειρά   αλφαριθμητικών   χαρακτή.  Με   τον   όρο  σειρά   αναφερόμαστε   σε   διαδοχικές   θέσεις   μνήμης   που   μπορούν   να  αντιμετωπισθούν   σαν   ένα   σύνολο   διατεταγμένων   στοιχειωδών   δεδομένων.  Μέχρι   στιγμής   παραδείγματα   συμβολοσειρών   έχουμε   δει   και   έχουμε  χρησιμοποιήσει  κατά  τις  εκτυπώσεις  μηνυμάτων  με  τη  συνάρτηση  printf. Στη   C   η   συμβολοσειρά   ορίζεται   σαν   μια   σειρά   δεδομένων   του   τύπου   char   τα  οποία   τερματίζονται   με   ένα   μηδενικό   χαρακτήρα   (NULL)   ή   αλλιώς   τερματικό  χαρακτήρα   ‘\0’.  Όταν  η  C  χειρίζεται  τη  συμβολοσειρά  με  κάποιο  τρόπο,  π.χ.  να  τη   συγκρίνει   με   κάποια   άλλη   συμβολοσειρά,   να   την   εκτυπώσει,   να   την  αντιγράψει   σε   μια   άλλη   συμβολοσειρά,   κ.λ.π.,   οι   συναρτήσεις   που   καλούνται  είναι  σχεδιασμένες  να   εκτελούν  τη  λειτουργία  τους  μέχρι   να  συναντήσουν  τον  μηδενικό  χαρακτήρα.  Η  συμβολοσειρά  είναι  ένας  ειδικός  τύπος  πίνακα  με  δεδομένα  του  τύπου  char  και  με  τερματισμό  μέσω  του  μηδενικού  χαρακτήρα.   char name[5]; /* define a string of characters */ Παρατηρήστε  στο  παραπάνω  παράδειγμα  ότι  ο  τρόπος  με  τον  οποίο  δηλώνεται  μια  συμβολοσειρά  είναι  σαν  ένας  πίνακας  χαρακτήρων.  Η  δήλωση  μοιάζει  με  τη  δήλωση  μεταβλητής  χαρακτήρα  αλλά  μετά  το  όνομα  της  μεταβλητής,  και  χωρίς  κενό,  ακολουθεί  ένα  ζεύγος  τετράγωνων  παρενθέσεων  που  περιέχει  έναν  αριθμό  ο  οποίος  καθορίζει  το  μέγεθος  του  πίνακα,  δηλαδή  τον  αριθμό  των  στοιχειωδών  δεδομένων   που   περιέχει   ο   πίνακας.   Στην   πιο   πάνω   δήλωση   η   συμβολοσειρά  μπορεί  να  έχει  το  πολύ  5  χαρακτήρες.  Η  δήλωση  μεγέθους  είναι  απαραίτητη  για  να  δεσμεύσει  ο  μεταφραστής  5  συνεχόμενες  θέσεις  μνήμης,  όπου  η  κάθε  μια  έχει  χωρητικότητα   ενός   χαρακτήρα.   Οι   θέσεις   αυτές   έχουν   η   κάθε   μια   το   δικό   της  όνομα   που   καθορίζεται   ως   συνδυασμός   δύο   τμημάτων:   το   όνομα   του   πίνακα,  δηλαδή   name,   και   ο   αριθμός   σειράς   του   στοιχείου.   Στην   C   ο   αριθμός   σειράς  ξεκινά  από  το  0  και  φθάνει  μέχρι   το  μέγεθος  του  πίνακα  μείον  μια  θέση.  Έτσι  έχουμε   τις   μεταβλητές   name[0],   name[1],   name[2],   name[3],   και   name[4]. Προσοχή, σε μια συμβολοσειρά τελευταίος  χαρακτήρας  να  είναι  ο  τερματικός  χαρακτήρας  ‘\0’,  άρα  μένουν  τέσσερις  ωφέλιμες  θέσεις  χαρακτήρων.  

Page 2: Εργαστήριο7 Συμβολοσειρές- Ορίσματαστη main()¦υλλάδια... · Εργαστήριο7ο! Συμβολοσειρές-–!Ορίσματαστη

 

Η   εκτύπωση   μιας   σταθερής   συμβολοσειράς   γίνεται   με   τη   βοήθεια   της  συνάρτησης   printf.   Απλά   η   συμβολοσειρά   -­‐   μήνυμα   περικλείεται   από   διπλά  εισαγωγικά,  π.χ.  printf("This is a constant string");

Στη   περίπτωση   του   πίνακα   name   έχουμε   μια   μεταβλητή   συμβολοσειρά   και   η  εμφάνισή  της  γίνεται  με  τον  χαρακτήρα  ελέγχου  '%s'.  printf("%s",name);

Ο  κάθε  χαρακτήρας  που  είναι  στοιχείο  της  συμβολοσειράς  μπορεί  να  εκτυπωθεί  αυτόνομα   με   τη   χρήση   του   χαρακτήρα   ελέγχου   '%c'   και   του   ονόματος   του  συγκεκριμένου  χαρακτήρα,  π.χ.  name[2].  printf("%c",name[2]);

Μπορούμε   επίσης   να   εκφράσουμε   τη   λειτουργία   εκτύπωσης   ολόκληρης   της  συμβολοσειράς  με  τη  βοήθεια  μιας  επανάληψης  for  ως  for (index = 0; name[index]; index++)

printf("%c",name[index]);

Σημειώστε  ότι  ο  μηδενικός  χαρακτήρας  ισοδυναμεί  με  το  αριθμητικό  0,  δηλαδή  τη   λογική   τιμή   του   ψευδούς   άρα   καθιστά   τη   συνθήκη   ελέγχου   ψευδή   και  τερματίζει  την  επανάληψη.  

Συναρτήσεις  Συμβολοσειρών   Οι συμβολοσειρες ει ναι ιδιαιτερα χρη σιμες στην επεξεργασι α κειμε νου κα θε ει δους. Μη ξεχνα τε οτι και τα προγραμματα μας ει ναι κει μενα μιας ειδικη ς γλω σσας, α ρα και η μετα φραση ενος προγραμματος ει ναι μια εξειδικευμενη επεξεργασι α κειμε νου. Τελικα στη μνημη του υπολογιστη ολες οι πληροφορι ες (εντολες, αριθμοι, χαρακτη ρες) δεν ει ναι παρα συμβολα. Επι σης πολλα προγραμματα συστημα των (οπως για παρα δειγμα οι επικοινωνι ες) στηρι ζονται σε επεξεργασι α συμβολοσειρων. Γι' αυτου ς τους λογους η C παρεχει μια βιβλιοθηκη συναρτη σεων για την επεξεργασι α συμβολοσειρων,  την, #include <string.h> strcpy:  αντιγραφή  ενός  string.  Αυτή  η  συνάρτηση  τα  byte  από  την  διεύθυνση  που  δείχνει  ο  s2  σε  αυτή  που  δείνχει  ο  s1'.  

Prototype: char strcpy(char *s1, const char *s2); Syntax: char string2[20]="red dwarf"; char string1[20]=""; strcpy(string1, string2); /* * Purpose: Program to demonstrate the 'strcpy' function. */ #include <string.h> /* strcpy */

Page 3: Εργαστήριο7 Συμβολοσειρές- Ορίσματαστη main()¦υλλάδια... · Εργαστήριο7ο! Συμβολοσειρές-–!Ορίσματαστη

 

main() { char text1[20]="martin"; /* string buffer */ char text2[20]="leslie"; /* string buffer */ printf (" original string contents are: %s\n", text1); /* Copy text2 into text1. If text1 is smaller that text2 it will probably overwrite something! */ strcpy(text1, text2); printf (" new string contents are: %s\n", text1); strcpy(text1, "linux"); printf (" final string contents are: %s\n", text1); } strcat:  συνάρτηση  για  την  συνέννωση  δύο  συμβολοσειρών  

char *strcat(char *dest, const char *src); /* * Purpose: Program to demonstrate the 'strcat' function. */ #include <stdio.h> int main() { char string1[20]; char string2[20]; strcpy(string1, "Hello"); strcpy(string2, "Hellooo"); printf("Returned String : %s\n", strcat( string1, string2 )); printf("Concatenated String : %s\n", string1 ); return 0; } strlen:  η  συνάρτηση  αυτή  επιστρέφει  το  μέγεθος  σε  bytes  μιας  συμβολοσειράς  μέχρι  και  τον  αλλά  χωρίς  τον  μηδενικό  χαρακτήρα  ‘\0’ /* * Purpose: Program to demonstrate the ‘strlen’ function. */ #include <stdio.h> #include <string.h> int main () { char str[50]; int len; strcpy(str, "This is tutorialspoint.com");

Page 4: Εργαστήριο7 Συμβολοσειρές- Ορίσματαστη main()¦υλλάδια... · Εργαστήριο7ο! Συμβολοσειρές-–!Ορίσματαστη

 

len = strlen(str); printf("Length of |%s| is |%d|\n", str, len); return(0); } strcmp(s1,   s2):   η   συνάρτηση   αυτή   συγκρίνει   το   s1   με   το   s2   και   επιστρέφει  θετική  τιμή  εάν  το  s1  είναι  μεγαλύτερο  (αλφαβητικά)  από  το  s2,  μηδέν  αμά  είναι  ίσα  και  αρνητική  τιμή  εάν  s1  μικρότερο  από  s2.  /* * Purpose: Program to demonstrate the ‘strlen’ function. */ /* string comparison */ if (strcmp(str1, str3))

printf("<%s> and <%s> are different\n", str1, str3); else

printf("<%s> and <%s> are the same\n", str1, str3);

Ορίσματα  στην  συνάρτηση  main()   Μία   δεύτερη   λειτουργία   της   main()   αφορά   στο   γεγονός   πως,   μέσω   της  συνάρτησης   αυτής,   μπορούμε   να   εισάγουμε   δεδομένα   τα   οποία   θέλουμε   το  πρόγραμμά  μας  να  χρησιμοποιεί  κάθε  φορά  που  εκτελείται,  κατά  περίπτωση.  Η  εισαγωγή  των  δεδομένων  αυτών,  γίνεται  στη  γραμμή  εντολών  ενός  shell  (unix-­‐command  line,  dos-­‐command  line  κ.λπ.  αναλόγως  το  λειτουργικό  σύστημα).  Μία  πολύ   συνηθισμένη   ανάγκη   για   εισαγωγή   τέτοιων   δεδομένων,   αφορά   στις  περιπτώσεις   όπου   ένα   πρόγραμμα   χρησιμοποιεί   αρχεία   εισόδου   και   εξόδου.  Μπορούμε  για  παράδειγμα  να  φανταστούμε  μία  εφαρμογή  η  οποία  ανοίγει  ένα  αρχικό   αρχείο   κειμένου   (αρχείο   εισόδου),   επεξεργάζεται   τα   δεδομένα   του   και  παράγει  ένα  τελικό  αρχείο  (αρχείο  εξόδου).  Μία  εφαρμογή  αυτού  του  είδους,  δεν  έχει   φυσικά   γραφτεί   για   κάποια   συγκεκριμένα   αρχεία.   Δηλώνοντας   έτσι  διαφορετικά  αρχεία  εισόδου  και  εξόδου  κάθε  φορά  που  τρέχουμε  την  εφαρμογή,  ο  κώδικας  μας  μπορεί  να  επαναχρησιμοποιείται  για  διαφορετικά  αρχεία.   Σε  τέτοιες  περιπτώσεις  η  main()  συντάσσεται  με  διαφορετικό  τρόπο:   int main(int argc, char *argv[]){ ... } όπου,   η   μεταβλητή   argc   αφορά   στο   πλήθος   ορισμάτων   που   το   πρόγραμμα  περιμένει   να   διαβάσει  από   τη   γραμμή   εντολών  και  argv[]   ένας  πίνακας  στον  οποίο  αποθηκεύονται  τα  ορίσματα  αυτά.   Πριν   ξεκινήσει   η   επεξεργασία   των   δεδομένων   που   δίδονται   από   τη   γραμμή  εντολών,  συνηθίζεται  να  γίνεται  ένας  έλεγχος  σε  σχέση  με  το  εάν  το  πλήθος  των  ορισμάτων  που  εισάγαμε  από  τη  γραμμή  εντολών  είναι  σωστά.  Ας  πάρουμε  για  

Page 5: Εργαστήριο7 Συμβολοσειρές- Ορίσματαστη main()¦υλλάδια... · Εργαστήριο7ο! Συμβολοσειρές-–!Ορίσματαστη

 

παράδειγμα  μία  εφαρμογή,  με  όνομα  my_prog,  η  οποία  χρησιμοποιεί  δύο  αρχεία  ήχου:  ένα  αρχείο  εισόδου,  τα  δεδομένα  του  οποίου  υφίστανται  μία  επεξεργασία  και  ένα  αρχείο  εξόδου,  το  οποίο  θα  περιέχει  τελικά  τα  επεξεργασμένα  δεδομένα.  Τα   ονόματα   των   αρχείων   εισόδου   και   εξόδου   θα   δίδονται   κάθε   φορά   από   το  χρήστη  στη  γραμμή  εντολών,  οπότε  η  μεταβλητή  argc  της  main()  ισοδυναμεί  με  3.    Έτσι,  εάν  για  παράδειγμα  πληκτρολογήσουμε:    

   τα  ορίσματα  της  argv[]  θα  είναι:   argv[0]: my_prog argv[1]: in.wav argv[2]: out.wav

Κάθε   δηλαδή   όρισμα   στη   γραμμή   εντολών   διαφέρει   από   το   επόμενο   με   έναν  χαρακτήρα  κενού.  Ο  κώδικας  πρέπει  να  κάνει  έναν  έλεγχο  εάν  τα  ορίσματα  αυτά  είναι  τρία.  Γράφουμε  λοιπόν:   int main(int argc,char *argv[]){ if (argc != 3) { /* If NOT 3 arguments we call the Usage routine and exit */ Usage(argv[0]); return 1; } /* handle the program options */ HandleOptions(argc,argv); return 0; } void Usage(char *programName){ printf("%s usage:\n",programName); printf("my_prog input_WAVE output_WAVE"); } void HandleOptions(int argc,char *argv[]){ /* The code of your application goes here */ }

Με  βάση  τον  παραπάνω  κώδικα  η  main()  ελέγχει  εάν  έχουν δοθεί τρία

Page 6: Εργαστήριο7 Συμβολοσειρές- Ορίσματαστη main()¦υλλάδια... · Εργαστήριο7ο! Συμβολοσειρές-–!Ορίσματαστη

 

ορίσματα  στη  γραμμή  εντολών:   if (argc != 3) { ...    

Εάν  όντως  argc  !=  3,  τότε  καλείται  η  συνάρτηση  Usage().  Η  συνάρτηση  αυτή  καλείται  με  όρισμα  εισόδου  το  argv[0],  το  όνομα  δηλαδή  της  εφαρμογής,  έτσι  ώστε    να  χρησιμοποιηθεί  στο  μήνυμα  λάθους:  

printf("%s usage:\n",programName); printf("%s input_WAVE output_WAVE",programName); Έτσι,  εάν  πληκτρολογήσουμε  δύο  ορίσματα,  αντί  για  τρία:  

Αντίθετα,  εάν  argc  ==  3,  τότε  καλείται  η  HandleOptions(),  η  οποία  αναλαμβάνει  να  εκτελέσει  τον  υπόλοιπο  κώδικα  του  προγράμματος.      

Ασκήσεις    

1. Γράψτε   ένα   πρόγραμμα   το   οποίο   διαβάζει   ένα   αλφαριθμητικό   από   το  πληκγρολόγιο   και   εμφανίζει   το   πλήθος   των   φωνηέντων   και   των  συμφώνων  που  περιέχει.  

2. Να  γραφεί  μια  συνάρτηση  με  το  όνομα  reverse,  η  οποία  αντιστρέφει  ένα  αλφαριθμητικό  στη  θέση  του.  

3. Να   γραφεί   συνάρτηση   (και   το   πρόγραμμα   που   την   καλεί),   η   οποία   θα  καλείται  με  όρισμα  τον  αύξοντα  αριθμό  του  μήνα  (από  1  έως  12)  και  θα  επιστρέφει  την  ονομασία  του.  

4. Να   γραφεί   ο   κώδικας   δύο   συναρτήσεων,   εκ   των   οποίων   η   πρώτη  διαβάζει   αλφαριθμητικά   από   το   πληκτρολόγιο   τα   οποία   μπορούν   να  περιέχουν  κενά  διαστήματα  και  η  δεύτερη  υπολογίζει  και  επιστρέφει  το  πλήθος   των   κενών   διαστημάτων   δοθέντος   αλφαριθμητικού.   Να  κατασκευάσετε   ένα   πρόγραμμα   που   θα   κάνει   χρήση   των   δύο  προηγούμενων  συναρτήσεων.  

5.