Προς το περιεχόμενο

Εκτύπωση κειμένου από C, σε έγγραφο της επιλογής μας


Επισκέπτης

Προτεινόμενες αναρτήσεις

Δημοσ. (επεξεργασμένο)
1 ώρα πριν, k33theod είπε

Τι διαφορά έχει το κείμενο που είναι έτοιμο στον πηγαίο από κάποιο που που δημιουργείται όταν τρέχει το πρόγραμμα:


char onoma[]="Thodoris";
char eponimo[50];
scanf("%s", eponimo);  

H απάντηση είναι νομίζω καμία. Και τα δύο είναι μεταβλητές που είναι φορτωμένες κάπου στη μνήμη. 

Αν αντί για char onoma[]="Thodoris" είχες γράψει char *onoma="Thodoris" τότε το string literal "Thodoris" θα υπήρχε αυτούσιο σε κάποιο section του binary και όταν φόρτωνες το πρόγραμμα θα γινόταν map στη μνήμη σαν read-only. Η διαφορά οπότε είναι ότι θα ήταν non-modifiable.

PS. Έτσι όπως το έγραψες το "Thodoris" δεν είναι string literal αλλά array initializer και άρα δεν ισχύει αυτό που γράφω παραπάνω.

 

Επεξ/σία από Ilias95
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

  • Απαντ. 43
  • Δημ.
  • Τελ. απάντηση

Συχνή συμμετοχή στο θέμα

Δημοσ. (επεξεργασμένο)

Η γλώσσα C είναι περίπτωση γλώσσας χωρίς αλφαριθμητικά. Αυτό που λέει ότι είναι αλφαριθμητικό είναι πίνακας. Το κενό αλφαριθμητικό είναι ο χαρακτήρας 0, δηλαδή πιάνει χώρο ένα byte. Αντί να έχει ένα πεδίο να κρατάει το μέγεθος του αλφαριθμητικού, έχει έναν "σκοπό", το 0. Αυτό σημαίνει ότι αλφαριθμητικά με περιεχόμενους χαρακτήρες μηδέν δεν μπορεί να πάρει. Δεν μπορούμε να πούμε το αλφαριθμητικό ως μια σειρά δυαδικών ψηφίων, διότι το 0 που είναι δυαδικό ψηφίο δεν μπορεί να περιλαμβάνεται.

Όταν ορίσουμε μια μεταβλητή A ότι θα έχει το αλφαριθμητικό "Hello" στην ουσία η C μας φτιάχνει μια ΣΤΑΘΕΡΑ με 6 ψηφία (το έκτο το 0) και δίνει στο Α την διεύθυνση του πρώτου γράμματος. Αμέσως μετά την θέση του 0 ακολουθούν άλλα στοιχεία, και μάλιστα χωρίς την δυνατότητα να αλλάξουν. Έτσι το Α δεν είναι μεταβλητή! Μας κάνει όμως δουλειά γιατί μπορούμε να χρησιμοποιήσουμε μια εξωτερική συνάρτηση που απλά θα διαβάσει τους χαρακτήρες και θα τους εμφανίσει στην οθόνη.

Το ερώτημα που μπαίνει είναι αν μπορούμε να γράψουμε απευθείας ένα κείμενο στη C. Η απάντηση είναι  ναι και όχι (γιατί η ερώτηση δεν είναι ολόκληρη). Ναι γιατί μπορούμε να βάλουμε το \ και να αλλάζουμε γραμμές, και όχι γιατί πρέπει να γράφουμε την αλλαγή γραμμής ως \n, εκτός και αν γράφουμε για WIndows οπότε εκε;i θέλει και το \r\n. Άρα άλλο πράγμα είναι να έχουμε πολλές γραμμές στο κώδικα και άλλο να έχουμε στην εμφάνιση πολλές γραμμές (το πρώτο παίζει με το \ στο τέλος της γραμμής και το άλλο με το \n ή \r\n).

Αν έβαζα αυτή την άσκηση θα περίμενα οι μαθητές να μου αναφέρουν ότι δεν τους έδωσα για πoιο περιβάλλον εμφάνισης μιλάμε. Διότι η C βγάζει πρόγραμμα για κάποια πραγματική μηχανή και όχι για εικονική μηχανή (όπως η java).

Έστω ότι το μάθαμε λοιπόν και στόχος είναι τα Windows. Μετά πρέπει το εσωτερικό κείμενο να το γράψω με τρόπο ώστε να μπουν τα κατάλληλα escape codes. Δεν μπορούμε έστι απλά να ρίξουμε ανάμεσα σε δυο διπλά εισαγωγικά (τα λεγόμενα και αυτάκια) κώδικα. Γιατί μπορεί ο κώδικας να έχει και αυτός εισαγωγικά. Πρέπει δηλαδή το σταθερό κείμενο, ο κώδικας, που ζητάει η άσκηση να τροποποιηθεί κατάλληλα.

Στο άλλο σκέλος της ερώτησης το κείμενο προφανώς θα μας το δίνει μια συνάρτηση, και επειδή οι συναρτήσεις της C δεν γυρνούν πίνακες, δεν γυρνούν και αλφαριθμητικά, θα παίξουμε υποχρεωτικά με δείκτες, που σημαίνει ότι θα περάσουμε σε συναρτήσεις (που καλούνται ως μέθοδοι, με Void) αλφαριθμητικά με αναφορά, αλλά προσοχή, όχι αλφαριθμητικά που ορίσαμε ως σταθερές. Πρέπει δηλαδή να φτιάξουμε πίνακα με το μέγεθος που θέλουμε και να δώσουμε το δείκτη του πίνακα για να μας τον γεμίσει η συνάρτηση. Υπάρχουν γενικά πολλές συναρτήσεις που δέχονται δυο τιμές για ένα αλφαριθμητικό, το δείκτη του πρώτου στοιχείου και το μέγεθος του χώρου που μπορεί να καλυφθεί με αλφαριθμητικό. Έτσι στην ουσία ο μεταβλητός χώρος του αλφαριθμητικού κανονίζεται από τον κώδικα με "περίσσευμα" από την αρχή. Υπάρχουν και άλλοι τρόποι χειρισμού αλφαριθμητικών όπως αυτός του συστήματος των Windows όπου τα αλφαριθμητικά είναι μιας μόνο εγγραφής! Δηλαδή όταν θέλουμε να προσθέσουμε έναν χαρακτήρα τότε η μεταβλητή θα δείχνει κάπου αλλού όπου θα υπάρχει το αντίγραφο του πρώτου και του δεύτερου αλφαριθμητικού, στην σειρά (χωρίς το 0 στο τέλος του πρώτου).

Μπορεί η συνάρτηση να παίρνει null και δίνει δείκτη, δηλαδή να ορίζει το αλφαριθμητικό με μια malloc εντός. Τότε πρέπει το free να γίνει μετά. Εκεί δεν μας ενδιαφέρει το μέγεθος του αλφαριθμητικού, γιατί όπως θα πάρουμε τον δείκτη θα τον δώσουμε στην συνάρτηση εμφάνισης, και μετά στην free και τελείωσε το πανηγύρι!

Και επειδή στη C όλα γίνονται  (και οι κανόνες πάνε περίπατο...)

https://stackoverflow.com/questions/1011455/is-it-possible-to-modify-a-string-of-char-in-c

Δείτε στο παράδειγμα που γράφει "Bender is always sober.", τι έκανε ο αντίχριστος! Παίρνει με κατάλληλη διαίρεση (το υπόλοιπο), τον χειριστή μνήμης που βρίσκεται αποθηκευμένο το αλφαριθμητικό (από το δείκτη του αλφαριθμητικού) που δεν γράφεται ως μνήμη και αλλάζει τον σκοπό χρήσης της μνήμης, για να μπορεί να γράφεται!

 

 

Επεξ/σία από solarpower
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Λίγο πρόχειρα επειδή είμαι από κινητό 

1) δεν μπορείς να αναθεσεις string όπως το έχεις γράψει. Πρέπει να χρησιμοποιήσεις την συνάρτηση strcpy. 

2) ελέγχεις αν απέτυχε το malloc και κάνεις exit. Οτιδήποτε μετά από αυτό δεν εκτελείται. Εδώ η γραμμή που κάνεις free. 

 

Επίσης μάλλον κάτι χάνω γιατί λες ότι λαμβάνεις τα ονόματα αρχείων από τον χρήστη αλλά τα έχεις γράψει χειροκίνητα μέσα στον κώδικα. 

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

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

Φτιάξε πρώτα ένα πρόγραμμα που θα αυξομειώνει μια μεταβλητή μεταξύ δυο ορίων, με τη χρήση των PageUp, PageDown.πλήκτρων.

 

 

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημοσ. (επεξεργασμένο)

Η αλλαγή σελίδας μπορεί να έχει, επόμενη-προηγούμενη, αρχική, τέλος.  Επιπλέον μπορεί ένα άλλο πλήκτρο το TAB να δουλεύει ως επόμενη σύνδεση, και να ορίσεις τις συνδέσεις ως #1 ώστε στο πάτημα του TAB να πας στο επόμενο # και με enter να αλλάξεις σελίδα. Mε SHIFT TAB θα μπορούσες να πήγαινες προς την αρχή του κειμένου, δηλαδή αναζήτηση προς την αρχή από το τρέχον σημείο του #.

Για να αποφεύγεις χαοτικές σκέψεις, ή όπως λέμε να πηδάς από το ένα θέμα στο άλλο χωρίς συνοχή, κράτησε τα χαρακτηριστικά του προγράμματός σου από την αρχή καθορισμένα.  Δηλαδή το χαρακτηριστικό του προγράμματός σου είναι το κείμενο, το όποιο έχει σελίδες. Μόνο αυτό. Θα επικεντρωθείς στο τι ευκολία θα ήθελες να είχες.  Αν πετάγεσαι στην σκέψη "σερφάρω" που σημαίνει εδώ ότι με κάποιο τρόπο επιλέγω υπερσύνδεση, ίσως να μην έχεις ένα κείμενο αλλά πολλά και το καθένα έχει τις σελίδες του. Δεν είναι ταυτόσημο αυτό με ένα κείμενο με όλες τις σελίδες άλλων κειμένων, γιατί το κάθε κείμενο αποτελεί ενότητα, και θα μπορούσαν να υπήρχαν μέθοδοι, όπως να τυπώσεις μόνο το κείμενο αυτό.

Άρα ξεκαθάρισε τα χαρακτηριστικά και μετά το συζητάμε.

 

Επεξ/σία από solarpower
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

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

Θα μπορούσαμε να χωρίσουμε ένα οποιοδήποτε πρόγραμμα σε τρεις τύπους συστατικών: Εντολές, Σταθερές, Δομές δεδομένων. Στις εντολές έχουμε οτιδήποτε κάνει κάτι αυτοτελώς. και εκεί μπαίνουν και διακλαδώσεις, ότι δομή θέλεις, όλα αυτά λέγονται statements.  Ο επόμενος τύπους συστατικών είναι οι σταθερές, δηλαδή οτιδήποτε έχει τιμή, αριθμητική ή αλφαριθμητική ακόμα και εικόνες, με τα μεν δυο πρώτα επειδή είναι στον κώδικα λέγονται Literals, ενώ εικόνες ή άλλα δεδομένα λέγονται resources. Το τρίτο χαρακτηριστικό είναι το σημείο που θέλω να δεις περισσότερο: Η δομή δεδομένων είναι μεν συλλογή από "δεδομένα" αλλά , υπάρχουν και βοηθητικά στοιχεία που δένουν τα δεδομένα σε αυτή τη δομή, και μπορεί να είναι απλά "συμβάσεις", να μην έχουν χώρο στη δομή, ή να έχουν όγκο σε δεδομένα., πχ δείκτες ή φύλακες, τα σημεία που σηματοδοτούν το τέλος. Θα σκεφτείς ότι συζητώ για αλγόριθμο, αλλά όχι δεν είναι αλγόριθμος η δομή δεδομένων, δεν είναι κώδικας, αλλά αποτύπωση σε ψηφιακό μέσο, πχ στην μνήμη ή σε αρχείο. Υπάρχει περίπτωση σε αρχεία να υπάρχει κώδικας, αλλά αυτό είναι περίπτωση και όχι κανόνας, και ο κώδικας χρησιμοποιείται για κάποια μετατροπή ή εμφάνιση στοιχείων της δομής, και όχι για την χρήση της δομής.

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

Λοιπόν ας σοβαρευτείς και ξεκίνα την ιδέα του αρχείου, το οποίο κάποια στιγμή μπορεί να μπει ως resource  μέσα στο πρόγραμμα, και έτσι να διαθέτεις κάτι "κλειστό" αλλά με δομή δεδομένων.

 

Όσο για κώδικα στη C και όποια γλώσσα θες, υπάρχει το rosettacode.org που διαθέτει πολλά προγράμματα παραδείγματα (σε 700 γλώσσες όπως είδα τελευταία)

 

 

 

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...