Εργαστήριο Δομημένος Προγραμματισμός (C#) Τμήμα Μηχανολογίας Νικόλαος Ζ. Ζάχαρης Καθηγητής Εφαρμογών Σκοπός Nα κατασκευάσουν πίνακες από δεδομένα. Να κατασκευάσουν συναρτήσεις με πίνακες. Να κάνουν χρήση βιβλιοθηκών. Να διαβάσουν και να αποθηκεύσουν δεδομένα σε αρχεία. Εκφώνηση Το αρχείο c:\week.txt περιέχει τις τιμές των θερμοκρασιών μιας εβδομάδας. Να δημιουργήσετε ένα πρόγραμμα για την ανάγνωση των τιμών του αρχείου και την αποθήκευση τους σε ένα πίνακα πραγματικών αριθμών. Το πρόγραμμα θα υπολογίζει και θα αποθηκεύει στο αρχείο c:\mintemp.txt, το πλήθος των ημερών της εβδομάδας που έχουν μικρότερη θερμοκρασία από μια καθορισμένη τιμή. Επίλυση Πατήστε το κουμπί Έναρξη (Start) και εν συνεχεία Όλα τα Προγράμματα (All Programs) και μέσα στο φάκελο Βοηθήματα (Accessories) επιλέξτε το πρόγραμμα Σημειωματάριο (NotePad). Στο παράθυρο κειμένου του προγράμματος πληκτρολογήστε επτά τιμές, όπως εμφανίζονται στην παρακάτω εικόνα : και αποθηκεύστε το αρχείο στο δίσκο C με το όνομα week.txt. Δημιουργείστε στο περιβάλλον της C# ένα νέο έργο (File New Project) τύπου 1
Windows Application με όνομα FileAccess. Σχεδιάστε την διεπαφή της εφαρμογής όπως παρακάτω : Επιλέξτε ένα προς ένα τα αντικείμενα της φόρμας και στο παράθυρο Properties αλλάξτε τις παρακάτω ιδιότητες : Η φόρμα Form1 Name frmfiles Το όνομα του Text Διαχείριση Αρχείων Η γραμμή τίτλου MaximizeButton False Για να μην FormBorderStyle FixedSingle αλλάζει το μέγεθος της φόρμας. Το κουτί κειμένου textbox1 Name txtnumber Το όνομα του Multiline True Περισσότερες από μια γραμμές κειμένου. Text Το πρώτο κουμπί εντολών button1 Name btnread Το όνομα του Text Ανάγνωση Το δεύτερο κουμπί εντολών 2
button2 Name btnwrite Το όνομα του Text Αποθήκευση Η ανάγνωση και η αποθήκευση δεδομένων σε αρχεία είναι από τις βασικότερες εργασίες στο χώρο των υπολογιστών. Η C# διαθέτει την βιβλιοθήκη System.IO η οποία υποστηρίζει όλες τις κλάσεις και τα εργαλεία για την διαχείριση των αρχείων. Επιλέξτε το κουμπί εντολών btnread και στο παράθυρο Properties κάντε κλικ στο εικονίδιο με το κεραυνό για να εμφανιστούν τα γεγονότα. Βρείτε το γεγονός Click κάντε διπλό κλικ πάνω για να εμφανιστεί το παράθυρο με το προγραμματισμό των γεγονότων. Πληκτρολογείστε μέσα στο παράθυρο του κώδικα τις παρακάτω εντολές : Πίνακας 1. Ο κώδικας της εφαρμογής 1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Text; 7 using System.Windows.Forms; 8 using System.IO; 9 10 namespace FileAccess 11 { 12 public partial class frmfiles : Form 13 { 14 float[] pinakas = new float[7]; 15 16 public frmfiles() 17 { 18 InitializeComponent(); 19 } 20 21 int CalcMin(float[] x, float limit) 22 { 23 int apot = 0; 24 for (int i = 0; i < x.length; i++) 25 { 26 if (x[i] < limit) 27 { 28 apot = apot + 1; 29 } 30 } 3
31 32 return apot; 33 } 34 35 private void btnread_click(object sender, EventArgs e) 36 { 37 StreamReader fileweek = new StreamReader("c:\\week.txt"); 38 String sline; 39 int i; 40 for (i = 0; i < 7; i++ ) 41 { 42 sline = fileweek.readline(); 43 if (sline == null) 44 { 45 break; 46 } 47 else 48 { 49 pinakas[i] = float.parse(sline); 50 } 51 } 52 53 fileweek.close(); 54 } 55 56 private void btnwrite_click(object sender, EventArgs e) 57 { 58 StreamWriter filemin = new StreamWriter("c:\\minTemp.txt"); 59 float plithos = CalcMin(pinakas, float.parse(txtnumber.text)); 60 61 filemin.writeline(plithos.tostring()); 62 63 filemin.close(); 64 } 65 } 66 } Στην γραμμή 8 θα πρέπει να δηλώσετε ότι θα χρησιμοποιήσετε την βιβλιοθήκη System.IO με σκοπό να έχετε πρόσβαση στις κλάσεις StreamReader και StreamWriter, οι οποίες χρησιμοποιούνται για την ανάγνωση και την αποθήκευση δεδομένων σε αρχεία, αντίστοιχα. Το περιβάλλον ανάπτυξης της C#, σε κάθε νέο Project, ενσωματώνει το ελάχιστο απαραίτητο πλήθος βιβλιοθηκών (Πίνακας 1, γραμμές 1 έως 7) και θα πρέπει ο προγραμματιστής χρησιμοποιώντας την δήλωση using να ενσωματώσει στο πρόγραμμα τις επιπλέον βιβλιοθήκες. Αν σε κάθε νέο project ενσωματώνονταν όλες 4
οι βιβλιοθήκες που υποστηρίζει η γλώσσα C# τότε τα προγράμματα θα αποκτούσαν μεγαλύτερο μέγεθος τόσο στο δίσκο όσο και στην μνήμη του υπολογιστή. Στην γραμμή 14 δηλώνετε σαν καθολική μεταβλητή το πίνακα pinakas, ο οποίος θα χρησιμοποιηθεί για την αποθήκευση των θερμοκρασιών της εβδομάδας. Πατώντας το πλήκτρο Ανάγνωση εκτελείται ο κώδικας της συνάρτησης btnread_click Πίνακας 1, γραμμές 35 έως 54 στο σώμα της οποίας γίνεται η ανάγνωση των τιμών από το αρχείο week.txt. Στην γραμμή 37 δημιουργείται το αντικείμενο fileweek το οποίο είναι τύπου StreamReader και αρχικοποιείται με το μονοπάτι του αρχείου που περιέχει τις τιμές. των θερμοκρασιών. Θα πρέπει να προσέξετε ότι είναι απαραίτητο να χρησιμοποιήσετε το συνδυασμό \\ για να δηλώσετε την διαδρομή του μονοπατιού. Στα αλφαριθμητικά το \ χρησιμοποιείται σε συνδυασμό με κάποιο χαρακτήρα για να δηλώσει ειδική λειτουργία (escape characters), όπως το πλήκτρο Tab (\t) το Enter (\r\n) κ.λπ. Οπότε σε ένα αλφαριθμητικό ο συνδυασμός \\ ερμηνεύεται σαν το χαρακτήρα \. Για παράδειγμα την διαδρομή K:\files\test\times.txt θα πρέπει να την γράψετε σαν K:\\files\\test\\times.txt. Εν συνεχεία, στην γραμμή 38, δηλώνετε την μεταβλητή sline στην οποία θα αποθηκεύεται κάθε φορά μια γραμμή που θα διαβάζετε από το αρχείο. Επειδή το αρχείο week.txt περιέχει επτά τιμές κάνετε επτά επαναλήψεις γραμμή 40, όπου στην διάρκεια της κάθε μιας, διαβάζετε μια γραμμή από το αρχείο με την βοήθεια της μεθόδου ReadLine και την αποθηκεύεται στην μεταβλητή sline. Τα περιεχόμενα της κάθε γραμμής μπορεί να περιέχουν χαρακτήρες ή να είναι null, που σημαίνει τίποτα και χρησιμοποιείται για να δηλώσει ότι η ανάγνωση των τιμών έφτασε στο τέλος του αρχείου. Πρακτικά κάνετε έναν έλεγχο στη γραμμή 43, για να τερματίσετε την ανάγνωση των τιμών στην περίπτωση που το αρχείο περιέχει λιγότερες από επτά τιμές. Αν η συνθήκη είναι αληθής τότε τερματίζετε την επανάληψη διαφορετικά μετατρέπετε τους χαρακτήρες σε πραγματικό αριθμό και τον αποθηκεύετε στο πίνακα, γραμμή 49. Στο τέλος της επανάληψης, κλείνετε το αρχείο - γραμμή 53. 5
Στις γραμμές 21 έως 33 ορίζετε την συνάρτηση CalcMin, η οποία δέχεται σαν παραμέτρους ένα πίνακα πραγματικών αριθμών και μια τιμή, βάση της οποίας θα υπολογίσει το πλήθος των τιμών του πίνακα που είναι μικρότερες από αυτήν. Στο σώμα της CalcMin, δηλώνετε την μεταβλητή apot που αρχικοποιείτε με την τιμή 0 και χρησιμοποιείται σαν μετρητής για τον υπολογισμό του πλήθους των θερμοκρασιών που πληροί την συνθήκη της γραμμής 26. Πατώντας το πλήκτρο Αποθήκευση εκτελείται ο κώδικας της συνάρτησης btnwrite_click Πίνακας 1, γραμμές 56 έως 64 στο σώμα της οποίας γίνεται η αποθήκευση του πλήθους των θερμοκρασιών που είναι αποθηκευμένες στο pinaka και είναι μικρότερες από την τιμή που έχετε πληκτρολογήσει στο κουτί κειμένου txtnumber. Στην γραμμή 58 δημιουργείται το αντικείμενο filemin το οποίο είναι τύπου StreamWriter και αρχικοποιείται με το μονοπάτι του αρχείου αποθήκευσης. Στην γραμμή 59 υπολογίζεται με την βοήθεια της CalcMin, το πλήθος των θερμοκρασιών που είναι μικρότερες από μια τιμή όριο και στην γραμμή 61, με την βοήθεια της WriteLine, αυτή η τιμή αποθηκεύεται στο αρχείο mintemp.txt. Στο τέλος κλείνει το αρχείο. 6
Το πρόγραμμα σας εκτελείται σωστά μόνο για τα συγκεκριμένα αρχεία. Αν θέλατε να δώσατε την δυνατότητα να επιλέγει ο χρήστης το αρχείο ανάγνωσης ή αποθήκευσης τότε θα πρέπει να κάνετε αλλαγές στο κώδικα της εφαρμογής. Όλα τα προγράμματα στα Windows όταν πρόκειται να διαβάσουν ή να αποθηκεύσουν δεδομένα σε ένα αρχείο χρησιμοποιούν το ίδιο παράθυρο διαλόγου για να διαβάσουν το μονοπάτι της διαδρομής του αρχείου. Για να έχετε αυτή τη λειτουργικότητα, θα πρέπει να σύρετε από την εργαλειοθήκη πάνω στην διεπαφή της εφαρμογής, τα αντικείμενα OpenFileDialog και SaveFileDialog. Τα δύο αντικείμενα δεν εμφανίζονται πάνω στην φόρμα της εφαρμογής αλλά στο κάτω μέρος της οθόνης και έχουν αντίστοιχα τα ονόματα openfiledialog1 και savefiledialog1. Επιλέξτε τα αντικείμενα και στο παράθυρο των ιδιοτήτων δώστε σαν τιμές : openfiledialog1 Name openfiledialog1 Το όνομα του Filename Title Επιλέξτε αρχείο θερμοκρασιών 7
savefiledialog1 Name savefiledialog1 Το όνομα του Filename Title Επιλέξτε αρχείο εξόδου Ο Πίνακας 2 περιέχει το κώδικα της btnread_click μετά την προσθήκη του openfiledialog1. Πίνακας 2. Ο κώδικας της btnread_click 1 private void btnread_click(object sender, EventArgs e) 2 { 3 if (openfiledialog1.showdialog() == DialogResult.OK) 4 { 5 StreamReader fileweek = new StreamReader(openFileDialog1.FileName ); 6 String sline; 7 int i; 8 for (i = 0; i < 7; i++ ) 9 { 10 sline = fileweek.readline(); 11 if (sline == null) 12 { 13 break; 14 } 15 else 16 { 17 pinakas[i] = float.parse(sline); 18 } 19 } 20 fileweek.close(); 21 } 22 } Στην γραμμή 3, η μέθοδος ShowDialog εμφανίζει το παράθυρο διαλόγου για την επιλογή της διαδρομής του αρχείου που περιέχει τις τιμές με τις θερμοκρασίες και επιστρέφει το πλήκτρο που πάτησε ο χρήστης για το κλείσιμο του παραθύρου. Όλα τα παράθυρα διαλόγου που είναι διαθέσιμα στο περιβάλλον των Windows έχουν κουμπιά τα οποία επιστρέφουν συγκεκριμένες οι τιμές, όπως OK ή YES ή NO κ.λπ. Η συλλογή DialogResult έχει όλες τις τιμές των κουμπιών και σας επιτρέπει να συγκρίνετε και να βρείτε πιο κουμπί πάτησε ο χρήστης της εφαρμογής. Στο συγκεκριμένο παράθυρο αν πατηθεί το πλήκτρο Open τότε η μέθοδος ShowDialog 8
επιστρέφει την τιμή OK διαφορετικά την τιμή Cancel. Έτσι λοιπόν αν πατηθεί το πλήκτρο ΟΚ, στην γραμμή 5, διαβάζετε το αρχείο με τις τιμές των θερμοκρασιών, του οποίου η διαδρομή του μονοπατιού είναι αποθηκευμένη στην ιδιότητα FileName του openfiledialog1. Ο Πίνακας 3 περιέχει το κώδικα της btnwrite_click μετά την προσθήκη του savefiledialog1. Στην γραμμή 3 του πίνακα 3, η μέθοδος ShowDialog εμφανίζει το παράθυρο διαλόγου για την επιλογή της διαδρομής του αρχείου που θα αποθηκευτεί το αποτέλεσμα και επιπλέον επιστρέφει το πλήκτρο που πάτησε ο χρήστης για το κλείσιμο του παραθύρου. Αν πατηθεί το πλήκτρο ΟΚ τότε δημιουργείτε το αρχείο αποθήκευσης, του οποίου η διαδρομή του μονοπατιού είναι αποθηκευμένη στην ιδιότητα FileName του savefiledialog1, γραμμή 5 στο πίνακα 3, Πίνακας 3. Ο κώδικας της btnwrite_click 1 private void btnwrite_click(object sender, EventArgs e) 2 { 3 if (savefiledialog1.showdialog() == DialogResult.OK) 4 { 5 StreamWriter filemin = new StreamWriter(saveFileDialog1.FileName); 9
6 float plithos = CalcMin(pinakas, float.parse(txtnumber.text)); 7 8 filemin.writeline(plithos.tostring()); 9 10 filemin.close(); 11 } 12 } Τα παράθυρα διαλόγου είναι πολύ χρήσιμα γιατί παρέχουν την ίδια λειτουργικότητα και διεπαφή σε όλες τις εφαρμογές των Windows. 10