vaggos_ece Δημοσ. 3 Ιουνίου 2015 Δημοσ. 3 Ιουνίου 2015 Καλημέρα, θέλω να διαβασω απο το πληκτολογιο μια λεξη και να την βάλω δυναμικα σε έναν πινακα.Με εντερ να σταματαει η επαναληψη.Γίνεται να δουλέψω με malloc,strlen(ονομα πινακα) και για συνθήκη για το enter να βαλω "\n"? Ευχαριστω.
lion2486 Δημοσ. 3 Ιουνίου 2015 Δημοσ. 3 Ιουνίου 2015 ναι, περίπου, γιατί μάλλον αυτό που δεν έχεις πιάσει καλά είναι ότι με τις συναρτήσεις εισόδου (πχ getchar) περιμένει \n για να συνεχίσει η εκτέλεση, για να πάρεις ολόκληρη λέξη πιο απλά κάνε το εξής: char * buffer[255], * str; fgets(buffer, 254, stdin); str = mallon((strlen(buffer) + 1) * sizeof(char)) ; strcpy(str, buffer); στην ουσία διαβάζεις μια γραμμή (μέχρι αλλαγή της) το πολύ 254 χαρακτήρες. Ο "πίνακας" - συμβολοσειρά str (το ίδιο πράγμα είναι) έχει το μήκος της λέξης σου. http://www.cplusplus.com/reference/cstdio/fgets/ 1
gon1332 Δημοσ. 3 Ιουνίου 2015 Δημοσ. 3 Ιουνίου 2015 Μπορώ να σκεφτώ δύο to-the-point τρόπους: α) Χρήση scanf με format identifier %(LENOFWORD-1)s, όπου LENOFWORD το μέγεθος της λέξης μαζί με το nul. β) Χρήση επαναληπτικής κλήσης getchar, μέχρι ο χαρακτήρας που θα λάβεις να είναι whitespace. Για την αποθήκευση της λέξης, θα μπορούσες να είχες έναν μεγαλούτσικο πίνακα με malloc και στη συνέχεια να τον κάνεις realloc. ναι, περίπου, γιατί μάλλον αυτό που δεν έχεις πιάσει καλά είναι ότι με τις συναρτήσεις εισόδου (πχ getchar) περιμένει \n για να συνεχίσει η εκτέλεση, για να πάρεις ολόκληρη λέξη πιο απλά κάνε το εξής: char * buffer[255], * str; fgets(buffer, 254, stdin); str = mallon((strlen(buffer) + 1) * sizeof(char)) ; strcpy(str, buffer); στην ουσία διαβάζεις μια γραμμή (μέχρι αλλαγή της) το πολύ 254 χαρακτήρες. Ο "πίνακας" - συμβολοσειρά str (το ίδιο πράγμα είναι) έχει το μήκος της λέξης σου. http://www.cplusplus.com/reference/cstdio/fgets/ Πρέπει όμως να πατάει enter μετά από κάθε λέξη. Εκτός και αν παίξει με strtok.
lion2486 Δημοσ. 3 Ιουνίου 2015 Δημοσ. 3 Ιουνίου 2015 Πρέπει όμως να πατάει enter μετά από κάθε λέξη. Εκτός και αν παίξει με strtok. εγώ κατάλαβα ότι θα εισάγει μόνο μία λέξη με το enter. 1
migf1 Δημοσ. 3 Ιουνίου 2015 Δημοσ. 3 Ιουνίου 2015 Αν έχω καταλάβει σωστά, το ερώτημα αφορά δυναμικό διάβασμα της εισόδου (stdin) μέσα σε ένα c-string, χωρίς να γνωρίζουμε εκ των προτέρων το μέγιστο μήκος. Αν ναι, τότε σε αυτές τις περιπτώσεις, η συνήθης προσέγγιση είναι να κάνουμε allocate-ahead το c-string, είτε κατά fixed πλήθος από bytes είτε διπλασιάζοντας το μέγεθός του, κάθε φορά που πάει να εξαντληθεί το buffer. Ο παρακάτω κώδικας, σε spoiler, δείχνει μια τέτοια υλοποίηση: #include <stdio.h> #include <stdlib.h> #define AHEAD (size_t) 16 // alloc-ahead size, in bytes (MUST be non-zero positive) /**********************************//** * ************************************** */ int main( void ) { // initially, alloc AHEAD bytes for input (sz) size_t sz = AHEAD; char *input = malloc(sz); if ( 0 == sz || NULL == input ) { goto alloc_failed; } // read chars from stdin into input, // realloc AHEAD every time sz gets exhausted int c; size_t len = 0; while ('\n' != (c=getchar()) && EOF != c) { // realloc ahead if needed if ( len == sz-1 ) { sz += AHEAD; char *temp = realloc( input, sz ); if ( 0 == sz || NULL == temp ) { goto alloc_failed; } input = temp; } // update input and len input[len++] = c; } // NUL terminate input input[len] = '\0'; puts( input ); printf( "sz = %zu, len = %zu\n", sz, len ); free( input ); return EXIT_SUCCESS; alloc_failed: free( input ); fprintf( stderr, "mem allocation failed, bye...\n" ); return EXIT_FAILURE; } Μερικές διευκρινήσεις: 1. Το allocation-ahead γίνεται κατά fixed πλήθος bytes (AHEAD στον κώδικα) κάθε φορά που πάει να εξαντληθεί το buffer (και πιο συγκεκριμένα, 1 byte πριν εξαντληθει). Αν αντί αυτού θέλεις να διπλασιάζεις το buffer, μπορείς να αλλάξεις τη γραμμή: sz += AHEADσε sz += sz2. Επειδή οι malloc(), calloc() και realloc() δεν επιστρέφουν NULL όταν τους περνάμε μηδενικό size, έχω βάλει τον πρόσθετο έλεγχο το sz να μην είναι 0 στις συνθήκες ελέγχου μετά το malloc() και το realloc(). Για τον ίδιο λόγο έχω βάλει και σχετικό σχόλιο στον ορισμό του AHEAD. 3. Αν χρησιμοποιείς gcc, παρέχει έτοιμη την συνάρτηση getline() που κάνει το ίδιο πράγμα. Μόνο που η getline() κρατάει και το ENTER, ενώ εγώ στον κώδικα το σβήνω (με '\0'). 4. Αν όλα έχουν πάει καλά, ο κώδικας τυπώνει το c-string που διάβασε, και κατόπιν τυπώνει το μέγιστο και το τρέχον μήκος του (sz και len, αντίστοιχα). 5. Για ρεαλιστική χρήση, ο κώδικας πρέπει να μετατραπεί σε συνάρτηση, κατά προτίμηση με το AHEAD είτε να ορίζεται μέσα της "εφάπαξ" είτε να περνιέται ως παράμετρος.
vaggos_ece Δημοσ. 4 Ιουνίου 2015 Μέλος Δημοσ. 4 Ιουνίου 2015 ναι, περίπου, γιατί μάλλον αυτό που δεν έχεις πιάσει καλά είναι ότι με τις συναρτήσεις εισόδου (πχ getchar) περιμένει \n για να συνεχίσει η εκτέλεση, για να πάρεις ολόκληρη λέξη πιο απλά κάνε το εξής: char * buffer[255], * str; fgets(buffer, 254, stdin); str = mallon((strlen(buffer) + 1) * sizeof(char)) ; strcpy(str, buffer); στην ουσία διαβάζεις μια γραμμή (μέχρι αλλαγή της) το πολύ 254 χαρακτήρες. Ο "πίνακας" - συμβολοσειρά str (το ίδιο πράγμα είναι) έχει το μήκος της λέξης σου. http://www.cplusplus.com/reference/cstdio/fgets/ επειδη δεν κανω copypaste:το stdin αποτι καταλαβα ειναι "σαν" το keyboard να τον κανει φακελο, αντι για mallon γραφω malloc, γραφω char buffer[225], *str. Αν έχω καταλάβει σωστά, το ερώτημα αφορά δυναμικό διάβασμα της εισόδου (stdin) μέσα σε ένα c-string, χωρίς να γνωρίζουμε εκ των προτέρων το μέγιστο μήκος. Αν ναι, τότε σε αυτές τις περιπτώσεις, η συνήθης προσέγγιση είναι να κάνουμε allocate-ahead το c-string, είτε κατά fixed πλήθος από bytes είτε διπλασιάζοντας το μέγεθός του, κάθε φορά που πάει να εξαντληθεί το buffer. Ο παρακάτω κώδικας, σε spoiler, δείχνει μια τέτοια υλοποίηση: #include <stdio.h> #include <stdlib.h> #define AHEAD (size_t) 16 // alloc-ahead size, in bytes (MUST be non-zero positive) /**********************************//** * ************************************** */ int main( void ) { // initially, alloc AHEAD bytes for input (sz) size_t sz = AHEAD; char *input = malloc(sz); if ( 0 == sz || NULL == input ) { goto alloc_failed; } // read chars from stdin into input, // realloc AHEAD every time sz gets exhausted int c; size_t len = 0; while ('\n' != (c=getchar()) && EOF != c) { // realloc ahead if needed if ( len == sz-1 ) { sz += AHEAD; char *temp = realloc( input, sz ); if ( 0 == sz || NULL == temp ) { goto alloc_failed; } input = temp; } // update input and len input[len++] = c; } // NUL terminate input input[len] = '\0'; puts( input ); printf( "sz = %zu, len = %zu\n", sz, len ); free( input ); return EXIT_SUCCESS; alloc_failed: free( input ); fprintf( stderr, "mem allocation failed, bye...\n" ); return EXIT_FAILURE; } Μερικές διευκρινήσεις: 1. Το allocation-ahead γίνεται κατά fixed πλήθος bytes (AHEAD στον κώδικα) κάθε φορά που πάει να εξαντληθεί το buffer (και πιο συγκεκριμένα, 1 byte πριν εξαντληθει). Αν αντί αυτού θέλεις να διπλασιάζεις το buffer, μπορείς να αλλάξεις τη γραμμή: sz += AHEADσε sz += sz2. Επειδή οι malloc(), calloc() και realloc() δεν επιστρέφουν NULL όταν τους περνάμε μηδενικό size, έχω βάλει τον πρόσθετο έλεγχο το sz να μην είναι 0 στις συνθήκες ελέγχου μετά το malloc() και το realloc(). Για τον ίδιο λόγο έχω βάλει και σχετικό σχόλιο στον ορισμό του AHEAD. 3. Αν χρησιμοποιείς gcc, παρέχει έτοιμη την συνάρτηση getline() που κάνει το ίδιο πράγμα. Μόνο που η getline() κρατάει και το ENTER, ενώ εγώ στον κώδικα το σβήνω (με '\0'). 4. Αν όλα έχουν πάει καλά, ο κώδικας τυπώνει το c-string που διάβασε, και κατόπιν τυπώνει το μέγιστο και το τρέχον μήκος του (sz και len, αντίστοιχα). 5. Για ρεαλιστική χρήση, ο κώδικας πρέπει να μετατραπεί σε συνάρτηση, κατά προτίμηση με το AHEAD είτε να ορίζεται μέσα της "εφάπαξ" είτε να περνιέται ως παράμετρος. ευχαριστω για τον χρονο σου αλλα το πρωτο παραδειγμα είναι μεσα στην ύλη μου οποτε.... !!!!Θέλω να φτιαξω κρεμαλα οποτε θελω την λεξη σε πινακα για να δουλεψω.
lion2486 Δημοσ. 4 Ιουνίου 2015 Δημοσ. 4 Ιουνίου 2015 επειδη δεν κανω copypaste:το stdin αποτι καταλαβα ειναι "σαν" το keyboard να τον κανει φακελο, αντι για mallon γραφω malloc. ναι malloc εννοούσα, στην ουσία "διαβάζεις" από την είσοδο σε έναν μεγάλο πίνακα από χαρακτήρες, και μετά δεσμεύεις μνήμη και αντιγράφεις όσους χαρακτέρες έχεις χτησιμοποιήσεις, μέχρι και το '\0'. Το char * a; είναι ίδιο με το char a[];, δηλαδή πίνακα αλλά χωρίς ακόμα ορισμένο μέγεθος. Όλοι οι χαρακτήρες είναι char , στην getchar χρησιμοποιούμε συνήθως Int για το λόγω ότι μπορεί και να μην επιστρέψει χαρακτήρα, π.χ. EOF. 1
vaggos_ece Δημοσ. 4 Ιουνίου 2015 Μέλος Δημοσ. 4 Ιουνίου 2015 Αυτο που θελω είναι να μπορω να βλεπω τον καθε χαρακτηρα του πινακα για να κανω τα απαραιτητα για την κρεμαλα. Δηλ. for(i=0;i<strlen(-1;i++){ printf("%s",str);
gon1332 Δημοσ. 4 Ιουνίου 2015 Δημοσ. 4 Ιουνίου 2015 επειδη δεν κανω copypaste:το stdin αποτι καταλαβα ειναι "σαν" το keyboard να τον κανει φακελο, αντι για mallon γραφω malloc, γραφω char buffer[225], *str. Το stdin είναι ένας δείκτης σε FILE (FILE *stdin), το οποίο FILE είναι ένα struct που περιγράφει αρχεία. Περιέχει διάφορα πεδία τα οποία είναι σημαντικά για το buffering του stdio. Επιπλέον, το πιο σημαντικό πεδίο που περιέχει είναι ο file descriptor. Ο file descriptor είναι ένας ακέραιος που συμβολίζει τη θέση σε έναν πίνακα ο οποίος αποτελείται από δείκτες σε δομές προσβασης. Για κάθε ανοικτό αρχείο* υπάρχουν τόσες δομές πρόσβασης, όσοι file descriptors είναι ανοιχτοί για αυτό το αρχείο (όσες φορές δηλαδή κάλεσες fopen, open πάνω στο αρχείο). Οι δομές πρόσβασεις περιέχουν πεδία που έχουν σχέση με την πρόσβαση σε διάφορα αρχεία. Η stdio δεσμεύει τις τρεις πρώτες θέσεις του πίνακα αυτού (0, 1 και 2) για την καθιερομένη είσοδο, έξοδο και έξο- δο λάθους αντίστοιχα. Ή καλύτερα STDIN_FILENO, STDOUT_FILENO και STDERR_FILENO αντίστοιχα. Αυτά τα τρία που ανέφερα είναι οι file descriptors για το πληκτρολόγιο, τερματικό και τερματικό. Αυτά περι- έχονται όπως είπαμε ως πεδία στο structrure FILE. Οπότε και προκύπτουν τα "μαγικά" stdin, stdout και stderr. Ο καθένας μπορεί να μπερδέψει την stdio και χωρίς να το γνωρίζει, ενώ εκτελεί μία printf, η οποία βγάζει στο stdout, να βγάζει σε ένα αρχείο που ανοίξαμε με fopen. *Για κάθε ανοικτό αρχείο, υπάρχει μόνο ένα *μοναδικό*(redundancy) i-node structure που το χαρακτηρίζει. 1
vaggos_ece Δημοσ. 4 Ιουνίου 2015 Μέλος Δημοσ. 4 Ιουνίου 2015 http://www.insomnia.gr/topic/571863-%CE%BA%CF%81%CE%B5%CE%BC%CE%B1%CE%BB%CE%B1-c/ Ευχαριστώ το thread μπορει να κλήσει , έκανα νεο γιατι δεν έχει σωστο τιτλο.
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα