ΣΕΤ ΑΣΚΗΣΕΩΝ 3 ΕΡΓΑΣΤΗΡΙΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ I, ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ 2014-2015 Προθεσµία: 10/12/2014, 22:00 Διαβάστε πριν ξεκινήσετε Διαβάστε την εκφώνηση προσεκτικά και σχεδιάστε το πρόγραµµά σας πριν ξεκινήσετε να γράφετε κώδικα. Ολοκληρώστε κάθε ένα στάδιο πριν προχωρήσετε στο επόµενο, κι αποθηκεύστε σε ξεχωριστά αρχεία ενδιάµεσες σωστές µορφές του προγράµµατός σας ώστε να µπορείτε να επανέλθετε σε αυτές αν κάνετε κάποιο λάθος. Μη διστάζετε να ζητήσετε βοήθεια! Χρησιµοποιήστε κατά προτίµηση το forum προγραµµατισµού (http://courses.inf.uth.gr/coding/?page_id=143) ή, αν είναι απαραίτητο, email (π.χ. αν πραγµατικά επιβάλλεται να στείλετε κάποιο κοµµάτι κώδικα µαζί µε το µήνυµά σας). Η εργασία αυτή µπορεί να γίνει σε οµάδες µέχρι 2 ατόµων. Δε χρειάζεται να είστε οµάδα µε το ίδιο άτοµο που είστε στο εργαστήριο. Μπορείτε να συζητάτε τις ασκήσεις µε συµφοιτητές σας αλλά δεν επιτρέπεται η ανταλλαγή κώδικα µε οποιονδήποτε τρόπο. Ξεκινήστε νωρίς! Ο προγραµµατισµός είναι πάντα ΠΟΛΥ πιο χρονοβόρος από ότι περιµένετε. Εκπρόθεσµες ασκήσεις δε γίνονται δεκτές. Η άσκησή σας θα βαθµολογηθεί στα παρακάτω (χωρίς ιδιαίτερη σειρά): Ορθότητα Γενική µορφοποίηση προγράµµατος (στοίχιση, ονόµατα µεταβλητών/συναρτήσεων/σταθερών κτλ.) Σχεδιασµός προγράµµατος και αποτελεσµατική χρήση κατάλληλων δοµών, µεταβλητών, σταθερών κτλ. Διαβάστε προσεκτικά το φυλλάδιο µε τίτλο Αρχές καλού προγραµµατισµού και ακολουθήστε τις προτάσεις του. Σωστή δηµιουργία και χρήση συναρτήσεων Κάθε συνάρτηση πρέπει να είναι καλά ορισµένη: να κάνει µια σαφώς ορισµένη δουλειά, να µην έχει περιττές παραµέτρους, να είναι σχετικά µικρή. Αποφύγετε την άσκοπη επανάληψη κώδικα. Αν δείτε ότι κάνετε copy+paste κοµµάτια κώδικα, τότε µάλλον χρειάζεστε συνάρτηση για τη συγκεκριµένη λειτουργία. Συµµόρφωση µε τις προδιαγραφές Δώστε ιδιαίτερη σηµασία στην έξοδο του προγράµµατός σας. Θα πρέπει να ταιριάζει ΑΚΡΙΒΩΣ στην ενδεικτική έξοδο. Αποτελεσµατικά σχόλια, σύµφωνα µε τους κανόνες σχολιασµού φυλλαδίου µε τίτλο "Πρότυπα σχολιασµού προγραµµάτων".
'Άσκηση 1: Συστάσεις βιβλίων Εισαγωγή Κάθε φορά που βλέπετε ένα βίντεο στο youtube, σας συστήνει εναλλακτικά κλιπ τα οποία πιστεύει ότι θα σας ενδιαφέρουν. Οµοίως, online βιβλιοπωλεία όπως το amazon κάνουν συστάσεις βιβλίων µε βάση τις προτιµήσεις που έχετε δείξει µέχρι στιγµής. Η ιδέα πίσω από το µηχανισµό συνιστώµενων βίντεο ή βιβλίων είναι απλή: αν έχετε βαθµολογήσει µια σειρά από αυτά µε βάση τις προτιµήσεις σας, και κάποιος άλλος χρήστης έχει παρόµοιες προτιµήσεις (όπως αυτές διαµορφώνονται από τις βαθµολογίες που έδωσε), τότε είναι πολύ πιθανό να σας αρέσουν κάποια βίντεο ή βιβλία που άρεσαν και στον άλλο χρήστη. Σε αυτό το σετ ασκήσεων θα γράψετε ένα πρόγραµµα το οποίο διαβάζει τις προτιµήσεις ενός µεγάλου αριθµού χρηστών για ένα σύνολο βιβλίων, και τις χρησιµοποιεί για να συστήνει νέα βιβλία σε κάποιον από αυτούς τους χρήστες. Ακολουθούν λεπτοµερείς οδηγίες για το πώς πρέπει να λειτουργεί το πρόγραµµά σας και στάδια κατασκευής του. ΜΗΝ προσπαθήσετε να γράψετε όλο το πρόγραµµα σε ένα βήµα γιατί θα κάνετε λάθη και θα σας πάρει πολύ περισσότερο χρόνο. Στάδιο 0: Μελέτη του αρχείου δεδοµένων (-) Ανοίξτε το αρχείο data.txt µε έναν επεξεργαστή κειµένου. Η δοµή του αρχείου είναι ως εξής: Η πρώτη γραµµή περιέχει έναν ακέραιο αριθµό ο οποίος αναπαριστά το πλήθος των βιβλίων που είναι διαθέσιµα από ένα online βιβλιοπωλείο. Ο αριθµός είναι τουλάχιστον 1 και το πολύ 60. Ακολουθούν οι περιγραφές τόσων βιβλίων όσος είναι ο παραπάνω αριθµός. Τα βιβλία δίνονται µε τη µορφή τίτλος, κόµµα, όνοµα συγγραφέα. Οι πληροφορίες για κάθε ένα βιβλίο βρίσκονται όλες σε µια γραµµή και καταλαµβάνουν το πολύ 120 χαρακτήρες. Διαδοχικά βιβλία χωρίζονται από ένα χαρακτήρα αλλαγής γραµµής. Δεν υπάρχουν χαρακτήρες whitespace ανάµεσα στις λέξεις που αποτελούν τον τίτλο ή το όνοµα του συγγραφέα ή ανάµεσα στον τίτλο και στο όνοµα. Ξεκινώντας στη γραµµή µετά τα βιβλία βρίσκονται πληροφορίες για τις βαθµολογίες που έδωσαν οι χρήστες του online βιβλιοπωλείου. Για κάθε χρήστη, το αρχείο περιλαµβάνει: το όνοµα του χρήστη, το οποίο δεν περιέχει χαρακτήρες whitespace. Τα ονόµατα είναι µοναδικά και καταλαµβάνουν το πολύ 20 χαρακτήρες. αλλαγή γραµµής τους βαθµούς που έδωσε αυτός ο χρήστης, έναν για κάθε ένα από τα παραπάνω βιβλία, µε την ίδια σειρά. Οι βαθµοί παίρνουν τις τιµές: -5 (το µισώ), -3 (δε µου άρεσε καθόλου), -1 (δε µου άρεσε πολύ), 0 (δεν το έχω διαβάσει), 1 (µέτριο), 3 (µου άρεσε), 5 (µου άρεσε πάρα πολύ). Διαδοχικοί βαθµοί χωρίζονται από whitespace. αλλαγή γραµµής. Υπάρχουν τουλάχιστον ένας και το πολύ 100 χρήστες. Στη γραµµή µετά τις βαθµολογίες του τελευταίου χρήστη βρίσκεται η λέξη EndOfNames η οποία µαρκάρει το τέλος των βαθµολογιών. Στη γραµµή µετά το EndOfNames βρίσκεται το username του χρήστη ο οποίος αναζητά προτάσεις για νέα βιβλία. Από εδώ και στο εξής θα τον αποκαλούµε "αγοραστή". Ο αγοραστής θα πρέπει να είναι ένας από τους χρήστες, διαφορετικά το πρόγραµµα δε θα µπορεί να δώσει προτάσεις (γιατί δε θα έχει πληροφορίες για τις προτιµήσεις του αγοραστή). Όταν θα ελέγχετε την ορθότητα του προγράµµατός σας, καλό είναι να το εκτελέσετε για διάφορους αγοραστές.
Στάδιο 1: Δηµιουργία δοµών και εισαγωγή δεδοµένων (() Θα χρειαστεί να αποθηκεύσετε τα δεδοµένα του προγράµµατος σε πίνακες. Για την ακρίβεια, θα χρειαστούν οι παρακάτω: Ένας διδιάστατος πίνακας χαρακτήρων, όπου κάθε γραµµή j περιέχει τα στοιχεία ενός βιβλίου (τίτλος και συγγραφέας). Ας τον πούµε "πίνακα βιβλίων". Ένας διδιάστατος πίνακας χαρακτήρων, όπου κάθε γραµµή i περιέχει το username ενός χρήστη. Ας τον πούµε "πίνακα χρηστών". Ένας διδιάστατος πίνακας ακεραίων, όπου σε κάθε κελί [i][j] περιέχεται η βαθµολογία που έδωσε ο χρήστης i στο βιβλίο j. To username του χρήστη i είναι ακριβώς αυτό που έχει αποθηκευτεί στη γραµµή i του πίνακα χρηστών. Το βιβλίο j είναι ακριβώς αυτό που έχει αποθηκευτεί στη γραµµή j του πίνακα βιβλίων. Ας πούµε αυτόν τον πίνακα "πίνακα βαθµών". Γράψτε µια συνάρτηση η οποία παίρνει ως παράµετρο τον (αρχικά άδειο) πίνακα βιβλίων, διαβάζει από το πληκτρολόγιο µια σειρά από βιβλία και τα αποθηκεύει ως συµβολοσειρές (δηλαδή τερµατίζουν µε '\0') στον πίνακα βιβλίων. Η συνάρτηση επιστρέφει το πλήθος των βιβλίων που έχουν αποθηκευτεί στον πίνακα. Γράψτε µια συνάρτηση η οποία παίρνει ως παραµέτρους το πλήθος βιβλίων και τους (αρχικά άδειους) πίνακες χρηστών και βαθµών, διαβάζει από το πληκτρολόγιο τα ονόµατα των χρηστών και τους βαθµούς που έδωσαν και τα αποθηκεύει στους αντίστοιχους πίνακες. Τα ονόµατα των χρηστών αποθηκεύονται ως συµβολοσειρές. Η συνάρτηση επιστρέφει το πλήθος των χρηστών. Γράψτε µια συνάρτηση main η οποία καλεί τις δύο παραπάνω συναρτήσεις για να διαβάσει τα δεδοµένα του προγράµµατος. Προσωρινός κώδικας: Εκτυπώστε τα περιεχόµενα και των τριών πινάκων και επιβεβαιώστε ότι αυτό το στάδιο λειτουργεί σωστά. Δώστε ιδιαίτερη προσοχή σε οριακές περιπτώσεις (πχ. ονόµατα που είναι ακριβώς 20 χαρακτήρες). Το πρόγραµµά σας πρέπει να είναι γραµµένο µε τέτοιο τρόπο ώστε αν αλλάξει το µέγιστο πλήθος βιβλίων ή ο µέγιστος αριθµός χρηστών ή τα µέγιστα µεγέθη usernames ή στοιχείων βιβλίου, να µπορούν να γίνουν εύκολα και γρήγορα οι κατάλληλες αλλαγές στον κώδικα. Ολοκληρώστε αυτό το στάδιο και βεβαιωθείτε ότι λειτουργεί σωστά πριν προχωρήσετε στο επόµενο. Στάδιο 2: Εντοπισµός προτιµήσεων αγοραστή (() Αφαιρέστε τον προσωρινό κώδικα που γράψατε στο στάδιο 1. Γράψτε µια συνάρτηση η οποία παίρνει ως παράµετρο τον πίνακα χρηστών, το όνοµα ενός χρήστη, και ότι άλλο χρειάζεται, ψάχνει το όνοµα στον πίνακα, κι αν το βρει επιστρέφει τη θέση, διαφορετικά -1. Προσθέστε τον παρακάτω κώδικα στη main: 1. Εκτυπώστε το µήνυµα: Hi, what's your name? ακολουθούµενο από ένα κενό. 2. Διαβάστε από το πληκτρολόγιο το όνοµα του αγοραστή. 3. Χρησιµοποιήστε την παραπάνω συνάρτηση για να βρείτε τη θέση του ονόµατος στον πίνακα χρηστών. Αν δε βρεθεί χρήστης µε αυτό το όνοµα, εκτυπώστε το µήνυµα No user "X". ακολουθούµενο από χαρακτήρα αλλαγής γραµµής, όπου X το όνοµα που διαβάσατε κι επαναλάβετε τα βήµατα 1-3. 4. Αν βρεθεί χρήστης µε αυτό το όνοµα, εκτυπώστε το µήνυµα Hello X! ακολουθούµενο από χαρακτήρα αλλαγής γραµµής, όπου X το όνοµα που διαβάσατε. Προσωρινός κώδικας: Εκτυπώστε τη θέση που βρήκατε και επιβεβαιώστε ότι είναι σωστή. Ολοκληρώστε αυτό το στάδιο και βεβαιωθείτε ότι λειτουργεί σωστά πριν προχωρήσετε στο επόµενο.
Στάδιο 3: Υπολογισµός µέτρου σύγκρισης προτιµήσεων (((() Αφαιρέστε τον προσωρινό κώδικα που γράψατε στο στάδιο 2. Διαβάστε προσεκτικά την περιγραφή όλου του σταδίου πριν ξεκινήσετε. Κατασκευάστε ένα πίνακα στη main στον οποίο θα αποθηκευτούν αριθµοί κινητής υποδιαστολής που εκφράζουν ένα µέτρο σύγκρισης ανάµεσα στις βαθµολογίες που έδωσε ο αγοραστής και στις βαθµολογίες των άλλων χρηστών. Ο πίνακας είναι µονοδιάστατος και έχει µέγεθος όσο το µέγιστο πλήθος χρηστών (αλλά προφανώς τελικά θα "γεµίσουν" τόσες γραµµές όσοι είναι και οι χρήστες). Ας τον πούµε "πίνακα συγκρίσεων". Γράψτε µια συνάρτηση η οποία παίρνει κατάλληλες παραµέτρους (πρέπει να σκεφτείτε ποιες) ώστε να µπορεί για δύο χρήστες να υπολογίσει και να επιστρέψει το µέτρο σύγκρισης ανάµεσα στους βαθµούς που έδωσαν. Αν θεωρήσουµε ότι οι βαθµοί που έδωσαν δύο χρήστες i, j είναι δύο διανύσµατα (i 0, i 1,..., i k ) και (j 0, j 1,..., j k ) όπου k το πλήθος των βιβλίων, τότε ως µέτρο σύγκρισης θα υπολογίσουµε την Ευκλείδεια απόσταση ανάµεσά τους, δηλαδή την τετραγωνική ρίζα του αθροίσµατος των διαφορών των αντίστοιχων βαθµών: %&&i 0 j 0 ' 2 $&i 1 j 1 ' 2 $...$&i k j k ' 2 '. Όσο πιο µικρή είναι αυτή η ποσότητα τόσο πιο κοντά είναι οι βαθµολογίες των δύο χρηστών. Για τον υπολογισµό της τετραγωνικής ρίζας χρησιµοποιήστε τη µαθηµατική συνάρτηση sqrt. Θα χρειαστεί να κάνετε #include το math.h και να κάνετε compile µε την επιλογή -lm. Γράψτε µια συνάρτηση η οποία θα παίρνει ως παράµετρο τον (αρχικά άδειο) πίνακα συγκρίσεων και ότι άλλο χρειάζεται (πρέπει να σκεφτείτε ποιες άλλες παράµετροι είναι απαραίτητες) ώστε να υπολογίσει για κάθε ένα χρήστη το µέτρο σύγκρισης ανάµεσα στους βαθµούς αυτού του χρήστη και στους βαθµούς του αγοραστή. Η συνάρτηση αυτή πρέπει να χρησιµοποιεί την προηγούµενη συνάρτηση που γράψατε γι αυτό το στάδιο. Προσθέστε κώδικα στη main που χρησιµοποιεί την παραπάνω συνάρτηση για να γεµίσει ο πίνακας συγκρίσεων. Προσωρινός κώδικας: Εκτυπώστε τα περιεχόµενα του πίνακα συγκρίσεων και επιβεβαιώστε ότι είναι σωστά. Δώστε ιδιαίτερη προσοχή στη γραµµή που περιέχει το µέτρο σύγκρισης ανάµεσα στον αγοραστή και τον εαυτό του. Στάδιο 4: Ταξινόµηση µε βάση τις προτιµήσεις (((() Αφαιρέστε τον προσωρινό κώδικα που γράψατε στο στάδιο 3. Στόχος αυτού του σταδίου είναι να ταξινοµήσουµε τον πίνακα συγκρίσεων σε αύξουσα σειρά. Όµως, τα στοιχεία του πίνακα συγκρίσεων αντιστοιχούν στα στοιχεία του πίνακα χρηστών και στα στοιχεία του πίνακα βαθµών (δηλαδή τα περιεχόµενα στη θέση i οποιουδήποτε από τους τρεις παραπάνω πίνακες αντιστοιχούν στον ίδιο χρήστη). Με αυτή την έννοια τα περιεχόµενα των τριών πινάκων είναι παράλληλα. Αν αλλάξει η σειρά στον πίνακα συγκρίσεων, πρέπει να αλλάξει µε ακριβώς τον ίδιο τρόπο και η σειρά στους άλλους δύο πίνακες. Για να µην ταξινοµήσουµε τρεις πίνακες ταυτόχρονα, θα κάνουµε κάτι πιο έξυπνο: Κατασκευάζουµε ένα νέο πίνακα ακεραίων, µεγέθους όσο και ο πίνακας συγκρίσεων και αποθηκεύουµε σε αυτόν τις θέσεις στις οποίες βρίσκονται τα στοιχεία του πίνακα συγκρίσεων (δηλαδή αρχικά θα περιέχει 0, 1, 2, κτλ). Ας ονοµάσουµε τον νέο πίνακα "πίνακα θέσεων". Μετά, κατά την ταξινόµηση, κάθε φορά που µετακινούµε ένα στοιχείο του πίνακα συγκρίσεων µετακινούµε µε τον ίδιο τρόπο το αντίστοιχο στοιχείο στον πίνακα θέσεων. Στο τέλος της ταξινόµησης, ο πίνακας θέσεων θα περιέχει τις θέσεις των χρηστών ταξινοµηµένες ως προς τα µέτρα σύγκρισης. Αν µετά διατρέξουµε τον πίνακα χρηστών ή τον πίνακα βαθµών όχι µε τη σειρά 0, 1, 2, κτλ αλλά µε τη σειρά που βρίσκεται στον πίνακα θέσεων, τότε ουσιαστικά διατρέχουµε αυτούς τους πίνακες "ταξινοµηµένα" µε βάση τα µέτρα σύγκρισης. Γράψτε µια συνάρτηση η οποία θα παίρνει ως παραµέτρους τον πίνακα συγκρίσεων, ένα πίνακα θέσεων αρχικοποιηµένο µε τιµές 0, 1, 2, κτλ. και το πραγµατικό πλήθος χρηστών. Η συνάρτηση χρησιµοποιεί τον
αλγόριθµο insertion sort για να ταξινοµήσει τον πίνακα συγκρίσεων µε αύξουσα σειρά. Κάθε φορά που µετακινεί ένα στοιχείο του πίνακα συγκρίσεων, πρέπει να µετακινεί το αντίστοιχο στοιχείο στον πίνακα θέσεων µε τον ίδιο ακριβώς τρόπο. Προσοχή: Η συνάρτηση ταξινοµεί µόνο τα κοµµάτια των πινάκων που περιέχουν έγκυρα δεδοµένα (δηλαδή συνολικά τόσα στοιχεία όσοι είναι και οι χρήστες). Προσθέστε κώδικα στη main που χρησιµοποιεί την παραπάνω συνάρτηση για να ταξινοµήσει τους πίνακες. Προσωρινός κώδικας: Εκτυπώστε τα περιεχόµενα των πινάκων και επιβεβαιώστε ότι είναι σωστά. Στάδιο 5: Εύρεση συνιστώµενου βιβλίου (((() Αφαιρέστε τον προσωρινό κώδικα που γράψατε στο στάδιο 4. Τώρα που έχουµε τα µέτρα σύγκρισης µπορούµε να συστήσουµε ένα βιβλίο στον αγοραστή. Προσθέστε κώδικα στο πρόγραµµά σας (χρησιµοποιώντας νέες συναρτήσεις όπου χρειάζεται) που να κάνει τα εξής: 1. Επιλέγει τον χρήστη µε το µικρότερο βαθµό σύγκρισης (απόσταση) σε σχέση µε τον αγοραστή. 2. Εκτυπώνει χαρακτήρα αλλαγής γραµµής, το όνοµα αυτού του χρήστη, µία αριστερή παρένθεση, ένα κενό, το µέτρο σύγκρισης µε δύο δεκαδικά ψηφία, µια δεξιά παρένθεση κι ένα χαρακτήρα αλλαγής γραµµής. (Αυτό κανονικά δε θα έπρεπε να δηµοσιοποιείται, αλλά το εκτυπώνετε για να είναι πιο εύκολος ο έλεγχος των αποτελεσµάτων σας) 3. Εκτυπώνει το µήνυµα This user recommends: ακολουθούµενο από χαρακτήρα αλλαγής γραµµής. 4. Ψάχνει στα βιβλία αυτού του χρήστη και εντοπίζει όλα τα βιβλία που του άρεσαν (βαθµός >=3) και που δεν έχει διαβάσει ακόµη ο αγοραστής (hint: αυτό µπορεί να γίνει σε µια νέα συνάρτηση) a. Για κάθε ένα τέτοιο βιβλίο που βρίσκει, εκτυπώνει τα στοιχεία του (τίτλος και συγγραφέας) και χαρακτήρα αλλαγής γραµµής. 5. Αν έχουν βρεθεί βιβλία, το πρόγραµµα τερµατίζει. 6. Αν δε βρεθεί κανένα τέτοιο βιβλίο από αυτό το χρήστη, το πρόγραµµα εκτυπώνει το µήνυµα Sorry, no recommendations from this user! ακολουθούµενο από χαρακτήρα αλλαγής γραµµής. Μετά επιστρέφει στο βήµα 1 επιλέγοντας το χρήστη µε τον αµέσως µεγαλύτερο βαθµό σύγκρισης κι επαναλαµβάνει τα βήµατα 2-6. Άσκηση 1, Στάδιο 5: Τελικός έλεγχος ορθότητας Το πρόγραµµά σας πρέπει να λειτουργεί σωστά και να εκτυπώνει όλα τα µηνύµατα και αποτελέσµατα µε τον τρόπο που σας περιγράφουµε. Θα σας δώσουµε ενδεικτικά αρχεία εισόδου και εξόδου. Χρησιµοποιήστε ανακατεύθυνση εισόδου/εξόδου και την εντολή diff όπως περιγράφουµε στο παράρτηµα Α για να επιβεβαιώσετε ότι το πρόγραµµά σας βγάζει ακριβώς την αναµενόµενη έξοδο. Πρέπει το πρόγραµµα που θα µας παραδώσετε να παράγει έξοδο που δεν έχει διαφορές από τη δική µας. Αρχείο προς παράδοση: hw3.c
Πώς να παραδώσετε τη δουλειά σας Προσθέστε σε σχόλια στην αρχή του κάθε αρχείου µε κώδικα τα πλήρη ονόµατα και ΑΕΜ των µελών της οµάδας. Παρακαλούµε να γράφετε τα σχόλια ΜΟΝΟ µε λατινικούς χαρακτήρες. Κατασκευάστε ένα φάκελο µε όνοµα hw3_epwnumo1_aem1_epwnumo2_aem2 και αντιγράψτε µέσα σε αυτόν το hw3.c Πηγαίνετε στο φάκελο µέσα στον οποίο βρίσκεται το hw3_epwnumo1_aem1_epwnumo2_aem2 που κατασκευάσατε και γράψτε την παρακάτω εντολή: tar czvf hw3_epwnumo1_aem1_epwnumo2_aem2.tgz hw3_epwnumo1_aem1_epwnumo2_aem2 Στείλτε email: στη διεύθυνση ce120lab@gmail.com αντίγραφο (CC) στον άλλο µέλος της οµάδας σας θέµα (subject) CE120 hw3 και επικολληµένο αρχείο το hw3_epwnumo1_aem1_epwnumo2_aem2.tgz Ασκήσεις που έχουν λάθος format ή είναι εκπρόθεσµες ΔΕ θα γίνουν δεκτές.
Παράρτηµα Α: Ανακατεύθυνση στο Linux Μέχρι στιγµής, έχετε δει πώς να γράφετε ένα πρόγραµµα που διαβάζει από το πληκτρολόγιο και γράφει στην οθόνη. Αυτό που συµβαίνει στην πραγµατικότητα είναι ότι το πρόγραµµα διαβάζει από το λεγόµενο standard input (stdin, προκαθορισµένη είσοδος) και γράφει στο λεγόµενο standard output (stdout, προκαθορισµένη έξοδος). Τυπικά, το standard input είναι συνδεδεµένο µε το πληκτρολόγιο και το standard output µε την οθόνη. Σε αυτή την εργασία θέλουµε διαβάσουµε από το πληκτρολόγιο ένα µεγάλο αριθµό δεδοµένων. Αντί να τα γράφουµε όλα στο πληκτρολόγιο θα ήταν πιο πρακτικό αν είχαµε αυτούς τους χαρακτήρες σε ένα αρχείο και µε κάποιο τρόπο διαβάζαµε από το αρχείο, χωρίς όµως να αλλάξουµε τον κώδικα στο πρόγραµµά µας (ο οποίος διαβάζει από το πληκτρολόγιο). Το Linux µας επιτρέπει να επιτύχουµε κάτι τέτοιο µε την "ανακατεύθυνση". Όταν το πρόγραµµα θέλει να διαβάσει είσοδο, µπορούµε να την ανακατευθύνουµε ώστε να γίνεται από αρχείο, αντί από το πληκτρολόγιο. Οµοίως, όταν το πρόγραµµα παράγει έξοδο, µπορούµε να την ανακατευθύνουµε από την οθόνη σε ένα αρχείο. Για να ανακατευθύνουµε την είσοδο χρησιµοποιούµε το ειδικό σύµβολο < Παράδειγµα:./myprogram < input.txt Το πρόγραµµα myprogram παίρνει την είσοδό του από το αρχείο input.txt αντί για το πληκτρολόγιο. Σηµειώστε ότι το πρόγραµµα ΔΕ γνωρίζει ότι διαβάζει από αρχείο! Για να ανακατευθύνουµε την έξοδο χρησιµοποιούµε το ειδικό σύµβολο > Παράδειγµα:./myprogram > output.txt Το πρόγραµµα myprogram γράφει την έξοδό του στο αρχείο output.txt αντί για την οθόνη. Και πάλι, το πρόγραµµα δε γνωρίζει ότι γράφει σε αρχείο και όχι στην οθόνη. Τέλος, µπορούµε να ανακατευθύνουµε και την είσοδο και την έξοδο ταυτόχρονα: Παράδειγµα:./myprogram < input.txt > output.txt Το πρόγραµµα myprogram παίρνει την είσοδό του από το αρχείο input.txt και γράφει την έξοδό του στο αρχείο output.txt. Γράψτε σε ένα αρχείο µε όνοµα data.c το παρακάτω πρόγραµµα: #include<stdio.h> int main(int argc, char *argv[]) { int i; for (i=0; i<120; i++) { printf( %d\n, i); } return 0; } Κάντε compile κι εκτελέστε το. Θα δείτε να τυπώνει στην οθόνη 120 αριθµούς. Τώρα, εκτελέστε το µε ανακατεύθυνση εξόδου προς ένα αρχείο µε όνοµα numbers.txt:./data > numbers.txt Δε θα εµφανιστεί τίποτα στην οθόνη, αλλά αν ανοίξετε το numbers.txt θα δείτε µέσα τους 120 ακεραίους.
Παράρτηµα Β: Σύγκριση αρχείων Η εντολή diff του Linux χρησιµοποιείται για να ελέγχουµε αν δυο αρχεία είναι ίδια. Δοκιµάστε τη! Φτιάξτε ένα αντίγραφο του αρχείου numbers.txt από το προηγούµενο παράρτηµα και ονοµάστε το numbers2.txt. Μετά, στη γραµµή εντολής γράψτε: diff -b numbers.txt numbers2.txt Δε θα βγει τίποτα γιατί τα αρχεία είναι ίδια. Τώρα, κάντε κάποιες αλλαγές στο numbers2.txt και ξαναδοκιµάστε. TΗ diff θα παρουσιάσει όλες τις διαφορές ανάµεσα στα δύο προγράµµατα (ανά γραµµή). Για παράδειγµα, αν στις γραµµές 3 και 4 το numbers.txt περιέχει τους αριθµούς 12 και 13 ενώ στις ίδιες γραµµές το numbers2.txt περιέχει τους αριθµούς 14 και 15, τότε η έξοδος της εντολής diff θα είναι: 3,4c3,4 < 12 < 13 --- > 14 > 15 Αυτό σηµαίνει ότι οι γραµµές 3,4 του numbers.txt θα πρέπει να αλλάξουν (c: change) από 12 13 σε 14 15 (τα οποία είναι επίσης στις γραµµές 3,4 του numbers2.txt) ώστε το numbers.txt να γίνει ίδιο µε numbers2.txt. Μπορείτε να χρησιµοποιείτε ανακατεύθυνση για να εκτυπώνετε την έξοδο ενός προγράµµατός σας σε αρχείο, να κάνετε το ίδιο και για την έξοδο του εκάστοτε εκτελέσιµου που σας δίνουµε και µετά να χρησιµοποιήσετε diff για να δείτε αν τα αποτελέσµατα είναι ίδια. Με τον ίδιο τρόπο θα ελέγχουµε κι εµείς τα αποτελέσµατα των προγραµµάτων σας.