Εμφάνιση 1-11 από 11
  1. #1
    Εγγραφή
    07-07-2013
    Περιοχή
    Παντού και πουθενά
    Μηνύματα
    477
    Downloads
    3
    Uploads
    0
    ISP
    ΟΤΕ Conn-x
    Router
    TD-W8960N
    Καλησπέρα σας! Κάνω μαθήματα προγρατισμού με την γλώσσα C. Αυτό που θέλω να ρωτήσω είναι: ποια είναι η διαφορά της εντολής scanf και scanf_s που ισχύει από το πρότυπο C11 κι έπειτα; Αυτό που διάβάζω από 'δω και από 'κει, είναι ότι η scanf_s είναι πιο ασφλής εντολή, διότι δεν επιτρέπει το buffer overload. Μπορεί κάποιος να μου πει τίποτα επί τούτου;

  2. #2
    Εγγραφή
    20-12-2005
    Μηνύματα
    3.214
    Downloads
    4
    Uploads
    0
    Τύπος
    VDSL2
    Ταχύτητα
    49997/4997
    ISP
    ΟΤΕ Conn-x
    DSLAM
    ΟΤΕ - ΞΑΝΘΗ
    Router
    Speedport W 724V
    SNR / Attn
    24,4(dB) / (dB)
    Παράθεση Αρχικό μήνυμα από HugeG Εμφάνιση μηνυμάτων
    Καλησπέρα σας! Κάνω μαθήματα προγρατισμού με την γλώσσα C. Αυτό που θέλω να ρωτήσω είναι: ποια είναι η διαφορά της εντολής scanf και scanf_s που ισχύει από το πρότυπο C11 κι έπειτα; Αυτό που διάβάζω από 'δω και από 'κει, είναι ότι η scanf_s είναι πιο ασφλής εντολή, διότι δεν επιτρέπει το buffer overload. Μπορεί κάποιος να μου πει τίποτα επί τούτου;
    Έγραψες "scanf vs scanf_s" στο google και δεν πήρες χιλιάδες αποτελέσματα που να εξηγούν τα πάντα ?
    "I like offending people, because I think people who get offended should be offended" - Linus Torvalds

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

  3. #3
    Εγγραφή
    03-11-2016
    Ηλικία
    34
    Μηνύματα
    160
    Downloads
    0
    Uploads
    0
    Τύπος
    ADSL2+
    Ταχύτητα
    UP:1061 k/ DN:11889 k
    ISP
    Cyta Hellas
    DSLAM
    Cyta Hellas - Σ.Σ. ΑΓΡΑ
    Router
    TG788v2
    SNR / Attn
    21.4(dB) / 4.3(dB)
    Path Level
    Interleaved
    Παράθεση Αρχικό μήνυμα από imitheos Εμφάνιση μηνυμάτων
    Έγραψες "scanf vs scanf_s" στο google και δεν πήρες χιλιάδες αποτελέσματα που να εξηγούν τα πάντα ?
    Δεν κατανοούν όλοι την ορολογία, πόσο μάλλον αρχάριοι στην C.

    Παράθεση Αρχικό μήνυμα από HugeG Εμφάνιση μηνυμάτων
    Καλησπέρα σας! Κάνω μαθήματα προγρατισμού με την γλώσσα C. Αυτό που θέλω να ρωτήσω είναι: ποια είναι η διαφορά της εντολής scanf και scanf_s που ισχύει από το πρότυπο C11 κι έπειτα; Αυτό που διάβάζω από 'δω και από 'κει, είναι ότι η scanf_s είναι πιο ασφλής εντολή, διότι δεν επιτρέπει το buffer overload. Μπορεί κάποιος να μου πει τίποτα επί τούτου;
    Βασική διαφορά: ΔΕΝ είναι portable. Υπάρχει μόνο στον compiler της microsoft (απ' όσο γνωρίζω μέχρι στιγμής δηλαδή). Αυτό σημαίνει ότι αν πάρεις τον κώδικά σου να τον κάνεις compile σε μια *NIX πλατφόρμα, px με τον GCC, ο compiler απλά θα σου απαντήσει ότι δε τη γνωρίζει.

    Η δεύτερη διαφορά είναι αυτό που αναφέρεις. H scanf δεν έχει κάποιο όριο, με αποτέλεσμα να δημιουργεί overflow εαν αφήσουμε ανεξέλεγκτο το
    input. Γι' αυτό ΠΑΝΤΑ μα ΠΑΝΤΑ, no matter what anybody says, εάν χρησιμοποιείς scanf βάζεις εσύ limit στο όριο των χαρακτήρων που την αφήνεις να διαβάσει. Όριο μπορείς να βάλεις με αριθμό στον placeholder.
    Αν νομίζεις ότι μπορείς να το κάνεις καλύτερα, απόδειξέ το. Μή μένεις μόνο στα λόγια.

  4. #4
    Εγγραφή
    07-07-2013
    Περιοχή
    Παντού και πουθενά
    Μηνύματα
    477
    Downloads
    3
    Uploads
    0
    ISP
    ΟΤΕ Conn-x
    Router
    TD-W8960N
    Βασική διαφορά: ΔΕΝ είναι portable. Υπάρχει μόνο στον compiler της microsoft (απ' όσο γνωρίζω μέχρι στιγμής δηλαδή). Αυτό σημαίνει ότι αν πάρεις τον κώδικά σου να τον κάνεις compile σε μια *NIX πλατφόρμα, px με τον GCC, ο compiler απλά θα σου απαντήσει ότι δε τη γνωρίζει.

    Η δεύτερη διαφορά είναι αυτό που αναφέρεις. H scanf δεν έχει κάποιο όριο, με αποτέλεσμα να δημιουργεί overflow εαν αφήσουμε ανεξέλεγκτο το
    input. Γι' αυτό ΠΑΝΤΑ μα ΠΑΝΤΑ, no matter what anybody says, εάν χρησιμοποιείς scanf βάζεις εσύ limit στο όριο των χαρακτήρων που την αφήνεις να διαβάσει. Όριο μπορείς να βάλεις με αριθμό στον placeholder.
    Σ' ευχαριστώ για την βοήθεια! Μήπως μπορείς να γράψεις ένα παράδειγμα με scanf χωρίς όριο στο οποίο παρουσιάζεται πρόβλημα και το ίδιο παράδειγμα ξανά, αλλά με scanf_s στο οποίο δεν υπάρχει πρόβλημα.

    Βρήκα το παρακάτω εδώ, αλλά απ΄όσο ξέρω δεν λειτουργεί έτσι η 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

  5. #5
    Εγγραφή
    20-12-2005
    Μηνύματα
    3.214
    Downloads
    4
    Uploads
    0
    Τύπος
    VDSL2
    Ταχύτητα
    49997/4997
    ISP
    ΟΤΕ Conn-x
    DSLAM
    ΟΤΕ - ΞΑΝΘΗ
    Router
    Speedport W 724V
    SNR / Attn
    24,4(dB) / (dB)
    Παράθεση Αρχικό μήνυμα από You lied Εμφάνιση μηνυμάτων
    Βασική διαφορά: ΔΕΝ είναι portable. Υπάρχει μόνο στον compiler της microsoft (απ' όσο γνωρίζω μέχρι στιγμής δηλαδή). Αυτό σημαίνει ότι αν πάρεις τον κώδικά σου να τον κάνεις compile σε μια *NIX πλατφόρμα, px με τον GCC, ο compiler απλά θα σου απαντήσει ότι δε τη γνωρίζει.
    Όπως είπε και ο You lied, τις "ασφαλείς" αυτές συναρτήσεις με το _s στο τέλος τις βρίσκεις μόνο στο visual studio. Έχουνε μπει στην έκδοση C11 όπως έγραψες αλλά είναι προαιρετικές και έτσι οι devs του gcc και της glibc δεν τις υλοποίησαν γιατί πιστεύουν ότι δημιουργούν προβλήματα χωρίς να διορθώνουν την κατάσταση.


    Παράθεση Αρχικό μήνυμα από HugeG Εμφάνιση μηνυμάτων
    Σ' ευχαριστώ για την βοήθεια! Μήπως μπορείς να γράψεις ένα παράδειγμα με scanf χωρίς όριο στο οποίο παρουσιάζεται πρόβλημα και το ίδιο παράδειγμα ξανά, αλλά με scanf_s στο οποίο δεν υπάρχει πρόβλημα.

    Βρήκα το παρακάτω εδώ, αλλά απ΄όσο ξέρω δεν λειτουργεί έτσι η 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
    Κώδικας:
    #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 "%10s" οπότε κάνεις αυτό που σου είπε ο You lied και ορίζεις ένα όριο. Έτσι λοιπόν δεν δημιουργείται κάποιο πρόβλημα και η μεταβλητή s παίρνει την τιμή Triapoulak άσχετα αν εγώ έδωσα πολλούς παραπάνω χαρακτήρες.

    Την επόμενη φορά η 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
    Γα.... την πολιτική ορθότητα.

  6. #6
    Το avatar του μέλους turboirc
    turboirc Guest
    Και μόνο που γίνεται γενικώς συζήτηση για την scanf φαίνεται το αρχαίο του πράγματος, καθώς και το πόσο απαρχαιωμένες είναι ακόμα πολλές σχολές που διδάσκουν αυτή την ανόητη μορφή της C.

  7. #7
    Εγγραφή
    03-11-2016
    Ηλικία
    34
    Μηνύματα
    160
    Downloads
    0
    Uploads
    0
    Τύπος
    ADSL2+
    Ταχύτητα
    UP:1061 k/ DN:11889 k
    ISP
    Cyta Hellas
    DSLAM
    Cyta Hellas - Σ.Σ. ΑΓΡΑ
    Router
    TG788v2
    SNR / Attn
    21.4(dB) / 4.3(dB)
    Path Level
    Interleaved
    Η C είναι το στάνταρ για το 99% των εφαρμογών σε embedded systems και microcontrollers. Αυτό ΙΜΗΟ δεν πρόκειται να αλλάξει για τα επόμενα χρόνια. Για τα παραπάνω δεν έχει βγεί κάποιος αξιόλογος compiler, πλην του deprecated EC++ - που και αυτός είχε γίνει ένα τεράστιο pain in the ass για τους system programmers.

    Επίσης, σου το έχω ξαναπεί και αλλού σε αυτό το φόρουμ, το να συγκρίνεις την C με τη C++, είναι σα να συγκρίνεις την Java με τη Javascript.
    Αν νομίζεις ότι μπορείς να το κάνεις καλύτερα, απόδειξέ το. Μή μένεις μόνο στα λόγια.

  8. #8
    Το avatar του μέλους turboirc
    turboirc Guest
    Και επειδή μου έχεις ξαναπεί δηλαδή ότι πρόκειται για σύγκριση Java με JavaScript (που είναι τελείως διαφορετικές γλώσσες) θα πρέπει να το ακούσω; Και, κυρίως, να το ακούνε εδώ οι αρχάριοι;

    Και τι έγινε επειδή η C είναι σε χρήση, δηλαδή αυτό σημαίνει ότι πρέπει να διδάσκεται με αυτόν τον ανόητο τρόπο? Και η assembly είναι σε χρήση και τα κινέζικα είναι σε χρήση.

  9. #9
    Εγγραφή
    03-11-2016
    Ηλικία
    34
    Μηνύματα
    160
    Downloads
    0
    Uploads
    0
    Τύπος
    ADSL2+
    Ταχύτητα
    UP:1061 k/ DN:11889 k
    ISP
    Cyta Hellas
    DSLAM
    Cyta Hellas - Σ.Σ. ΑΓΡΑ
    Router
    TG788v2
    SNR / Attn
    21.4(dB) / 4.3(dB)
    Path Level
    Interleaved
    Παράθεση Αρχικό μήνυμα από turboirc Εμφάνιση μηνυμάτων
    Και επειδή μου έχεις ξαναπεί δηλαδή ότι πρόκειται για σύγκριση Java με JavaScript (που είναι τελείως διαφορετικές γλώσσες) θα πρέπει να το ακούσω; Και, κυρίως, να το ακούνε εδώ οι αρχάριοι;

    Και τι έγινε επειδή η C είναι σε χρήση, δηλαδή αυτό σημαίνει ότι πρέπει να διδάσκεται με αυτόν τον ανόητο τρόπο? Και η assembly είναι σε χρήση και τα κινέζικα είναι σε χρήση.
    Οκ, εφ'όσων δεν ακούς και διαφορετικές απόψεις, τότε δεν έχει κάποιο νόημα να συνεχίσουμε. Καλή σου μέρα.
    Αν νομίζεις ότι μπορείς να το κάνεις καλύτερα, απόδειξέ το. Μή μένεις μόνο στα λόγια.

  10. #10
    Εγγραφή
    20-12-2005
    Μηνύματα
    3.214
    Downloads
    4
    Uploads
    0
    Τύπος
    VDSL2
    Ταχύτητα
    49997/4997
    ISP
    ΟΤΕ Conn-x
    DSLAM
    ΟΤΕ - ΞΑΝΘΗ
    Router
    Speedport W 724V
    SNR / Attn
    24,4(dB) / (dB)
    Παράθεση Αρχικό μήνυμα από You lied Εμφάνιση μηνυμάτων
    Οκ, εφ'όσων δεν ακούς και διαφορετικές απόψεις, τότε δεν έχει κάποιο νόημα να συνεχίσουμε. Καλή σου μέρα.
    Και οι δύο έχετε δίκιο. Εσύ λες ότι η 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
    Γα.... την πολιτική ορθότητα.

  11. #11
    Εγγραφή
    24-04-2006
    Περιοχή
    Χανιά
    Ηλικία
    56
    Μηνύματα
    1.624
    Downloads
    1
    Uploads
    0
    ISP
    None
    Ο turboirc δεν είπε ότι «η C δεν είναι η κατάλληλη γλώσσα για όλες τις περιπτώσεις», είπε «καθώς και το πόσο απαρχαιωμένες είναι ακόμα πολλές σχολές που διδάσκουν αυτή την ανόητη μορφή της C» το οποίο είναι ανοησία και σ' αυτό έχει δίκιο ο "you lied", δεν υπάρχει έξυπνη και ανόητη μορφή της C. Μία είναι η C (ως γλώσσα προγραμματισμού) και η C++ δεν είναι απλά μια βελτιωμένη C που έχει και αντικείμενα, είναι μια άλλη γλώσσα προγραμματισμού με παρόμοιο συντακτικό και κάποια άλλα κοινά σημεία.

    Και πιστεύω πως ναι, υπάρχουν περιπτώσεις που ενδείκνυται να ξεκινήσει κανείς με το K&R και ας μην είναι το πιο προσιτό (από διδακτικής πλευράς) βιβλίο (εννοείται όχι από περιέργεια για τον προγραμματισμό γενικά ή για να καταλήξει να γράφει web εφαρμογές).

Παρόμοια Θέματα

  1. Asus Z170- Pro vs. Asus Z-170 Pro Gaming έχουν διαφορές ουσιαστικές?
    Από Sebu στο φόρουμ Motherboards, CPU και memory
    Μηνύματα: 50
    Τελευταίο Μήνυμα: 15-02-17, 11:06

Bookmarks

Bookmarks

Δικαιώματα - Επιλογές

  • Δεν μπορείτε να δημοσιεύσετε νέα θέματα
  • Δεν μπορείτε να δημοσιεύσετε νέα μηνύματα
  • Δεν μπορείτε να αναρτήσετε συνημμένα
  • Δεν μπορείτε να επεξεργαστείτε τα μηνύματα σας
  •  
  • Τα BB code είναι σε λειτουργία
  • Τα Smilies είναι σε λειτουργία
  • Το [IMG] είναι σε λειτουργία
  • Το [VIDEO] είναι σε λειτουργία
  • Το HTML είναι εκτός λειτουργίας