Αυτό το commit περιλαμβάνεται σε:
infl00p 2022-03-23 20:14:33 +02:00
commit 8ec8e9bee2
451 αρχεία άλλαξαν με 46736 προσθήκες και 0 διαγραφές

46
content/articles/24/01_editorial.md Κανονικό αρχείο

@ -0,0 +1,46 @@
+++
title = 'Editorial'
date = '2000-04-01T00:00:00Z'
description = ''
author = 'Μιχάλης Καμπριάνης(mailto:kabrianis@hellug.gr)'
issue = ['Magaz 24']
issue_weight = 1
+++
----------------------------------------------------------------------------------------------------------------------------------------------------------------
*Καλώς ορίσατε στο **Magaz**\... Τεύχος Παράδοσης / Παραλαβής*
----------------------------------------------------------------------------------------------------------------------------------------------------------------
Γεια σας, για τελευταία φορά από μένα από αυτό το βήμα, του αρχισυντάκτη. Από το επόμενο τεύχος, ο αρχισυντάκτης του περιοδικού αλλάζει, και εγώ μετατρέπομαι σε
απλό αρθρογράφο.\
Λίγες εξηγήσεις για αυτό, νομίζω ότι σας τις οφείλω. Από ιδρύσεως του Magaz, δηλαδή, το 1ο τεύχος που βγήκε τον Ιανουάριο του 1998, και μέχρι και αυτό το τεύχος
(24o, Μάιος του 2000), αρχικά ανεπίσημα και στη συνέχεια επίσημα (εκ των πραγμάτων βέβαια), είχα την ευθύνη αρχισυνταξίας του Magaz. Αν και πίστευα ότι δεν
χρειάζεται να υπάρχει αρχισυντάκτης, από τα πράγματα αποδείχτηκε ότι αυτός που \"κυνηγάει\" τους αρθρογράφους, συντονίζει τι άρθρα θα γράψουν, τα στέλνει στον
διορθωτή, φτιάχνει τις σελίδες, τις \"μοιράζει\" στα mirrors και πολλά άλλα, είναι ένας άτυπος έστω αρχισυντάκτης. Αυτή η ιστορία με έχει κουράσει πλέον. Όπως
θα έχετε παρατηρήσει, τα άρθρα μου (πλην του editorial) συνεχώς μειώνονται στο περιοδικό. Αυτό είναι κάτι που δεν ήθελα να συμβεί. Συμβαίνει όμως, λόγω ελλείψης
χρόνου. Αισθάνομαι ότι υπηρέτησα καλά το Magaz από αυτή τη θέση, τα δυόμιση αυτά χρόνια. Η αλήθεια είναι ότι δεν το παραδίδω και στην καλύτερη κατάσταση, έχει
όμως δυναμική.
Προφανώς θα συνεχίσω να είμαι τριγύρω, κυρίως γράφοντας άρθρα πλέον, εκμεταλλευόμενος τον χρόνο που θα εξοικονομήσω από την αρχισυνταξία, αλλά και σαν βοηθός
του νέου αρχισυντάκτη, αντικαθιστώντας τον όποτε χρειάζεται (σε δυό μήνες ας πούμε που θα παντρευτεί, πάλι εγώ θα βγάλω το τεύχος).
Αναλαμβάνει νέος αρχισυντάκτης ο παλιότερος τακτικός συνεργάτης του περιοδικού που παραμένει ενεργός (μία ευνόητη και φυσιολογική εξέλιξη νομίζω), ο [Βαγγέλης
Παπαδογιαννάκης](mailto:papas@hellug.gr). Τα άρθρα του συνήθως είναι πρώτα από πλευράς αναγνωσιμότητας σε όποιο τεύχος συμμετέχουν σύμφωνα με τα στατιστικά μας,
ενώ έχει και το ρεκόρ να έχει γράψει το άρθρο με την μεγαλύτερη αναγνωσιμότητα που εμφανίστηκε στο Magaz από τότε που κρατάμε στατιστικά (το Enlightenment του
τεύχους 14). Ο Βαγγέλης έχει μεταξύ των άλλων και τις τεχνικές γνώσεις να διορθώσει τυχόν προβλήματα που θα προκύψουν, και με βάση όλα τα παραπάνω φαντάζομαι
ότι η μετάβαση θα γίνει χωρίς καν να το καταλάβετε (ή, ελπίζω, αν το καταλάβετε, θα δείτε βελτίωση).
Είμαι σίγουρος ότι ο Βαγγέλης θα δώσει νέα πνοή στο Magaz, ενώ περιμένω από τους μέχρι τώρα συνεργάτες του Magaz (τους οποίους και ευχαριστώ προσωπικά για την
καλή συνεργασία που είχαμε) να τον στηρίξουν και βοηθήσουν στο δύσκολο έργο που αναλαμβάνει. Το Magaz πάντα στηριζόταν, και θα συνεχίσει να στηρίζεται, στην
καλή θέληση και διάθεση όλων των μελών της κοινότητας να στείλουν άρθρα. Αν αυτή η διάθεση σταματήσει να υπάρχει, το Magaz απλά θα σταματήσει να βγαίνει. Είναι
λοιπόν ευθύνη όλων μας να συνεισφέρουμε στην συνέχιση του Magaz.
Να επισημάνω για άλλη μία φορά (τρίτη) ότι το Magaz δεν βγαίνει κάθε μήνα. Βγαίνει 10 φορές το χρόνο. Αυτό το λέω, για να προλάβω αντιδράσεις του τύπου \"άλλαξε
η δομή του και εξαφανίστηκε\" :-)
Να στείλω τέλος, για τελευταία φορά ως αρχισυντάκτης του περιοδικού, μία πρόσκληση προς κάθε εύηκοον ους για αποστολή άρθρων.\
Ευχαριστώ όλους που με ανεχτήκατε σε αυτό το ταξίδι των δυόμιση χρόνων. Θα τα ξαναπούμε πιστεύω, από άλλο μετερίζι. Εύχομαι στον νέο αρχισυντάκτη καλή δύναμη
και καλή επιτυχία στο δύσκολο έργο που αναλαμβάνει.
Καλή ανάγνωση\...

236
content/articles/24/02_xbasic.md Κανονικό αρχείο

@ -0,0 +1,236 @@
+++
title = 'Xbasic'
date = '0000-04-01T00:00:00Z'
description = ''
author = 'Κώστας Τσακάλογλου(mailto:tsakf@hellug.gr)'
issue = ['Magaz 24']
issue_weight = 2
+++
----------------------------------------------------------------------------------------------------------------------------------------------------------------
*Μία γλώσσα προγραμματισμού Basic που έχει αρκετά στοιχεία C. Μέρος ΙΙ*
----------------------------------------------------------------------------------------------------------------------------------------------------------------
Μετα από μια πρώτη ματιά και την πρώτη προσπάθεια να γράψω ένα πρόγραμμα σκέφτηκα ότι πρώτα πρέπει να εξοικειωθώ με το περιβάλλον ανάπτυξης εφαρμογών της XBASIC
για να μπορώ να δουλέψω καλύτερα. Στο σημερινό άρθρο θα σας παρουσιάσω το περιβάλλον ανάπτυξης για να είναι κατανοητό το παράδειγμα εφαρμογής που θα γραφτεί
μετά.
**1. Περιβάλλον συγγραφής του κώδικα**
---------------------------------------------------------------
**2. Παράθυρο εμφάνισης αποτελεσμάτων**
----------------------------------------------------------------
**3. Παράθυρο κατασκευής γραφικών αντικειμένων**
-------------------------------------------------------------------------
**4. Επίλογος**
----------------------------------------
### [1. Περιβάλλον συγγραφής του κώδικα]{#s1}
![](/24/img/xbdev1.gif)
Σε αυτό το παράθυρο γράφουμε τον κώδικα και έχουμε όλες τις δυνατότητες που έχουν τα σύγχρονα περιβάλλοντα προγραμματισμού. Πχ. σημεία προσωρινής παύσης
(breakpoints), εμφάνιση τιμών μεταβλητών κ.λ.π.\
Αναλυτικά θα δούμε τις κυριώτερες επιλογές των μενού.
- FileNew\
Επιλέγεται νέο αρχείο. Διαγράφεται ότι έχει παραμείνει στην μνήμη και διακόπτεται οποιαδήποτε λειτουργία. Τα δεδομένα δεν αποθηκεύονται έτσι πρέπει να έχει
γίνει πριν αποθήκευση αν θέλουμε να χρησιμοποιήσουμε πάλι το πρόγραμμα που μόλις είχαμε γράψει. Η επιλογή αυτή έχει μας δίνει την δυνατότητα να
δημιουργήσουμε 3 διαφορετικούς τύπους κώδικα.
1. Απλό αρχείο χαρακτήρων (text file)
2. Κανονικό πρόγραμμα BASIC (χωρίς την χρήση γραφικού περιβάλλοντος)
3. Πρόγραμμα που χρησιμοποιεί γραφικό περιβάλλον (φόρμες, κουμπιά κ.λ.π.)
- FileTextLoad\
Με αυτή την επιλογή μπορούμε να φορτώσουμε στο περιβάλλον αρχεία χαρακτήρων (text files) που μπορεί να μην είναι πρόγραμμα πχ. σημειώσεις. Στο περιβάλλον
δεν υποστηρίζεται η εμφάνιση χαρακτήρων πάνω από το 128 όπου αν υπάρχουν τέτoιοι χαρακτήρες θα φαίνονται περίεργα. Επίσης στο αρχείο χαρακτήρων δεν πρέπει
να υπάρχουν χαρακτήρες NULL. Βέβαια εδώ δημιουργείται το ερώτημα τι γινέται με τα Ελληνικα; Νομίζω όμως οτι μπορούμε να ξεπεράσουμε αυτόν τον περιορισμό αν
τα μηνύματα του προγράμματος δεν είναι μέσα στο ν κώδικα αλλά σε αρχείο όπου θα διαβάζεται από το πρόγραμμα. Αυτός ο τρόπος δίνει επίσης την δυνατότητα να
έχουμε διαφορετικά αρχεία για κάθε γλώσσα και έτσι νομίζω ότι ο περιορισμός του περιβάλλοντος να μην δέχεται χαρακτήρες \> 128 δεν είναι σπουδαίο πρόβλημα.
- FileLoad\
Φορτώνεται στο περιβάλλον ένα πρόγραμμα που εχει αποθηκευθεί από πριν.
- FileSave\
Αποθηκεύεται το τρέχον πρόγραμμα σε αρχείο.
- FileMode\
Επιλέγεται ο τρόπος λειτουργίας του περιβάλλοντος. Text mode είναι για να μπορούμε να επεξεργαζόμαστε οποιοδήποτε κείμενο ενώ το Program Mode μας δίνει τις
ευκολίες που χρειαζόμαστε για το γράψιμο προγραμμάτων
- FileRename\
Το επιλέγουμε για να αλλάξουμε το όνομα του προγράμματος που έχουμε στην μνήμη.
- FileQuit\
Δηλώνουμε ότι θέλουμε να εγκαταλείψουμε το περιβάλλον εργασίας και άν έχουμε κάνει μεταβολές στο πρόγραμμά μας το περιβάλλον μας ζητά επιβεβαίωση και φύλαξη
των τελευταίων αλλαγών άν θέλουμε.
- EditCut\
Διαγράφει καί αποθηκεύει σε προσωρική μνήμη (clipboard) το επιλεγμένο κείμενο.
- EditGrab\
Αντιγράφει το επιλεγμένο κείμενο στην προσωρινή μνήμη (clipboard).
- EditPaste\
Παρεμβάλλει στο τρέχον σημείο ότι είναι αποθηκευμένο στην μνήμη.
- EditFind\
Αναζήτηση κειμένου στο πρόγραμμα
- Edit\_\_\
Αντικατάσταση κειμένου με άλλο
- EditRead\
Ανάγνωση αρχείου στην προσωρινή μνήμη (clipboard).
- EditWrite\
Εγγραφή σε αρχείο της προσωρινής μνήμης (clipboard).
- EditAbandon\
Ακύρωση όλων των αλλαγών στην τρέχουσα ρουτίνα.
- ViewFunction\
Εμφανίζεται παράθυρο με όλες τις ρουτίνες του προγράμματος και επιλέγεται η επιθυμητή.
- ViewPriorFunction\
Εμφανίζεται η προηγούμενη ρουτίνα
- ViewNewFunction\
Δημιουργούμε μια νέα ρουτίνα και καθορίζουμε το όνομά της, παραμέτρους κλπ.
- ViewDeleteFunction\
Εμφανίζεται κατάλογος με όλες τις ρουτίνες και επιλέγουμε αυτήν πρός διαγραφή.
- ViewRenameFunction\
Δίνεται η δυνατότητα αλλαγής ονόματος της τρέχουσας ρουτίνας. Με την εντολή αλλαγής όλες οι κλήσεις σε αυτή την ρουτίνα προσαρμόζονται ανάλογα.
- ViewCloneFunction\
Αναπαράγεται ένα πιστό αντίγραφο κάποιας ρουτίνας.
- ViewLoadFunction\
Φορτώνεται μια ρουτίνα από αρχείο και ενσωματώνεται στο ήδη υπάρχον πρόγραμμα.
- ViewSaveFunction\
Αποθηκεύεται μια ρουτίνα σε αρχείο για την μεταφορά της όπως είναι σε άλλο πρόγραμμα.
- Options\
Επηρεάζεονται οι παράμετροι εμφάνισης του περιβάλλοντος και οι παράμετροι της μεταγλώττισης (Compile).
- RunStart\
Εκτελείται το τρέχον πρόγραμμα
- RunContinue\
Συνεχίζεται η εκτέλεση μετά από διακοπή της εκτέλεσης του προγράμματος.
- RunPause\
Διακοπή της εκτέλεσης του προγράμματος για τον έλεγχο μεταβλητών ή κλήσεων ρουτινών.
- RunKill\
Τερματισμός της λειτουργίας του προγράμματος και μηδενισμός μεταβλητών.
- RunRecompile\
Γίνεται μεταγλώττιση του προγράμματος χωρίς να εκτελεστεί για το έλεγχο λαθών σύνταξης κλπ.
- RunAssembly\
Γίνεται μεταγλώττιση του προγράμματος σε γλώσσα Assembly και αποθηκεύεται στον δίσκο με το επίθεμα .a
- RunLibrary\
Γίνεται μεταγλώττιση του προγράμματος σε γλώσσα Assembly και αποθηκεύεται στον δίσκο με το επίθεμα .a για να χρησιμοποιηθεί για την δημιουργία βιβλιοθηκών
ρουτινών.
- DebugToggleBreakpoint\
Τοποθετείται/ακυρώνεται στην τρέχουσα γραμμή σημείο διακοπής εκτέλεσης (Breakpoint) για έλεγχο της ροής και τνω μεταβλητών του προγράμματος.
- DebugClearBreakpoints\
Ακυρώνονται τα σημεία διακοπής (Breakpoints) σε όλο το πρόγραμμα.
- DebugEraseBreakpoints\
Ακυρώνονται τα σημεία διακοπής (Breakpoints) στην τρέχουσα ρουτίνα.
- DebugMemory\
Εμφανίζονται τα περιεχόμενα της μνήμης σε σημεία πού επιλέγετε.
- DebugAssembly\
Εμφανίζεται η τρέχουσα γραμμή σε μορφή Assembly και μπορούμε να προχωράμε τις εντολές βήμα-βήμα.
- DebugRegisters\
Εμφανίζονται τα περιεχόμενα των καταχωρητών (Registers) του επεξεργαστή.
- Help\
Βοήθεια για την λειτουργία το περιβάλλοντος προγραμματισμού.
### [2. Παράθυρο εμφάνισης αποτελεσμάτων]{#s2}
![](/24/img/xbdev2.gif)
Σε αυτό το πραράθυρο εμφανίζονται τα μυνήματα εισόδου/εξόδου όταν η εφαρμογή μας δεν είναι κατασκευασμένη για γραφικό περιβάλλον. Εμφανίζονται τα αποτελέσματα
(output) ή οι ερωτήσεις για πληκτρολόγηση δεδεομένων (input) με το απλό στύλ της κονσόλας.\
Για απλά προγράμματα χωρίς περίπλοκη εισαγωγή δεδομένων είναι ότι πρέπει γιατί δεν υπάρχει λόγος να μπλέξουμε με γραφικό περιβάλλον στις απλές εφαρμογές.
### [3. Παράθυρο κατασκευής γραφικών αντικειμένων]{#s3}
![](/24/img/intro3.gif)
Με την βοήθεια του toolkit μπορούμε να δημιουργήσουμε παράθυρα,κουμπιά και ότι άλλο προσφέρει το GuiDesigner για να κατασκευάσουμε το περιβάλλον της εφαρμογής
μας. Για να φανούν οι δυνατότητες του, θα αναφέρω παρακάτω ένα-ένα τα εικονίδια και τι κάνει το κάθε ένα. Πρώτα από όλα να δούμε τι κάνουν τα μενού.
![](/24/img/guiguide35.gif)
Επιλέγοντας το Window μπορούμε να δημιουργήσουμε νέο παράθυρο, να εξαφανίσουμε το τρέχον, να ανακαλέσουμε κάποιο παλαιό για διόρθωση/συμπλήρωμα, να
αποθηκεύσουμε αυτό που έχουμε δημιουργήσει ή και να διαγράψουμε μόνιμα το τρέχον παράθυρο. Προσοχή! Δεν υπάρχει τρόπος να ανακληθεί παράθυρο που έχει διαγραφεί.
Ο τρόπος αποθήκευσης είναι τέτοιος ώστε τα παράθυρα αποθηκεύνται με ειδικές παραμέτρους για να μπορούν να ενσωματωθούν και να επικοινωνούν με την εφαρμογή μας.
Η τρίτη και δεύτερη επιλογή από το τέλος κάνει αυτή την μετατροπή στην μνήμη για να είναι άμεσα διαθέσιμες οι εντολές στο πρόγραμμά μας. Η τελευταία επιλογή
είναι φανερό ότι είναι το τέλος λειτουργίας του GuiDesigner.
![](/24/img/guiguide36.gif)
Επιλέγοντας το Grid μπορούμε να ρυθμίσουμε την εμφάνιση, την συμεριφορά, την σειρά και την εξάρτηση (ποιό αντικείμενο ανήκει που, ομάδες κλπ) του κάθε
αντικειμένου. Η τελευταία επιλογή είναι για την διαγραφή του τρέχοντος αντικειμένου.\
Παρακάτω θα δούμε ένα ένα τα αντικείμενα του γραφικού περιβάλλοντος ένα ένα.
----------------------------------------------------- ----------------------------------------------------- -----------------------------------------------------
\ XuiColor. Επιλογή χρωμάτων (125 διαθέσιμα)
![](/24/img/guiguide4.gif)
![](/24/img/guiguide5.gif) XuiLabel. Εμφάνιση γραμμών κειμένου ή εικόνας
![](/24/img/guiguide6.gif) XuiCheckBox Επιλογή ανεξαρτήτων επιλογών (όχι μία από ομάδα)..
![](/24/img/guiguide7.gif) XuiRadioBox Επιλογή από μια ομάδα XuiRadioBox.
![](/24/img/guiguide8.gif) XuiPressButton Επιλέγεται όταν πατήσουμε το ποντίκι.
![](/24/img/guiguide9.gif) XuiPushButton Επιλέγεται όταν πατήσουμε και αφήσουμε το ποντίκι.
![](/24/img/guiguide10.gif) XuiToggleButton Με το πρώτο πάτημα ένεργοποιείται και με το δεύτερο
απενεργοποιείται.
![](/24/img/guiguide11.gif) XuiScrollBarH Οριζόντια κίνηση/τοποθέτηση.
![](/24/img/guiguide12.gif) XuiScrollBarV Κάθετη κίνηση/τοποθέτηση.
![](/24/img/guiguide13.gif) XuiTextLine Εισαγωγή κειμένου (μία γραμμή).
![](/24/img/guiguide14.gif) XuiTextArea Εισαγωγή κειμένου (πολλές γραμμές).
![](/24/img/guiguide15.gif) XuiMenu Δημιουργία μενού εντολών.
![](/24/img/guiguide16.gif) XuiMenuBar Μενού επιλογών σε οριζόντια διάταξη.
![](/24/img/guiguide17.gif) XuiPullDown Μενού επιλογών σε κάθετη διάταξη.
![](/24/img/guiguide18.gif) XuiList Επιλογή ενός στοιχείου διαθέσιμου από μια λίστα.
![](/24/img/guiguide19.gif) ![](/24/img/guiguide20.gif) XuiMessage1B/2B/3B/4B Εμφάνιση μηνύματος με 1/2/3/4 κουμπιά επιλογών
![](/24/img/guiguide21.gif) ![](/24/img/guiguide22.gif) αντίστοιχα.
![](/24/img/guiguide23.gif) XuiProgress Εμφάνιση ποσοστού εκτέλεσης/υπολοίπου για κάποια
διαδικασία.
![](/24/img/guiguide24.gif) ![](/24/img/guiguide25.gif) XuiDialog2B/3B/4B Εμφάνιση μηνύματος και αποδοχή απάντησης από τον
![](/24/img/guiguide26.gif) χρήστη με 2/3/4 κουμπιά επιλογών.
![](/24/img/guiguide27.gif) XuiDropButton Εμφάνιση λίστας επιλογών με πάτημα κουμπιού.
![](/24/img/guiguide28.gif) XuiDropBox Καταχώρηση κειμένου ή επιλογή από λίστα επιλογών
![](/24/img/guiguide29.gif) XuiListButton Εμφάνιση λίστας επιλογών με πάτημα κουμπιού με μπάρα
μετακίνησης στην λίστα.
![](/24/img/guiguide30.gif) XuiListBox Καταχώρηση κειμένου ή επιλογή από λίστα επιλογών με
μπάρα μετακίνησης στην λίστα .
![](/24/img/guiguide31.gif) XuiRange Εμφάνιση τιμής και μεταβολή της +- με το πάτημα
κουμπιών.
![](/24/img/guiguide32.gif) XuiFile Ετοιμο παράθυρο για την επιλογή αρχείου
![](/24/img/guiguide33.gif) XuiFont Ετοιμο παράθυρο επιλογής χαρακτήρων. (Είδος, μέγεθος,
έντονα κλπ.)
![](/24/img/guiguide34.gif) XuiListDialog2B Εμφάνιση μηνύματος και αποδοχή απάντησης από τον
χρήστη με 2 κουμπιά
----------------------------------------------------- ----------------------------------------------------- -----------------------------------------------------
Αυτά είναι τα διάφορα αντικείμενα που μπορούμε να χρησιμοποιήσουμε για να κατασκευάσουμε την παραθυρική εφαρμογή μας.
### [4. Επίλογος]{#s4}
Μετά την πρώτη γνωριμία με το περιβάλλον στο επόμενο άρθρο θα δούμε τα βασικά δομικά στοιχεία που αποτελούν μια εφαρμογή XBASIC είτε σε περιβάλλον κονσόλας είτε
σε παραθυρικό περιβάλλον (φόρμες, κουμπιά, πεδία κλπ.) Θα γίνουν και κάποια συγκριτικά τεστ με τις άλλες δύο Basic που ξέρω (Basic για το DOS και Visual Basic
gia ta Windows) έτσι για να δούμε και τί γίνεται από ταχύτητες και θα αναφέρω ότι άλλο δώ ότι είναι ενδιαφέρον κάποιος να ξέρει πρίν ξενικήσει να γράψει την
πρώτη του εφαρμογή. Θα τα ξαναπούμε στο επόμενο Magaz.

505
content/articles/24/03_gawk.md Κανονικό αρχείο

@ -0,0 +1,505 @@
+++
title = 'Προγραμματισμός με gawk μέρος 2ο'
date = '2000-04-01T00:00:00Z'
description = ''
author = 'DJ Art(mailto:djart@hellug.gr)'
issue = ['Magaz 24']
issue_weight = 3
+++
----------------------------------------------------------------------------------------------------------------------------------------------------------------
*Το άρθρο αυτό αποτελεί το δεύτερο (και τελευταίο) μέρος της παρουσίασης της γλώσσας awk με στόχο την βοήθεια για την εκμάθησή της.*
----------------------------------------------------------------------------------------------------------------------------------------------------------------
**1. Ενσωματωμένες συναρτήσεις**
-------------------------------------------------------
**2. Αριθμητικοί τελεστές**
--------------------------------------------------
**3. Εντολές ελέγχου ροής**
--------------------------------------------------
- [3.1 If](#ss3.1)
- [3.2 Υποθετικός τελεστής](#ss3.2)
- [3.3 βρόγχοι](#ss3.3)
**4. Advanced Input**
--------------------------------------------
- [4.1 Next](#ss4.1)
- [4.2 Exit](#ss4.2)
- [4.3 Getline](#ss4.3)
- [4.4 Input από αρχείο](#ss4.4)
- [4.5 Input από εντολή](#ss4.5)
- [4.6 Τερματίζοντας το Input από αρχείο ή εντολή](#ss4.6)
**5. Advanced Output**
---------------------------------------------
- [5.1 Printf](#ss5.1)
- [5.2 Output σε αρχείο](#ss5.2)
- [5.3 Output σε εντολή](#ss5.3)
- [5.4 Τερματίζοντας το Output από αρχείο ή εντολή](#ss5.4)
**6. Συναρτήσεις**
-----------------------------------------
- [6.1 Δήλωση της συνάρτησης](#ss6.1)
- [6.2 Συνάρτηση με παραμέτρους](#ss6.2)
- [6.3 Η δήλωση return](#ss6.3)
- [6.4 Η συνάρτηση system](#ss6.4)
**7. Βιβλιογραφία**
------------------------------------------
### [1. Ενσωματωμένες συναρτήσεις]{#s1}
Παρακάτω, μπορείτε να δείτε έναν πίνακα με χρήσιμες συναρτήσεις που μπορείτε να χρησιμοποιήσετε σε ένα πρόγραμμά σας:
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
\ Επιστρέφει το ημίτονο του x
sin(x)
cos(x) Επιστρέφει το συνημίτονο του x
int(x) Επιστρέφει το ακέραιο μέρος του x
log(x) Επιστρέφει το φυσικό λογάριθμο του x
exp(x) Eπιστρέφει το e υψωμένο στη δύναμη του x
sqrt(x) Επιστρέφει την τετραγωνική ρίζα του x
getline() Διαβάζει την επόμενη γραμμή από το αρχείο.\
Επιστρέφει 0 για το τέλος του αρχείου, διαφορετικά,\
επιστρέφει 1
rand() Επιστρέφει έναν τυχαίο αριθμό ανάμεσα στο 0 και στο 1.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
### [2. Αριθμητικοί τελεστές]{#s2}
Εδώ, επίσης θα δείτε έναν πίνακα, ο οποίος παρουσιάζει τους τελεστές που μπορείτε να χρησιμοποιήσετε για να κάνετε αριθμητικές πράξεις:
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
\ Υψώνει το x στη δύναμη του y
x\^y
x\*\*y Κάνε ακριβώς την ίδια δουλειά με τον παραπάνω τελεστή
x%y Υπολογίζει το υπόλοιπο της διαίρεσης x/y
x+y Προσθέτει το x στο y
x-y Αφαιρεί το y από το x
x\*y Πολλαπλασιάζει το x με το y
x/y Διαιρεί το x με το y
-x Επιστρέφει τον αντίθετο του x (αλλάζει το πρόσημο)
++x Αυξάνει τον x κατά 1 και χρησιμοποιεί την τιμή (όλου αυτού)
x++ Χρησιμοποιεί πρώτα την τιμή του x και μετά την αυξάνει κατά 1
\--x (αντίστοιχα με τα παραπάνω)
x\-- (αντίστοιχα με τα παραπάνω
x=y Αποδίδει την τιμή του y στον x
x+=y Ισοδυναμεί με την παράσταση x=x+y
x/=y Iσοδυναμεί με την παράσταση x=x/y
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
**Παραδείγματα**\
Ακόμα μπερδευόσαστε με τα x++ και ++x ; :-) Πάμε, λοιπόν, να δούμε μέσα από παραδείγματα τί ακριβώς προσφέρουν:
x++\
Αυτή εδώ η παράσταση ισοδυναμεί με την παράσταση x=x+1. Λοιπόν, προσέξτε: όσοι ασχολούνται για πρώτη φορά με τον προγραμματισμό, πρέπει να δώσουν ιδιαίτερη
προσοχή με το σύμβολο της ισότητας. Εδώ το = δεν σημαίνει ακριβώς \"ίσον\" !!! Το σύμβολο = χρησιμοποιείται για να αποδώσει τιμές. Δηλαδή, στην ισότητα x=x+1,
δεν πρέπει κανείς να πάει και \"να φέρει το x στο πρώτο μέλος, οπότε να μείνει 0=1\" !!! Απλά, το = κάνει το εξής: αποδίδει στην μεταβλητή x την τιμή που
υπάρχει στο δεξί μέρος του, δηλαδή, αν αρχικά είχαμε ορίσει ότι το x είναι ίσο με 3, τώρα, μετά από αυτήν την δήλωση, το x θα είναι ίσο με 4.
y = x++\
Αυτή εδώ η παράσταση, αντιστοιχεί σε δύο παραστάσεις, στην y=x και στην x=x+1. Δηλαδή, αν αρχικά το x είναι ίσο με 3, τότε το y ισούται με 3 (**ΠΡΟΣΟΧΗ εδώ**),
ενώ το x πιά ισούται με 4 !!!! Κοιτάξτε και το παρακάτω παράδειγμα για να καταλάβετε:
y = \--x\
Λοιπόν, και αυτή η παράσταση αντιστοιχεί σε άλλες δύο, στην x=x-1 και στην y=x. Μα, θα μου πείτε, αυτές οι δύο δεν έχουν διαφορά με τις παραπάνω. Πρέπει να
λάβετε υπ\' όψιν την σειρά με την οποία εκτελούνται οι παραστάσεις, δηλαδή εδω, **ΠΡΩΤΑ** μειώνεται η τιμή του x κατά 1 και **ΜΕΤΑ** αποδίδεται η τιμή (του
μειωμένου πιά x) στην μεταβλητή y, δηλαδή αν είχαμε αρχικά ότι το x ισούται με 3, τότε τώρα πιά, το x **ΑΛΛΑ ΚΑΙ ΤΟ** y ισούται με 2.
### [3. Εντολές ελέγχου ροής]{#s3}
### [3.1 If]{#ss3.1}
Απο τη φύση της, η gawk έχει την εξής μορφή: αν το πρότυπο ικανοποιείται, τότε εκτελείται η πράξη. Φυσικά, έχετε τη δυνατότητα να γράψετε ένα πρόγραμμα με
\"υποθετική ροή\". Αυτό μπορείτε να το κάνετε, φυσικά, με το if.
Η γενική δομή του if έχει ως εξής:
if (υπόθεση)
εντολή που εκτελείται αν η υπόθεσή μας είναι αληθινή
else
εντολή που εκτελείται αν η υπόθεσή μας δεν είναι αληθινή
Η υπόθεσή μας μπορεί να είναι οποισδήποτε συνδυασμός προτύπων από αυτά που είπαμε στο 1ο μέρος. Τώρα, αν θέλετε να εκτελούνται περισσότερες από μία εντολές,
μετά τον έλεγχο αληθείας της υπόθεσης, τότε θα πρέπει να \"περικυκλώσετε\" τις εντολές με αγκύλες ({ }), ακριβώς όπως και στη C.
Μπορείτε να χρησιμοποιήσετε πολλά if στη σειρά (και μετά από ένα else) με τον εξής τρόπο:
if ("Linux" in magaz_subject)
print "We are studying Linux :-)"
else if ("gawk" in magaz_subject)
print "We are studying awk :-)"
else
print "We are doing nothing :-("
### [3.2 Υποθετικός τελεστής]{#ss3.2}
Η gawk σας παρέχει με αυτόν τον τελεστή, ο οποίος αποτελείται από τρείς παραμέτρους, τη δυνατότητα να εφαρμόζετε if-ελέγχους ανά πάσα στιγμή μέσα στο πρόγραμμά
σας. Η μορφή του είναι η εξής:
υπόθεση ? αποτέλεσμα σε περίπτωση αλήθειας : εναλλακτικό αποτέλεσμα (σε μη-αληθινή περίπτωση)
Αυτός ο τελεστής καθιστά τα προγράμματά σας πιο ευανάγνωστα. Ας δούμε ένα παράδειγμα χρήσης του παραπάνω τελεστή σε περίπτωση όπου ανάλογα με τον αριθμό των
αρχείων που αντιγράφηκαν, θέλουμε πληθυντικό ή ενικό:
{ print $1, "αρχεί" $1 != 1 ? "α αντιγράφηκαν" : "ο αντιγράφηκε" }
Αν θα θέλαμε να γράψουμε το παραπάνω, χρησιμοποιώντας το if, τότε θα γράφαμε:
if ( $1 != 1 )
print $1, "αρχεία αντιγράφηκαν"
else
print $1, "αρχείο αντιγράφηκε"
### [3.3 βρόγχοι]{#ss3.3}
H awk υποστηρίζει τους βρόγχους do, for και while, όπως ακριβώς αυτοί συντάσσονται στην C. Μια γενική συμβουλή (για όλους τους βρόγχους) είναι να μην ξεχνάτε να
χρησιμοποιείτε αγκύλες ({ }) όταν θέλετε μέσα στο βρόγχο να εκτελέσετε πάνω από μία εντολές. Ένα λάθος που γίνεται συχνά είναι ακριβώς αυτό, να ξεχνάει κανείς
τις αγκύλες.
#### Do
Ο βρόγχος do (συνήθως καλείται και do-while) αποτελείται από δύο μέρη: τις εντολές που θέλουμε να εκτελέσουμε και τον (υποθετικό) έλεγχο. Προσέξτε πως αυτός ο
βρόγχος έχει το χαρακτηριστικό να εκτελούνται οι εντολές που του δηλώνουμε τουλάχιστον μία φορά, καθώς ο υποθετικός έλεγχος που \"επιβάλλουμε\" αναγράφεται μετά
την δήλωση των εντολών. Για να το καταλάβετε καλύτερα, ας δούμε τη σύνταξη του do:
do
εντολές
while (υπόθεση)
π.χ:
do
print "Magaz kicks!!"
while ($1 != 1)
Το μήνυμα της print θα εκτελείται μέχρι το πρώτο πεδίο (\$1) να πάρει την τιμή 1. Όμως, ακόμα και αν το \$1 \"ξεκινάει\" με αρχική τιμή 1, τότε το μήνυμα θα
τυπωθεί. Απλά, όταν θα γίνει ο έλεγχος και \"ικανοποιηθεί\" η while, δεν θα ξαναγυρίσουμε στο do, αλλά το πρόγραμμα θα προχωρήσει στις τυχόν παρακάτω εντολές.
#### For
O βρόγχος for είναι ένας πασίγνωστος βρόγχος στις γλώσσες προγραμματισμού. Ας δούμε κατ\' ευθείαν την σύνταξή του για να καταλάβουμε τη λειτουργία του:
for (i = 0; i < 100; i++)
{
εντολή 1
εντολή 2
}
Παραπάνω, οι εντολές του βρόγχου θα εκτελεστούν 100 φορές!! Ας δούμε γιατί: Αρχικά, ορίζουμε μιά μεταβλητή, την i, η οποία θα μας χρησιμεύσει απλά και μόνο για
το πόσες φορές θα εκτελεστεί ο βρόγχος, και δίνουμε στην i την τιμή 0. Μετά, η for κοιτάει τη 2η δήλωση στην παρένθεση (οι δηλώσεις, υπενθυμίζω, χωρίζονται με
;) και κάνει τον υποθετικό έλεγχο. Στην περίπτωσή μας, ελέγχεται αν η τιμή της μεταβλητής i είναι μικρότερη από 100 και αν είναι, τότε εκτελούνται οι εντολές
που καθορίσαμε. Μετά (και εδώ φαίνεται η \"δυναμη\" της for), δεν χρειάζεται να \"κανονίσουμε\" εμείς την μεταβλητή i, αλλά έχουμε δηλώσει η i να αυξάνεται κατά
1. Η for λοιπόν, αυξάνει την τιμή της i και ξαναρχίζει: κάνει τον έλεγχο, εκτελεί της εντολές, αυξάνει την i κ.ο.κ. \... Όταν, λοιπόν, η i θα αποκτήσει την τιμή
100, τότε δεν θα εκτελεστούν οι εντολές, καθώς το αποτέλεσμα του ελέγχου 100 \< 100 είναι ψευδές (το 100 δεν είναι μικρότερο από το 100 !! :)
#### While
Ο βρόγχος while είναι αρκετά απλός και μάλλον θα έχετε ήδη καταλάβει πως λειτουργεί (από το βρόγχο do-while). Σε αντίθεση με την do, οι εντολές εκτελούνται μόνο
αν το αποτέλεσμα του υποθετικού ελέγχου, ο οποίος γίνεται στην αρχή του βρόγχου, είναι αληθής. Ας δούμε τη σύνταξή του:
while (υπόθεση)
εντολή(ες και μήν ξεχάσετε τις αγκύλες :)
Γενικά, για τους βρόγχους, να έχετε υπ\' όψιν πως μέσα στις εντολές του βρόγχου, η μεταβλητή πάνω στην οποία γίνεται ο υποθετικός έλεγχος, πρέπει να αλλάζει,
αλλιώς ο βρόγχος μας δεν τελειώνει ποτέ !!! (ατέρμων βρόγχος)
#### Έλεγχος στους βρόγχους
Όπως και στις υπόλοιπες γλώσσες προγραμματισμού, έτσι και στην awk, έχετε τη δυνατότητα να \"βγείτε\" από έναν βρόγχο (loop), \"νωρίτερα από το κανονικό\",
δηλαδή χωρίς να \"ικανοποιηθεί\" κάποιος υποθετικός έλεγχος και τερματίσει ο βρόγχος. Αυτό μπορείτε να το κάνετε με δύο εντολές: την break και την continue.
Με την εντολή break **\*ΑΚΑΡΙΑΙΑ\*** τερματίζετε τον βρόγχο και, φυσικά, όσες εντολές ακολουθούν την break **\*ΜΕΣΑ\*** στον βρόγχο, δεν εκτελούνται, αλλά το
πρόγραμμα θα συνεχίσει, εκτελώντας τις εντολές που τυχόν βρίσκονται μετά τον βρόγχο. Η εντολή break είναι σαν να εκτελείτε εκείνη την στιγμή τον υποθετικό
έλεγχο του βρόγχου, αλλά το αποτέλεσμα **\*ΒΕΒΙΑΣΜΕΝΑ\*** (από την break) είναι μή αληθές (FALSE).
Αντίθετα, η εντολή continue αναγκάζει τον βρόγχο να εκτελέσει τον υποθετικό του έλεγχο. Όσες τυχόν εντολές βρίσκονται μετά την continue (μέσα στο βρόγχο) δεν
εκτελούνται. Η continue δεν είναι σίγουρο πως θα \"τερματίσει\" το βρόγχο, αν το αποτέλεσμα του βρόγχου είναι αληθές (TRUE), τότε ο βρόγχος θα συνεχίσει να
εκτελείται. Η continue είναι ιδιαίτερα χρήσιμη αν θέλετε (για κάποιο λόγο, για κάποια συνθήκη) να \"παρακάμψετε\" κάποιες εντολές του κώδικα.
### [4. Advanced Input]{#s4}
Εξ ορισμού, η awk αυτόματα διαβάζει και εκτελεί συνέχεια την ίδια δουλειά: Διαβάζει μιά εγγραφή και αν ταιριάξει κάποιο πεδίο ή εγγραφή με το πρότυπο, τότε
εκτελεί την πράξη. Όμως, η awk σας δίνει την δυνατότητα να \"επέμβετε\" σε όλην αυτήν την διαδικασία και να πάρετε την είσοδο (input) από ένα άλλο αρχείο ή να
προκαλέσετε πρώιμο ξαναξεκίνημα της όλης διαδικασίας, να πάρετε είσοδο από την έξοδο κάποιας εντολής κλπ.
### [4.1 Next]{#ss4.1}
Η εντολή next \"υποχρεώνει\" την awk να διαβάσει την αμέσως επόμενη εγγραφή και να κάνει τα γνωστά (ταίριασμα των προτύπων και αν είναι αληθές, τότε εκτέλεση
της πράξης κλπ.), δηλαδή αγνοείται πλήρως η παρούσα εγγραφή που επεξεργάζεται η awk.
### [4.2 Exit]{#ss4.2}
Η εντολή exit, χρησιμοποιούμενη σε πράξη, συμπεριφέρεται σαν να έφτασε το τέλος του αρχείου (που επεξεργάζεται η awk). Αυτό έχει σαν συνέπεια να σταματήσει,
γενικότερα, η εκτέλεση του κώδικα, δεν εκτελούνται άλλες πράξεις, δεν ταιριάζονται άλλα πρότυπα. Στη συνέχεια, κανονικά, εκτελείται (αν υπάρχει, βέβαια) το
ειδικό πρότυπο END.
Αν τώρα, χρησιμοποιήσουμε την εντολή exit μέσα στο ειδικό πρότυπο END, τότε τερματίζεται ολόκληρο το πρόγραμμα, δεν εκτελείται τίποτα άλλο στη συνέχεια.
### [4.3 Getline]{#ss4.3}
Η εντολή getline διαβάζει μία εγγραφή \"κατηγορηματικά\", επιστρέφει 1 αν η ανάγνωση της εγγραφής ήταν επιτυχής (θυμίζω πως εξ ορισμού η κάθε γραμμή ενός
αρχείου αποτελεί μία εγγραφή), ή 0 αν δεν ήταν επιτυχής (δηλαδή αν έφτασε στο τέλος του αρχείου). Η getline συμπεριφέρεται \"κανονικά\", δηλαδή ορίζει με τον
σωστό τρόπο το \$0, ορίζει τις μεταβλητές πεδίων και τις μεταβλητές FNR, NR και NF).
### [4.4 Input από αρχείο]{#ss4.4}
Έτσι, λοιπόν, η getline μπορεί να χρησιμεύσει για να πάρετε είσοδο δεδομένων από κάποιο αρχείο, το οποίο δεν αναφέρατε στην γραμμή εντολών. Η γενική μορφή, με
την οποία χρησιμοποιούμε την getline σ\' αυτήν την περίπτωση είναι η getline \< \"filename\". Σε αυτήν την περίπτωση, αν το αρχείο υπάρχει και η getline διάβασε
εγγραφή, επιστρέφει 1, αλλιώς αν έφτασε στο τέλος του αρχείου επιστρέφει 0, ενώ αν το αρχείο δεν υπάρχει επιστρέφει -1.
ΣΗΜΕΙΩΣΗ: Και πάλι, οι μεταβλητές \$0, οι μεταβλητές πεδίων και η NF ορίζονται κανονικά, ενώ οι μεταβλητές FNR και NR **ΔΕΝ ΑΛΛΑΖΟΥΝ, ΠΑΡΑΜΕΝΟΥΝ ΩΣ ΕΙΧΑΝ !!**
### [4.5 Input από εντολή]{#ss4.5}
Μιά άλλη περίπτωση όπου χρησιμοποιείται η getline, είναι η είσοδος από UNIX εντολή. Ας δούμε πως μπορούμε να συντάξουμε κάτι τέτοιο:
while ("UNIX εντολή" | getline)
{
# ακολουθούν οι εντολές που θέλω να εκτελέσω
}
Φανταστείτε π.χ. πως θα θέλατε κάθε φορά που μπαίνει ένας χρήστης στο σύστημα, να τυπώνετε ένα μήνυμα (ή, τέλος πάντων, να κάνατε κάτι άλλο), τότε στη θέση της
UNIX εντολής θα βάζατε το who ή και το who -u.
### [4.6 Τερματίζοντας το Input από αρχείο ή εντολή]{#ss4.6}
Καλό θα είναι, κάθε φορά που χρησιμοποιείτε την getline για να \"ανοίξετε\" ένα αρχείο ή μία εντολή, δηλαδή να πάρετε είσοδο από αυτά, να τα \"κλείνετε\" όταν
τελειώσετε με αυτά. Υπάρχει ένας μέγιστος αριθμός \"ανοιχτών\" αρχείων/εντολών που επιτρέπεται σε έναν χρήστη (αυτός ο αριθμός ποικίλει από σύστημα σε σύστημα,
αλλά και ανάλογα με τις ρυθμίσεις του διαχειριστή του συστήματος). Με το να \"κλείνετε\" τις εντολές/αρχεία που χρησιμοποιήσατε, ουσιαστικά μειώνετε την
πιθανότητα να φτάσετε τον μέγιστο αριθμό. Λοιπόν, αυτό μπορείτε να το κάνετε με την εξής εντολή:
close ("filename")
Στη θέση του filename μπορείτε να χρησιμοποιήσετε είτε το όνομα κάποιας μεταβλητής (η οποία περιέχει αρχείο/εντολή) είτε το όνομα της εντολής που
χρησιμοποιήσατε (εδώ, προσέξτε να δηλώσετε την ακριβή εντολή που χρησιμοποιήσατε, π.χ. αν χρησιμοποιήσετε την who -u να γράψετε close (\"who -u\") \...).
### [5. Advanced Output]{#s5}
Μερικές πιο ειδικευμένες δυνατότητες υπάρχουν στην awk για την έξοδο (output). Αυτές είναι: το \"όμορφο\" φορμάρισμα του κειμένου, η ανακατεύθυνση του output σε
αρχεία (κειμένου) και η διασωλήνωση του output στην είσοδο (input) άλλων (εξωτερικών) εντολών του command prompt.
### [5.1 Printf]{#ss5.1}
Η εντολή print που είδαμε (στο 1ο μέρος), είναι αρκετά απλή και το output της είναι και αυτό αρκετά απλό. Αν, όμως, θέλετε να έχετε μορφοποιημένη την έξοδο του
προγράμματός σας (παραγωγή στηλών, για παράδειγμα), τότε θα πρέπει να χρησιμοποιήσετε την δανεισμένη από τη C εντολή, την printf. H printf έχει την εξής γενική
μορφή:
printf("αλφαριθμητικό ελέγχου", λίστα_ορισμάτων, 1ο όρισμα, 2ο όρισμα, κ.ο.κ.)
Το αλφαριθμητικό ελέγχου, μπορεί να αποτελείται από τα εξής στοιχεία:
1. Απλούς χαρακτήρες (δηλαδή κείμενο)
2. ειδικούς μεταχαρακτήρες (θυμάστε το \\n π.χ.)
3. Τις διαταγές φόρμας
Ας δούμε από ένα παράδειγμα για τα παραπάνω τρία στοιχεία, και μετά να μιλήσουμε περισσότερο για τις διαταγές φόρμας:
1. printf(\"hello world\")
2. printf(\"\\f\")
3. printf(\"%22s\", \"Magaz\")
4. Και φυσικά, συνδυασμό όλων αυτών των στοιχείων (θα το δούμε)
#### Διαταγές φόρμας
Λοιπόν, κάθε διαταγή φόρμας αποτελείται από 3 μέρη. Στο 1ο μέρος, **ΠΑΝΤΑ**, γράφουμε το σύμβολο του ποσοστού (**%**). Κάθε διαταγή φόρμας αρχίζει με αυτό το
σύμβολο. Το 2ο μέρος συμπληρώνεται προαιρετικά. Συμπληρώνεται με αριθμούς, οι οποίοι υποδηλώνουν το μέγιστο μήκος της εξόδου. Τέλος, το 3ο μέρος αποτελείται από
ειδικούς χαρακτήρες, οι οποίοι υποδηλώνουν το είδος της εξόδου (αν είναι αλφαριθμητικό, αν είναι δεκαδικός αριθμός κλπ.) Θα μιλήσουμε τώρα αναλυτικότερα για το
2ο μέρος και μετά θα δούμε έναν πίνακα με τους χαρακτήρες του 3ου μέρους.
Ο αριθμός, το εύρος πεδίου, αποτελείται από δύο αριθμούς οι οποίοι χωρίζονται με μία τελεία (.), δηλαδή είναι της μορφής x.y. Αν η έξοδος μας είναι δεκαδικός
αριθμός, τότε ο αριθμός αριστερά από την τελεία υποδηλώνει τον αριθμό ψηφίων **ΟΛΟΥ** του αριθμού (*συμπεριλαμβανόμενης της τελείας (.) του αριθμού*), ενώ ο
αριθμός δεξιά από την τελεία υποδηλώνει τον αριθμό ψηφίων του δεκαδικού μέρους του αριθμού. Αν τώρα, η έξοδος μας δεν είναι δεκαδικός αριθμός, αλλά ο,τιδήποτε
άλλο, τότε ο αριθμός αριστερά από την τελεία είναι ο ελάχιστος αριθμός ψηφίων/χαρακτήρων αυτού που θα τυπώσουμε, ενώ ο αριθμός δεξιά της τελείας είναι ο
μέγιστος αριθμός ψηφίων/χαρακτήρων και ο \"πραγματικός\" αριθμός των ψηφίων/χαρακτήρων που τελικά θα εκτυπωθούν. Δηλαδή, μπορείτε κάλλιστα να παραλείψετε τον
αριθμό αριστερά της τελείας (π.χ. %.4s)
**ΣΗΜΕΙΩΣΕΙΣ:**\
Αν θέλετε μέσα από την printf να τυπώσετε τον χαρακτήρα %, τότε θα γράψετε μέσα στον κώδικά σας %%.\
Εξ ορισμού, η έξοδος της printf είναι σε δεξιά στοίχιση. Αν θέλετε να έχετε αριστερή, τότε μπροστά από τον αριθμό που βρίσκεται αριστερά της τελείας (στο εύρος
πεδίου) βάζετε το σύμβολο μείον (-).
Παρακάτω, βλέπετε τον πίνακα με τους χαρακτήρες που μπορείτε να χρησιμοποιήσετε. Στη συνέχεια θα δούμε και παραδείγματα.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
\ **Σημασία**
**Κωδικός φόρμας**
%c Χαρακτήρας ASCII
%d Ακέραιος δεκαδικός αριθμός
%i Το ίδιο με το %d
%e Εκτύπωση δεκαδικού αριθμού κινητής υποδιαστολής με επιστημονική\
σημειογραφία, δηλαδή της μορφής \[-\]x.xxxxe\[-/+\]xxx
%f Δεκαδικός κινητής υποδιαστολής
%g Η awk κρίνει και διαλέγει για έναν αριθμό μία από τις μορφές %e και\
%f (όποια έχει μικρότερο μήκος) και, παράλληλα, \"απαλοίφει\" άχρηστα μηδενικά
%o Μη προσημασμένος (χωρίς πρόσημο) ακέραιος οκταδικός αριθμός
%s Αλφαριθμητικό
%x Μη προσημασμένος ακέραιος δεκαεξαδικός αριθμός (με πεζά τα abcdef)
%X Μη προσημασμένος ακέραιος δεκαεξαδικός αριθμός (με κεφαλαία τα ABCDEF)
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
#### Παραδείγματα
Επειδή θέλω να σας δείξω την λειτουργία του εύρους πεδίου, θα συμβολίζω τα κενά με παύλα (-), ώστε να μπορείτε να μετρήσετε τους χαρακτήρες και τα κενά (και να
βγάλετε τα συμπεράσματά σας):
printf("%10d\n", 29) (θα έχει σαν αποτέλεσμα:) --------29
printf("%-10d\n", 29) 29--------
printf("%10.3f\n", 123.56) ---123.560
printf("%15s\n", "Linux Magaz") ----Linux Magaz
printf("%-15s\n", "Linux Magaz") Linux Magaz----
### [5.2 Output σε αρχείο]{#ss5.2}
Όπως και στην περίπτωση της getline, έτσι και εδώ, μπορείτε να χρησιμοποιήσετε τα σύμβολα της ανακατεύθυνσης για να στείλετε την έξοδο κατ\' ευθείαν μέσα σε ένα
αρχείο. Π.χ:
printf("hello world\n") > "filename"
printf("hello world\n") >> "filename"
### [5.3 Output σε εντολή]{#ss5.3}
Σε αυτήν την περίπτωση, έχετε την δυνατότητα να στείλετε έξοδο (output) στην είσοδο (input) μιάς εξωτερικής εντολής του UNIX. Π.χ:
printf("hello world\n") | "sort -t , "
### [5.4 Τερματίζοντας το Output από αρχείο ή εντολή]{#ss5.4}
Ακριβώς για τους ίδιους λόγους που αναφέραμε στην getline, έτσι και εδώ, καλό θα ήταν να \"κλείνετε\" ένα αρχείο ή μία εντολή αφού τελειώσετε με αυτά. Η σύνταξη
είναι ακριβώς η ίδια: close (\"filename\") και στη θέση του filename χρησιμοποιείτε είτε όνομα αρχείου, είτε το όνομα της **ΑΚΡΙΒΟΥΣ** εντολής που τρέξατε με
διασωλήνωση, είτε το όνομα κάποιας μεταβλητής που \"δείχνει\" σε αρχείο.
### [6. Συναρτήσεις]{#s6}
**ΠΡΟΣΟΧΗ!!!**\
Οι συναρτήσεις (που ορίζονται από τον χρήστη) δεν υπάρχουν στην \"αυθεντική\" awk, αλλά προστέθηκαν αργότερα στην nawk και υποστηρίζονται από την gawk.
Όπως θα καταλάβατε, εκτός από τις ενσωματωμένες συναρτήσεις η gawk σας επιτρέπει να φτιάξετε τις δικές σας. Μία συνάρτηση χρησιμεύει σε ένα πρόγραμμα αν θέλετε
να επαναλάβετε τα ίδια κομμάτια κώδικα σε πολλά σημεία του προγράμματος, ώστε να μην ξαναγράφετε κάθε φορά το ίδιο πράγμα. Η χρήση των συναρτήσεων απαιτεί δύο
βήματα: την δήλωση της συνάρτησης και την κλήση της συνάρτησης μέσα στο πρόγραμμα.
### [6.1 Δήλωση της συνάρτησης]{#ss6.1}
Παρακάτω, θα δούμε τον κώδικα που απαιτείται για να δηλώσετε μιά συνάρτηση. Επιπλέον, να σημειώσω πως δεν παίζει κανέναν ρόλο η θέση που θα δηλώσετε την
συνάρτηση. Μπορείτε κάλλιστα να την δηλώσετε στο τέλος του προγράμματος.
function όνομα_συνάρτησης(παράμετροι) {
κώδικας της συνάρτησης
}
Τώρα θα δούμε τη λειτουργία των συναρτήσεων μέσα από τρία παραδείγματα. Το πρώτο παράδειγμα θα δείχνει την συνάρτηση στην απλή της μορφή (χωρίς παραμέτρους), το
δεύτερο παράδειγμα θα δείχνει τη χρήση, λειτουργία και χρησιμότητα των παραμέτρων, ενώ στο 3ο παράδειγμα, θα μιλήσουμε για την δήλωση return και θα δούμε το
αντίστοιχο παράδειγμα.
BEGIN { function1() }
function function1() {
printf("Magaz τεύχος 24\n");
printf("Άρθρο για gawk\n");
}
Όταν τρέξουμε το πρόγραμμα, το αποτέλεσμα θα είναι να μας τυπώσει στην οθόνη το περιεχόμενο των δύο printf, όπως ορίζονται μέσα στην συνάρτηση. Δώστε ιδιαίτερη
έμφαση στις παρενθέσεις της συνάρτησης, πάντα πρέπει να τις γράφετε (σε αντίθεση με τις ενσωματωμένες συναρτήσεις της awk, όπου είναι προαιρετική η αναγραφή των
παρενθέσεων).
### [6.2 Συνάρτηση με παραμέτρους]{#ss6.2}
Όταν χρησιμοποιούμε παραμέτρους στη συνάρτηση, τότε η αριθμητική αξία της μεταβλητής που αποτελεί την παράμετρο, αντιγράφεται και μετά \"περνάει\" στην
συνάρτηση. Αυτό έχει σαν αποτέλεσμα η αρχική τιμή της μεταβλητής-παραμέτρου να παραμένει αναλλοίωτη. Αυτό είναι ένα πλεονέκτημα, μπορεί να μας φανεί σε πολλές
περιπτώσεις χρήσιμο. Βέβαια, υπάρχει πάντα και η δυνατότητα να αλλοιωθεί, θα το δούμε παρακάτω. Ας δούμε τώρα ένα παράδειγμα:
BEGIN { variable = 0; function1(variable);
printf("Η τιμή της μεταβλητής variable είναι: %d\n", variable); }
function function1(variable2) {
variable2++;
printf("Η τιμή της μεταβλητής variable2 είναι: %d\n", variable2); }
Όταν εκτελέσουμε το πρόγραμμα θα δούμε πως θα μας τυπωθούν στην οθόνη δύο γραμμές. Η πρώτη γραμμή (που θα προέρχεται από την συνάρτηση) θα λέει πως η variable2
είναι ίση με 1, ενώ η δεύτερη θα λέει πως η variable είναι ίση με 0. Βλέπετε, λοιπόν, πως η τιμή της variable αντιγράφεται στην variable2 και δεν αλλάζει.
### [6.3 Η δήλωση return]{#ss6.3}
H return έχει δύο λειτουργίες: είτε να επιστρέψετε την τιμή της παραμέτρου, είτε να βγείτε από την συνάρτηση νωρίτερα. Η σύνταξή της είναι: return
όνομα\_μεταβλητής. Μπορείτε σε κάθε συνάρτηση να επιστρέψετε την τιμή *μόνο μίας μεταβλητής*, **όχι παραπάνω**. Ας δούμε το παράδειγμα:
BEGIN { variable = 0; function1(variable);
printf("Η τιμή της μεταβλητής variable είναι: %d\n", variable); }
function function1(variable2) {
variable2++;
printf("Η τιμή της μεταβλητής variable2 είναι: %d\n", variable2);
return variable2; }
Σε αυτήν την περίπτωση, θα τυπωθούν δύο γραμμές πάλι. Και στις δύο γραμμές η τιμή των μεταβλητών θα είναι ίση με 1, καθώς η τιμή της variable2 επέστρεψε στην
τιμή της variable.
### [6.4 Η συνάρτηση system]{#ss6.4}
Η συνάρτηση system είναι ενσωματωμένη στην awk. Είναι διαφορετική από τις άλλες, δεν ανήκει ούτε στην κατηγορία των αριθμητικών ούτε στην κατηγορία των
αλφαριθμητικών συναρτήσεων. Αυτό που πραγματικά κάνει είναι να εκτελεί το αλφαριθμητικό που της δόθηκε ως παράμετρος, επιτρέποντας στον προγραμματιστή να
εκτελεί απ\'ευθείας εντολές μέσα από το πρόγραμμα. Η σύνταξη της system έχει ως εξής:
system ("εντολή")
### [7. Βιβλιογραφία]{#s7}
Για την επίτευξη αυτού του άρθρου (συμπεριλαμβανομένου, φυσικά, και του 1ου μέρους) συμβουλεύτηκα τις εξής πηγές:
- Την man page της εντολής gawk (man gawk)
- Το βιβλίο \"Linux Unleashed\" της SAMS
- Το βιβλίο \"UNIX: Θεωρία και πράξη\" του Κώστα Ν. Γιαλελή
Αν θα θέλατε να κάνετε ένα βήμα παραπάνω από το άρθρο, θα σας συμβούλευα πριν ψάξετε οπουδήποτε αλλού, να διαβάσετε τουλάχιστον μία φορά το man page της gawk.
Είναι πολύ κατατοπιστικό και πολύ περιεκτικό.

88
content/articles/24/04_perldbi.md Κανονικό αρχείο

@ -0,0 +1,88 @@
+++
title = 'DataBaseInterface για Perl μέρος 2ο'
date = '2000-06-01T00:00:00Z'
description = ''
author = 'Μιχάλης Καμπριάνης(mailto:kabrianis@hellug.gr)'
issue = ['Magaz 24']
issue_weight = 4
+++
----------------------------------------------------------------------------------------------------------------------------------------------------------------
*Σε αυτό το τεύχος συνεχίζουμε την προσέγγιση στον προγραματισμό Perl για Databases μέσω του DBI interface που ξεκινήσαμε στο τεύχος Απριλίου.*
----------------------------------------------------------------------------------------------------------------------------------------------------------------
Αυτή τη φορά θα ασχοληθούμε με απλά κολπάκια για καλύτερο προγραμματισμό, τα οποία δεν αναφέραμε στο εισαγωγικό άρθρο. Ξεκινάμε:
1. Έλεγχος λαθών
Είχαμε πει στο προηγούμενο τεύχος ότι πρέπει ο προγραμματιστής να ελέγχει το exit status κάθε function που καλεί, για να δει αν πέτυχε ή όχι. Σε περίπτωση
που δεν πέτυχε μπορεί να κάνει κάποιες δουλειές, αλλά συνήθως θέλει να σταματάει η εργασία εκεί. Γι αυτό το DBI παρέχει το RaiseError. Αμέσως μετά τη
σύνδεση (ή και παράλληλα) μπορούμε να θέσουμε τη μεταβλητή RaiseError και τότε, σε κάθε error το πρόγραμμά μας θα σταματάει με ένα die.
Παράδειγμα 1
$dbh=DBI->connect('DBI:Pg:dbname=dbname user=dbuser password=dbpass');
$dbh->{RaiseError} = 1;
Η πρώτη γραμμή, απλά συνδέεται σε μία postgres database, στην βάση με όνομα dbname, με username dbuser και password dbpass. Η δεύτερη γραμμή θέτει τη
μεταβλητή RaiseError όπως λέγαμε. \`Αλλη μία μεταβλητή που μπορεί να τεθεί με αυτόν τον τρόπο, είναι η AutoCommit, για transactional databases. Αν δεν
ξέρετε τι είναι transactional database, καλά θα κάνετε να διαβάσετε το manual της βάσης σας.
2. Απ\' ευθείας ανάθεση αποτελεσμάτων σε μεταβλητές
Εκτός από την παραδοσιακή μέθοδο που είδαμε στο προηγούμενο τεύχος, να τοποθετούμε δηλαδή τα αποτελέσματα σε ένα array (μία στήλη αποτελεσμάτων είναι
αντίστοιχα ένα στοιχείο του array), μπορούμε να χρησιμοποιήσουμε την bind\_columns για να αναθέσουμε τα αποτελέσματα σε ήδη ορισμένες μεταβλητές.
Παράδειγμα 2
$entoli = $dbh->prepare('SELECT phone,name FROM clients WHERE id=?');
$entoli->execute($num);
$entoli->bind_columns(\$phone,\$name);
$entoli->fetch;
Το \$num καθώς και τα \$phone και \$name πρέπει προφανώς να τα έχουμε δηλώσει νωρίτερα. Προσοχή πρέπει να δοθεί στο ότι η bind\_columns δίνεται μετά την
execute. Επίσης όπως βλέπετε δεν χρησιμοποιούμε την fetchrow\_array αλλά την σκέτη fetch για να τραβήξουμε τα στοιχεία από την βάση.
3. Casting και πέρασμα παραμέτρων από πριν Μία άλλη μέθοδος που υποστηρίζει το DBI είναι η bind\_param(). Αυτή δίνει εξ αρχής στην execute τις παραμέτρους που
θα πάρει, δίνoντάς μας την δυνατότητα να κάνουμε και casting.
Παράδειγμα 2
$entoli = $dbh->prepare('SELECT phone,name FROM clients WHERE id=?');
$entoli->bind_param(1, $num, { TYPE => SQL_INTEGER });
$entoli->execute();
$entoli->bind_columns(\$phone,\$name);
$entoli->fetch;
Σε αυτό το παράδειγμα πριν καλέσουμε την execute λέμε στο DBI ότι στο πρώτο placeholder (όπου placeholder είναι το ερωτηματικό, και το πρώτο βγαίνει από το
1 που είναι το πρώτο όρισμα της bind\_param()) θα βάλει την τιμή \$num και θα πει στην βάση μας ότι είναι τύπου Integer. Αυτό σε ορισμένες περιπτώσεις είναι
χρήσιμο, αν και το σε ποιες ακριβώς, αφήνεται ως άσκηση στον αναγνώστη :-) Αν λοιπόν θέλουμε για οποιονδήποτε λόγο να κάνουμε casting, αυτή είναι η μέθοδος
που πρέπει να ακολουθήσουμε.
4. Αποθήκευση παραμέτρων σε hashed array
Αντί για την fetchrow\_array και την fetch που είδαμε πιο πάνω, μπορούμε να χρησιμοποιήσουμε και την fetchrow\_hashref() μέθοδο, για να τοποθετήσουμε τα
αποτελέσματα που θα μας επιστρέψει η βάση σε ένα hash.\
Για κάθε γραμμή αποτελεσμάτων που επιστρέφεται από την βάση, δημιουργείται ένα reference σε ένα array που περιέχει το field name σαν κλειδί και την τιμή του
σαν value. Αν κάποιο value είναι Null, τότε επιστρέφεται με τιμή undef. Αυτό προσέξτε το γιατί σημαίνει ότι θα υπάρχει συνδυασμός κλειδί-τιμή στο hash που
θα δημιουργηθεί (ενώ ίσως περίμενε κάποιος να μην υπάρχει καν αυτός ο συνδυασμός εφόσον η τιμή του είναι Null).\
Αυτή η υλοποίηση δημιουργεί περισσότερο overhead στο πρόγραμμά μας απ\' ότι η fetchrow\_array και δεν είναι και πολύ μεταφέρσιμη μεταξύ των διαφορετικών
βάσεων, συνεπώς αν δεν το χρειάζεστε, μην το χρησιμοποιήσετε.
5. Πληροφορίες από την βάση
Μπορούμε να πάρουμε όλα τα αποτελέσματα του select μας με την μέθοδο dump\_results() η οποία καλεί εσωτερικά την neat\_list και τυπώνει τα αποτελέσματα.Aν
δεν δώσουμε παραμέτρους, θα τυπώσει μέχρι 35 χαρακτήρες (\$maxlen=35), μία γραμμή αποτελεσμάτων σε μία γραμμή του output (\$lsep=\'\\n\'), χωρισμένες οι
στήλες με κόμματα (\$fsep=\',\') στο STDOUT (\$fh). Όλα αυτά μπορούμε να τα αλλάξουμε με τις μεταβλητές που ανέφερα.
Η βάση μας δίνει επίσης πληροφορίες για:
- NUM\_OF\_FIELDS (integer)\
Ο αριθμός των πεδίων που θα επιστρέψει το select που έχουμε κάνει prepare.
- NUM\_OF\_PARAMS (integer)\
Ο αριθμός των παραμέτρων που περνάμε στην prepare (αυτά που λέγαμε για Placeholders).
- NAME (reference σε array)\
Ένα reference σε array που περιέχει τα ονόματα των πεδίων. Υπάρχουν αντίστοιχα και οι NAME\_lc και NAME\_uc που επιστρέφουν τα ίδια στοιχεία σε
LowerCase και UpperCase αντίστοιχα.
Όλες οι παραπάνω παράμετροι είναι βέβαια read\_only.
Με αυτό το κείμενο τελειώσαμε την εισαγωγή στο DBI interface της perl. Διαβάστε πάλι την βιβλιογραφία από το προηγούμενο τεύχος και είστε έτοιμοι να ξεκινήσετε.

45
content/articles/24/05_odigos.md Κανονικό αρχείο

@ -0,0 +1,45 @@
+++
title = 'Οδηγός καλής συμπεριφοράς προς Linuxάδες'
date = '2000-04-01T00:00:00Z'
description = ''
author = 'Ευριπίδης Παπακώστας(mailto:evris@hellug.gr)'
issue = ['Magaz 24']
issue_weight = 5
+++
----------------------------------------------------------------------------------------------------------------------------------------------------------------
*Το κείμενο αυτό\... έχει νόημα :-). Ολόκληρο το κείμενο με τις σχετικές επεξηγήσεις, θα το βρείτε στο
[DiLiMa](http://baza.eeea.gr/article.php3?sid=20000530224100) που θα κυκλοφορήσει σύντομα.*
----------------------------------------------------------------------------------------------------------------------------------------------------------------
Ένα Παραμύθι με Νόημα
*\"Μια φορά κι έναν καιρό, σε ένα απόμακρο χωριό, ζούσαν δέκα ψαράδες. Την εποχή εκείνη, κανείς άλλος δεν ήξερε να ψαρεύει και ούτε ενδιαφερόταν για το ψάρεμα.
Αν μάλιστα οι ψαράδες έκαναν το αστείο να διδάξουν ψάρεμα στους ανθρώπους της πόλης, ή να τους δώσουν δωρεάν ψάρια εκείνοι τους κορόιδευαν και τους χλεύαζαν.*
*Οι κάτοικοι της πόλης, βλέπετε, τρώγανε μόνο έτοιμες προτηγανισμένες τηγανητές πατάτες που τους προμήθευε ο αφέντης μεγαλέμπορας.*
*Οι ψαράδες όμως επέμειναν. Σιγά σιγά, καλλιέργησαν και τη γη, κάναν μια μικρή φάρμα εκτροφής ζώων, άρμεγαν τα ζώα και επειδή ήταν όλοι φίλοι μεταξύ τους και
ήταν λίγοι σε πληθυσμό, ο καθένας έκανε ότι του άρεσε και το πρόσφερε δωρεάν και χαμογελαστά στους υπόλοιπους. Όποιος δεν μπορούσε να φέρει σε πέρας κάποια
δουλειά, μπορούσε να ρωτήσει τους παλιότερους κατοίκους του χωριού και εκείνοι με χαρά τον βοηθούσαν.*
*Σιγά σιγά, οι ταλαιπωρημένοι και στα πρόθυρα της ασιτίας κάτοικοι της πόλης ενδιαφέρθηκαν να μάθουν και αυτοί τον τρόπο ζωής του μικρού αυτού χωριού και
άρχισαν να μαζεύονται στα περίχωρα του χωριού.*
*Ο πληθυσμός του χωριού αυξήθηκε. Οι νέοι κάτοικοι απαιτούσαν σαν κακομαθημένα παιδιά τα δωρεάν ψάρια τους (λες και κάποιος τους τα χρώσταγε) και
κακοαναθρεμένοι όπως ήταν, άρχισαν να ζητάνε τσιπούρες, φιλέτο, λαχανάκια Βρυξελλών, πράγματα που οι παλιοί χωρικοί δε μπορούσαν (χωρίς τη συνεργασία των νέων)
να φτιάξουν.*
*Αλλά αυτό που πραγματικά έφερνε σε απόγνωση τους γέροντες του χωριού, ήταν η συμπεριφορά των νέων στο σχολείο. Δεν έκαναν τις εργασίες τους, δε διάβαζαν τα
βιβλία τους, δεν παίδευαν το μυαλό τους και δεν παρατηρούσαν τους γεροντότερους ώστε να προοδεύσουν. Αντί αυτού, συνεχώς έβριζαν τη δασκάλα τους όταν τους
εξηγούσε πως αν είχαν διαβάσει το βιβλίο δε θα χρειαζόταν να διακόπτουν συνέχεια το μάθημα και να ρωτούν τα ίδια και τα ίδια.*
*Η κατάσταση αυτή συνεχίστηκε για πολύ καιρό, μέχρι που πέθαναν οι γεροντότεροι, χάθηκε η γνώση που είχαν και τελείωσαν από τις αποθήκες οι έτοιμες τροφές που
με τόσο κόπο συσσώρευαν.*
*Πεινασμένοι και απογοητευμένοι οι κάτοικοι της πόλης, ξαναγύρισαν στον παλιό αφέντη τους. Με σκυμμένο το κεφάλι, παραδέχτηκαν πως ήταν λάθος τους να φύγουν από
κοντά του και του ζήτησαν να τους πάρει στη δούλεψή του.*
*Αυτός άλλο που δεν ήθελε. Τώρα πια όλοι δουλεύουν γι\' αυτόν, για μια μερίδα προτηγανισμένες σάπιες πατάτες και κανένας δεν έχει μείνει για να επαναστατήσει
εναντίον του.\"*