maniac89 Δημοσ. 6 Σεπτεμβρίου 2008 Δημοσ. 6 Σεπτεμβρίου 2008 Λοιπόν γράφω λίγο το κομμάτι του κώδικα που έχω πρόβλημα #include <stdio.h> int main(int argc,char* argv[]) { char *ptr; ptr="C How To Program"; printf("%s\n",ptr); return 0; } //αυτό το πρόγραμμα θα τυπώσει C How To Program //πώς γίνεται όμως να εισάγω την φράση από το πληκτρολόγιο με scanf;;;; //δηλαδή αντί για ptr="C How To Program"; να έχω scanf("%s",....); προκαταβολικά ευχαριστώ
Evgenios1 Δημοσ. 6 Σεπτεμβρίου 2008 Δημοσ. 6 Σεπτεμβρίου 2008 Λοιπόν γράφω λίγο το κομμάτι του κώδικα που έχω πρόβλημα#include <stdio.h> int main(int argc,char* argv[]) { char *ptr; ptr="C How To Program"; printf("%s\n",ptr); return 0; } //αυτό το πρόγραμμα θα τυπώσει C How To Program //πώς γίνεται όμως να εισάγω την φράση από το πληκτρολόγιο με scanf;;;; //δηλαδή αντί για ptr="C How To Program"; να έχω scanf("%s",....); προκαταβολικά ευχαριστώ #include <sdtio.h> #include <string> // ή strings δεν το θυμαμαι main() { string str; scanf("%s",&str); printf("%s",str); getchar(); }
Επισκέπτης Δημοσ. 6 Σεπτεμβρίου 2008 Δημοσ. 6 Σεπτεμβρίου 2008 Η παραπάνω απάντηση είναι εντελώς λάθος (θα πρέπει να σου πήρε λιγότερο από μισό λεπτό για να την γράψεις τόσο λάθος): > #include <sdtio.h> #include <string> // ή strings δεν το θυμαμαι Όλα τα library header files έχουν κατάληξη .h Στην συγκεκριμένη περίπτωση το string.h header file δεν χρειάζεται καθώς το prototype της scanf υπάρχει στο stdio.h > main() { Ο παραπάνω κώδικας δεν είναι ANSI C. Το σωστό prototype για την main είναι: int main(void) ή int main(int argc, char *argv[]) ή int main(int argc, char **argv) κτλ > string str; Δεν υπάρχει τύπος δεδομένων string εκτός και αν τον έχεις δηλώσει με την typedef (πράγμα που σε αυτό το παράδειγμα δεν κάνεις). Πχ: typedef char *string; (Στο συγκεκριμένο παράδειγμα θα ήταν πάλι λάθος καθώς θέλουμε static allocated μνήμη για ένα char array που θα μπορεί να τροποποιηθεί από την scanf) Άλλο παράδειγμα: typedef char string[256]; > scanf("%s",&str); printf("%s",str); getchar(); } Στην scanf όπως και στην printf δεν χρειάζεται να περάσουμε έναν char ** (που είναι το &str) αλλά την διεύθυνση του πρώτου στοιχείου που είναι το str (char *). Παρακάτω παραθέτω τον κώδικα για να κάνεις αυτό που θέλεις: > #include <stdio.h> #define UNUSED(x) ((void) (x)) int main(int argc, char *argv[]) { UNUSED(argc); UNUSED(argv); char str[256]; if (scanf("%256s", str) == 1) printf("%s\n", str); return 0; } Μην σε μπερδεύει το UNUSED macro που χρησιμοποιώ, είναι για να αποφύγω warnings του compiler. Προσοχή: Με την scanf μπορούμε να διαβάσουμε μόνο μια λέξη, εάν θέλουμε να διαβάσουμε μια ολόκληρη πρόταση: > #include <stdio.h> #define UNUSED(x) ((void) (x)) #define BUFFSIZE 256 int main(int argc, char *argv[]) { UNUSED(argc); UNUSED(argv); char str[bUFFSIZE]; if (fgets(str, BUFFSIZE, stdin) != NULL) printf("%s\n", str); return 0; } PS. Ρε παιδιά αν δεν είστε σίγουροι για κάτι δεν χρειάζεται να απαντάτε.
Evgenios1 Δημοσ. 6 Σεπτεμβρίου 2008 Δημοσ. 6 Σεπτεμβρίου 2008 Η παραπάνω απάντηση είναι εντελώς λάθος (θα πρέπει να σου πήρε λιγότερο από μισό λεπτό για να την γράψεις τόσο λάθος): > #include <sdtio.h> #include <string> // ή strings δεν το θυμαμαι Όλα τα library header files έχουν κατάληξη .h Στην συγκεκριμένη περίπτωση το string.h header file δεν χρειάζεται καθώς το prototype της scanf υπάρχει στο stdio.h > main() { Ο παραπάνω κώδικας δεν είναι ANSI C. Το σωστό prototype για την main είναι: int main(void) ή int main(int argc, char *argv[]) ή int main(int argc, char **argv) κτλ > string str; Δεν υπάρχει τύπος δεδομένων string εκτός και αν τον έχεις δηλώσει με την typedef (πράγμα που σε αυτό το παράδειγμα δεν κάνεις). Πχ: typedef char *string; (Στο συγκεκριμένο παράδειγμα θα ήταν πάλι λάθος καθώς θέλουμε static allocated μνήμη για ένα char array που θα μπορεί να τροποποιηθεί από την scanf) Άλλο παράδειγμα: typedef char string[256]; > scanf("%s",&str); printf("%s",str); getchar(); } Στην scanf όπως και στην printf δεν χρειάζεται να περάσουμε έναν char ** (που είναι το &str) αλλά την διεύθυνση του πρώτου στοιχείου που είναι το str (char *). Παρακάτω παραθέτω τον κώδικα για να κάνεις αυτό που θέλεις: > #include <stdio.h> #define UNUSED(x) ((void) (x)) int main(int argc, char *argv[]) { UNUSED(argc); UNUSED(argv); char str[256]; if (scanf("%256s", str) == 1) printf("%s\n", str); return 0; } Μην σε μπερδεύει το UNUSED macro που χρησιμοποιώ, είναι για να αποφύγω warnings του compiler. Προσοχή: Με την scanf μπορούμε να διαβάσουμε μόνο μια λέξη, εάν θέλουμε να διαβάσουμε μια ολόκληρη πρόταση: > #include <stdio.h> #define UNUSED(x) ((void) (x)) #define BUFFSIZE 256 int main(int argc, char *argv[]) { UNUSED(argc); UNUSED(argv); char str[bUFFSIZE]; if (fgets(str, BUFFSIZE, stdin) != NULL) printf("%s\n", str); return 0; } PS. Ρε παιδιά αν δεν είστε σίγουροι για κάτι δεν χρειάζεται να απαντάτε. Πολυ μισος
nzeppos Δημοσ. 7 Σεπτεμβρίου 2008 Δημοσ. 7 Σεπτεμβρίου 2008 Μην πυροβολάτε τον Evgenio, ο άνθρωπος προσπάθησε κι ας έγραψε όλες τις γραμμές του κώδικα λάθος!
Επισκέπτης Δημοσ. 7 Σεπτεμβρίου 2008 Δημοσ. 7 Σεπτεμβρίου 2008 Δεν πυροβολώ κανέναν και φυσικά δεν υπάρχει ίχνος μίσους στην απάντηση που έδωσα. Αυτό που έκανα ήταν να διορθώσω μια λανθασμένη απάντηση και να δώσω μια σωστή. Δεν αμφισβητώ την πρόθεση του Evgeniou να βοηθήσει αλλά μερικές φορές όταν δεν γνωρίζουμε κάποια πράγματα δεν απαντάμε καθώς το μόνο που καταφέρνουμε είναι να μπερδέψουμε τους άλλους (και όχι μόνον αυτόν που ρωτάει). Σκεφτείτε να απαντούσαν όλοι σε τομείς που δεν γνωρίζουν προσπαθώντας να βοηθήσουν τι μπάχαλο θα γινόταν εδώ μέσα. Σίγουρα όλοι μας κάνουμε λάθη αλλά η συγκεκριμένη απάντηση υποδηλώνει άγνοια επί του θέματος. Ο λόγος λοιπόν που απάντησα με αυτόν τον τρόπο ήταν επειδή σε ένα πρόγραμμα 7 γραμμών οι 4 περιείχαν σοβαρά λάθη και κατά συνέπεια 4 τρόπους να μπερδέψουν έναν νέο προγραμματιστή. Φιλικά
chrismfz Δημοσ. 7 Σεπτεμβρίου 2008 Δημοσ. 7 Σεπτεμβρίου 2008 Δηλαδή εμάς που (προσπαθούν) μας μαθαίνουν C++ και αρχισα να διαβάζω και το αντίστοιχο βιβλίο του Stroustrup, χρησιμοποιώ για τέτοια θέματα στεγνα cin / cout και strings. σε C, με έναν C compiler (πχ gcc) string και include <string> using namespace std; και τα σχετικά που ξέρω για τη C++ (cout / cin etc) δεν δουλέυουν ? Ούτε αν περάσω τα headers απο την string (string.h) ? <confused>
Directx Δημοσ. 7 Σεπτεμβρίου 2008 Δημοσ. 7 Σεπτεμβρίου 2008 Η παραπάνω απάντηση είναι εντελώς λάθος (θα πρέπει να σου πήρε λιγότερο από μισό λεπτό για να την γράψεις τόσο λάθος): > #include <sdtio.h> #include <string> // ή strings δεν το θυμαμαι Όλα τα library header files έχουν κατάληξη .h Στην συγκεκριμένη περίπτωση το string.h header file δεν χρειάζεται καθώς το prototype της scanf υπάρχει στο stdio.h > main() { Ο παραπάνω κώδικας δεν είναι ANSI C. Το σωστό prototype για την main είναι: int main(void) ή int main(int argc, char *argv[]) ή int main(int argc, char **argv) κτλ > string str; Δεν υπάρχει τύπος δεδομένων string εκτός και αν τον έχεις δηλώσει με την typedef (πράγμα που σε αυτό το παράδειγμα δεν κάνεις). Πχ: typedef char *string; (Στο συγκεκριμένο παράδειγμα θα ήταν πάλι λάθος καθώς θέλουμε static allocated μνήμη για ένα char array που θα μπορεί να τροποποιηθεί από την scanf) Άλλο παράδειγμα: typedef char string[256]; > scanf("%s",&str); printf("%s",str); getchar(); } Στην scanf όπως και στην printf δεν χρειάζεται να περάσουμε έναν char ** (που είναι το &str) αλλά την διεύθυνση του πρώτου στοιχείου που είναι το str (char *). Παρακάτω παραθέτω τον κώδικα για να κάνεις αυτό που θέλεις: > #include <stdio.h> #define UNUSED(x) ((void) (x)) int main(int argc, char *argv[]) { UNUSED(argc); UNUSED(argv); char str[256]; if (scanf("%256s", str) == 1) printf("%s\n", str); return 0; } Μην σε μπερδεύει το UNUSED macro που χρησιμοποιώ, είναι για να αποφύγω warnings του compiler. Προσοχή: Με την scanf μπορούμε να διαβάσουμε μόνο μια λέξη, εάν θέλουμε να διαβάσουμε μια ολόκληρη πρόταση: > #include <stdio.h> #define UNUSED(x) ((void) (x)) #define BUFFSIZE 256 int main(int argc, char *argv[]) { UNUSED(argc); UNUSED(argv); char str[bUFFSIZE]; if (fgets(str, BUFFSIZE, stdin) != NULL) printf("%s\n", str); return 0; } PS. Ρε παιδιά αν δεν είστε σίγουροι για κάτι δεν χρειάζεται να απαντάτε. Αν πρόκειται για ANSI C τότε θα πρέπει να τροποποιήσεις τα UNUSED ως: > char str[bUFFSIZE]; UNUSED(argc); UNUSED(argv); Διαφορετικά ο κώδικα δεν γίνεται compile αφού η ANSI C δεν επιτρέπει την δήλωση μεταβλητών στο μέσο του προγράμματος εκτός και αν έχουμε έναρξη βρόχων ελέγχου κτλ. Υ.Γ. 1. Αντί του BUFFSIZE μπορούμε να χρησιμοποιήσουμε το ANSI C BUFSIZ το οποίο δηλώνεται στο stdio.h και περιέχει μια αρκετά μεγάλη τιμή (συνήθως 512). 2. Αντί του UNUSED μπορούμε να χρησιμοποιήσουμε το ανάλογο #pragma του compiler μας - αν και συμφωνώ ότι το UNUSED μας αποδεσμεύει από αυτή την ανάγκη με έναν τρόπο compiler independed. 3. Το #include <string> (και όχι #include <string.h>) παραπέμπει στην C++ STL όπως επίσης και ο τύπος string str οπότε δεν έχει καμία σχέση με την C - ο φίλος μας απλά έμπλεξε τις βιβλιοθήκες της C με εκείνες της C++.
Επισκέπτης Δημοσ. 7 Σεπτεμβρίου 2008 Δημοσ. 7 Σεπτεμβρίου 2008 Αν πρόκειται για ANSI C τότε θα πρέπει να τροποποιήσεις τα UNUSED ως:... Διαφορετικά ο κώδικα δεν γίνεται compile αφού η ANSI C δεν επιτρέπει την δήλωση μεταβλητών στο μέσο του προγράμματος εκτός και αν έχουμε έναρξη βρόχων ελέγχου κτλ. Σωστά αυτό δεν το σκέφτηκα, thanks. Btw σε gcc 4.x κάνει κανονικά compile (δοκιμάζω όλα τα προγράμματα πριν κάνω post) μάλλον επειδή χρησιμοποιεί αυτόματα C99 flag όταν υπάρχουν τέτοιες δηλώσεις
Directx Δημοσ. 7 Σεπτεμβρίου 2008 Δημοσ. 7 Σεπτεμβρίου 2008 Ουσιαστικά δεν υπάρχει ζήτημα, η πλειοψηφία των compilers λειτουργεί σε C++ mode ή τώρα πια σε C99 (δυστυχώς δεν υποστηρίζεται ακόμη από τον compiler μου και δεν έχω πολλά υπόψη μου επ' αυτού), αρκεί να μην πέσεις σε κανέναν περίεργο τύπο (μου έχει τύχει παλαιότερα) που θέλει σώνει και καλά ANSI C (C89)
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.