Καλησπέρα σας! Κάνω μαθήματα προγρατισμού με την γλώσσα C. Αυτό που θέλω να ρωτήσω είναι: ποια είναι η διαφορά της εντολής scanf και scanf_s που ισχύει από το πρότυπο C11 κι έπειτα; Αυτό που διάβάζω από 'δω και από 'κει, είναι ότι η scanf_s είναι πιο ασφλής εντολή, διότι δεν επιτρέπει το buffer overload. Μπορεί κάποιος να μου πει τίποτα επί τούτου;
Εμφάνιση 1-11 από 11
-
22-11-17, 21:10 C προγραμματισμός: διαφορές scanf με scanf_s #1
-
22-11-17, 23:54 Απάντηση: C προγραμματισμός: διαφορές scanf με scanf_s #2"I like offending people, because I think people who get offended should be offended" - Linus Torvalds
"Παλιά είχαμε φτωχούς οι οποίοι ζούσανε σε φτωχογειτονιές. Τώρα, η οικονομικά δυσπραγούσα τάξη
κατέχει στέγες υποδεέστερης ποιότητας σε υποβαθμισμένα αστικά κέντρα" - George Carlin
Γα.... την πολιτική ορθότητα.
-
25-11-17, 13:58 Απάντηση: C προγραμματισμός: διαφορές scanf με scanf_s #3
Δεν κατανοούν όλοι την ορολογία, πόσο μάλλον αρχάριοι στην C.
Βασική διαφορά: ΔΕΝ είναι portable. Υπάρχει μόνο στον compiler της microsoft (απ' όσο γνωρίζω μέχρι στιγμής δηλαδή). Αυτό σημαίνει ότι αν πάρεις τον κώδικά σου να τον κάνεις compile σε μια *NIX πλατφόρμα, px με τον GCC, ο compiler απλά θα σου απαντήσει ότι δε τη γνωρίζει.
Η δεύτερη διαφορά είναι αυτό που αναφέρεις. H scanf δεν έχει κάποιο όριο, με αποτέλεσμα να δημιουργεί overflow εαν αφήσουμε ανεξέλεγκτο το
input. Γι' αυτό ΠΑΝΤΑ μα ΠΑΝΤΑ, no matter what anybody says, εάν χρησιμοποιείς scanf βάζεις εσύ limit στο όριο των χαρακτήρων που την αφήνεις να διαβάσει. Όριο μπορείς να βάλεις με αριθμό στον placeholder.Αν νομίζεις ότι μπορείς να το κάνεις καλύτερα, απόδειξέ το. Μή μένεις μόνο στα λόγια.
-
26-11-17, 14:56 Απάντηση: C προγραμματισμός: διαφορές scanf με scanf_s #4Βασική διαφορά: ΔΕΝ είναι portable. Υπάρχει μόνο στον compiler της microsoft (απ' όσο γνωρίζω μέχρι στιγμής δηλαδή). Αυτό σημαίνει ότι αν πάρεις τον κώδικά σου να τον κάνεις compile σε μια *NIX πλατφόρμα, px με τον GCC, ο compiler απλά θα σου απαντήσει ότι δε τη γνωρίζει.
Η δεύτερη διαφορά είναι αυτό που αναφέρεις. H scanf δεν έχει κάποιο όριο, με αποτέλεσμα να δημιουργεί overflow εαν αφήσουμε ανεξέλεγκτο το
input. Γι' αυτό ΠΑΝΤΑ μα ΠΑΝΤΑ, no matter what anybody says, εάν χρησιμοποιείς scanf βάζεις εσύ limit στο όριο των χαρακτήρων που την αφήνεις να διαβάσει. Όριο μπορείς να βάλεις με αριθμό στον placeholder.
Βρήκα το παρακάτω εδώ, αλλά απ΄όσο ξέρω δεν λειτουργεί έτσι η scanf με τους πίνακες.
char name[10]; //declares an array that can hold 10 characters
scanf("%s", name); //gets a string from the user and puts it in name
-
26-11-17, 16:13 Απάντηση: C προγραμματισμός: διαφορές scanf με scanf_s #5
Όπως είπε και ο You lied, τις "ασφαλείς" αυτές συναρτήσεις με το _s στο τέλος τις βρίσκεις μόνο στο visual studio. Έχουνε μπει στην έκδοση C11 όπως έγραψες αλλά είναι προαιρετικές και έτσι οι devs του gcc και της glibc δεν τις υλοποίησαν γιατί πιστεύουν ότι δημιουργούν προβλήματα χωρίς να διορθώνουν την κατάσταση.
Κώδικας:#include <stdio.h> int main(void) { char s[11]; int i = 5; printf("i before scanf = %d\n", i); printf("Dose s\n"); scanf("%10s", s); printf("s = %s - i after scanf = %d\n\n\n", s, i); printf("i before scanf = %d\n", i); printf("Dose s\n"); scanf("%s", s); printf("s = %s - i after scanf = %d\n", s, i); return 0; }
Κώδικας:% ./a.out i before scanf = 5 Dose s Triapoulakiakathontaikaiplekoyunepoulover s = Triapoulak - i after scanf = 5 i before scanf = 5 Dose s s = iakathontaikaiplekoyunepoulover - i after scanf = 1885954411 zsh: segmentation fault ./a.out
Την επόμενη φορά η scanf καλείται με σκέτο το format "%s" χωρίς όριο (επειδή υπάρχουν χαρακτήρες που περίσσεψαν, δεν μου ζητάει να γράψω κάτι αλλά παίρνει από αυτούς). Εδώ βλέπουμε ότι δημιουργήθηκε buffer overflow. Πήγε και έγραψε όλο το κατεβατό που έδωσα εγώ στην περιοχή μνήμης του s αλλά επειδή δεν υπάρχει έλεγχος ορίων έγραψε και πέρα από την μνήμη του s για αυτό βλέπεις να έχει αλλάξει η τιμή του i. Ο αριθμός 1885954411 αντιστοιχεί σε δεκαεξαδικό με τον 0x7069616B το οποίο αντιστοιχεί στους ascii χαρακτήρες "kaip".
Δηλαδή οι χαρακτήρες "iakathontai" γράφτηκαν σωστά στις 11 θέσεις μνήμης του s, οι χαρακτήρες "kaip" έσβησαν την μνήμη της μεταβλητής i, οι υπόλοιποι χαρακτήρες "lekoynepoylover" έσβησαν ό,τι υπήρχε μετά.
Με την scanf_s έχω την εντύπωση ότι η σύνταξη θα ήταν scanf_s("%S", s, 10); δηλαδή βάζεις κεφαλαίο S στο format και μετά από την μεταβλητή σου βάζεις το μέγεθός της. Κάτι παρόμοιο μπορείς να κάνεις με την απλή scanf όπως είδαμε στην 1η εκτέλεσή της.
Ακόμη και έτσι όμως που θα αποφύγεις το buffer overflow, πάλι δεν γίνεται δουλειά. Το format "s" λαμβάνει μόνο μέχρι χαρακτήρες κενού (space, tab, κτλ) δηλαδή αν έγραφα "Tria poulakia" θα έπιανε μόνο το "Tria". Για να το αποφύγεις αυτό πρέπει να αλλάξεις format σε κάποιο πιο πολύπλοκο πχ "%10[^\n]" ώστε να σου πάρει 10 χαρακτήρες μέχρι τον χαρακτήρα αλλαγής γραμμής. Και έτσι ακόμη θα έχεις το πρόβλημα που είδες πριν ότι αν κάποιος δώσει παραπάνω χαρακτήρες, αυτοί θα μείνουν στο buffer και θα σου πηδήξουν επόμενες εκτελέσεις της scanf. Γενικά με την scanf δεν μπορείς να κάνεις δουλειά. Πρέπει να χρησιμοποιηθεί κάτι άλλο."I like offending people, because I think people who get offended should be offended" - Linus Torvalds
"Παλιά είχαμε φτωχούς οι οποίοι ζούσανε σε φτωχογειτονιές. Τώρα, η οικονομικά δυσπραγούσα τάξη
κατέχει στέγες υποδεέστερης ποιότητας σε υποβαθμισμένα αστικά κέντρα" - George Carlin
Γα.... την πολιτική ορθότητα.
-
26-11-17, 19:43 Απάντηση: C προγραμματισμός: διαφορές scanf με scanf_s #6
Και μόνο που γίνεται γενικώς συζήτηση για την scanf φαίνεται το αρχαίο του πράγματος, καθώς και το πόσο απαρχαιωμένες είναι ακόμα πολλές σχολές που διδάσκουν αυτή την ανόητη μορφή της C.
-
27-11-17, 14:12 Απάντηση: C προγραμματισμός: διαφορές scanf με scanf_s #7
Η C είναι το στάνταρ για το 99% των εφαρμογών σε embedded systems και microcontrollers. Αυτό ΙΜΗΟ δεν πρόκειται να αλλάξει για τα επόμενα χρόνια. Για τα παραπάνω δεν έχει βγεί κάποιος αξιόλογος compiler, πλην του deprecated EC++ - που και αυτός είχε γίνει ένα τεράστιο pain in the ass για τους system programmers.
Επίσης, σου το έχω ξαναπεί και αλλού σε αυτό το φόρουμ, το να συγκρίνεις την C με τη C++, είναι σα να συγκρίνεις την Java με τη Javascript.Αν νομίζεις ότι μπορείς να το κάνεις καλύτερα, απόδειξέ το. Μή μένεις μόνο στα λόγια.
-
27-11-17, 15:43 Απάντηση: C προγραμματισμός: διαφορές scanf με scanf_s #8
Και επειδή μου έχεις ξαναπεί δηλαδή ότι πρόκειται για σύγκριση Java με JavaScript (που είναι τελείως διαφορετικές γλώσσες) θα πρέπει να το ακούσω; Και, κυρίως, να το ακούνε εδώ οι αρχάριοι;
Και τι έγινε επειδή η C είναι σε χρήση, δηλαδή αυτό σημαίνει ότι πρέπει να διδάσκεται με αυτόν τον ανόητο τρόπο? Και η assembly είναι σε χρήση και τα κινέζικα είναι σε χρήση.
-
28-11-17, 13:31 Απάντηση: C προγραμματισμός: διαφορές scanf με scanf_s #9
-
28-11-17, 14:02 Απάντηση: C προγραμματισμός: διαφορές scanf με scanf_s #10
Και οι δύο έχετε δίκιο. Εσύ λες ότι η C είναι ο βασιλιάς σε embedded και γενικά όπου χρειάζονται οι καλύτερες επιδόσεις (ή δεν υπάρχει compiler άλλης γλώσσας) και έχεις δίκιο σε αυτό. Ο turboirc σου λέει ότι αυτό δεν έχει σχέση με το αν πρέπει να διδάσκεται σε κάποιον που μαθαίνει προγραμματισμό και έχει και αυτός δίκιο.
Μια και μιλάμε για την scanf, για να λάβεις ένα ακέραιο στην C και να μπορείς να έχεις εποπτεία για λάθη, πρέπει να ορίσεις μια συνάρτηση η οποία να κάνει:
* να εκχωρήσεις μνήμη για ένα "string"
* να λάβεις την είσοδο του χρήστη ως "string" με την fgets
* να μετατρέψεις το αποτέλεσμα σε ακέραιο με την strtol ώστε να μπορείς να ελέγξεις αν ο χρήστης έδωσε όντως ακέραιο ή έγραψε χαζά
* να χρησιμοποιήσεις την errno ώστε σε περίπτωση που έδωσε ο χρήστης χαζά να μπορείς να επιστρέψεις error
* ποιος ξέρει τι άλλο
Γράψε αυτή την συνάρτηση και δώσε την σε ένα μαθητευόμενο και πες του "έτσι λαμβάνεις ένα integer". Με τόσες γραμμές κώδικα σε python θα έγραφε ένα irc client Εκτός αυτού, αντί να αναλώνει το χρόνο και το μυαλό του στο να μάθει πώς πρέπει να σκέφτεται για να λύσει ένα προγραμματιστικό πρόβλημα, τον αναλώνει στις ιδιοτροπίες της C. Ο turboirc έχει δίκιο ότι η C δεν είναι γλώσσα για διδασκαλία εκμάθησης προγραμματισμού.
Έχω συναδέλφους και φίλους που ήξεραν μόνο java, python, κτλ και πολλά προβλήματα τα έλυναν ας πούμε λιγότερο δόκιμα από ό,τι θα μπορούσαν και όταν έμαθαν C (ή όχι απαραίτητα C αλλά όταν έκατσαν και έμαθαν πώς δουλεύει το πράγμα σε χαμηλότερο επίπεδο, διευθύνσεις μνήμης, στοίβα, κτλ) μπήκαν σε ένα καλύτερο τρόπο σκέψης. Είναι δηλαδή καλό να μαθαίνει κάποιος C / assembly / whatever αλλά σε ένα advanced επίπεδο όχι σαν πρώτη γλώσσα. Όπως σε κάποια πανεπιστήμια αφού φτάσεις σε advanced επίπεδο έχεις τιμής ένεκεν σαν μάθημα αρχαία ελληνικά και λατινικά, έτσι κάπως να ήταν και η C.
ΥΓ: Ειδικά όταν βλέπω σε ένα αρχάριο να προτείνεται σαν βιβλίο εκμάθησης το K&R που δεν είναι διδακτικό βιβλίο, τραβάω τα μαλλιά μου."I like offending people, because I think people who get offended should be offended" - Linus Torvalds
"Παλιά είχαμε φτωχούς οι οποίοι ζούσανε σε φτωχογειτονιές. Τώρα, η οικονομικά δυσπραγούσα τάξη
κατέχει στέγες υποδεέστερης ποιότητας σε υποβαθμισμένα αστικά κέντρα" - George Carlin
Γα.... την πολιτική ορθότητα.
-
28-11-17, 14:59 Απάντηση: C προγραμματισμός: διαφορές scanf με scanf_s #11
Ο turboirc δεν είπε ότι «η C δεν είναι η κατάλληλη γλώσσα για όλες τις περιπτώσεις», είπε «καθώς και το πόσο απαρχαιωμένες είναι ακόμα πολλές σχολές που διδάσκουν αυτή την ανόητη μορφή της C» το οποίο είναι ανοησία και σ' αυτό έχει δίκιο ο "you lied", δεν υπάρχει έξυπνη και ανόητη μορφή της C. Μία είναι η C (ως γλώσσα προγραμματισμού) και η C++ δεν είναι απλά μια βελτιωμένη C που έχει και αντικείμενα, είναι μια άλλη γλώσσα προγραμματισμού με παρόμοιο συντακτικό και κάποια άλλα κοινά σημεία.
Και πιστεύω πως ναι, υπάρχουν περιπτώσεις που ενδείκνυται να ξεκινήσει κανείς με το K&R και ας μην είναι το πιο προσιτό (από διδακτικής πλευράς) βιβλίο (εννοείται όχι από περιέργεια για τον προγραμματισμό γενικά ή για να καταλήξει να γράφει web εφαρμογές).
Παρόμοια Θέματα
-
Asus Z170- Pro vs. Asus Z-170 Pro Gaming έχουν διαφορές ουσιαστικές?
Από Sebu στο φόρουμ Motherboards, CPU και memoryΜηνύματα: 50Τελευταίο Μήνυμα: 15-02-17, 11:06
Bookmarks