lektikos Δημοσ. 13 Νοεμβρίου 2013 Δημοσ. 13 Νοεμβρίου 2013 Προσπαθώ να φτιάξω μια συνάρτηση που θα καλείται από τη main με σκοπό να εκτυπώνεται η συμβολοσειρά Little,by little,one travel far. χωρίς τα σημεία στίξης, δηλ: Little by little one travel far Παραθέτω τον κώδικα που έκανα, αλλά κάτι δεν κάνω σωστά και τυπώνεται null και κάποιοι χαρακτήρες σκουπίδια. Καμιά ιδέα κανείς? #include <stdio.h>#include <stdlib.h>char *my_Strtok(char *str, const char *p);int main(){ const char *delim=",."; const char str[]="Little,by little,one travel far."; printf("%s,%s",(my_Strtok(str,delim)));}char *my_Strtok(char *string, const char *p){ if (!string) return NULL; char s[]="Little,by little,one travel far."; if(p!=NULL) printf("%s\n",p); while (p=my_Strtok(NULL,",.")!=NULL){ printf("%s",p); } return 0;}
migf1 Δημοσ. 14 Νοεμβρίου 2013 Δημοσ. 14 Νοεμβρίου 2013 Αν η strtok() δεν είναι προαπαιτούμενο της άσκησης, τότε... #include <stdio.h> #include <ctype.h> void print_nopunct( const char *str ) { if ( !str || !*str ) return; for (char *p=str; *p; p++) { if ( ispunct(*p) ) putchar('\n'); else putchar(*p); } fflush( stdout ); } ... ή πιο εξειδικευμένα... #include <stdio.h> #include <string.h> void print_nopunct( const char *str ) { if ( !str || !*str ) return; for (char *p=str; *p; p++) { if ( strchr(".,", *p) ) putchar('\n'); else putchar(*p); } fflush( stdout ); } ... ΥΓ. Αντί για p μπορείς να δουλέψεις κι απευθείας με το str μέσα στην συνάρτηση.
lektikos Δημοσ. 14 Νοεμβρίου 2013 Μέλος Δημοσ. 14 Νοεμβρίου 2013 Αν η strtok() δεν είναι προαπαιτούμενο της άσκησης, τότε... #include <stdio.h> #include <ctype.h> void print_nopunct( const char *str ) { if ( !str || !*str ) return; for (char *p=str; *p; p++) { if ( ispunct(*p) ) putchar('\n'); else putchar(*p); } fflush( stdout ); } ... ή πιο εξειδικευμένα... #include <stdio.h> #include <string.h> void print_nopunct( const char *str ) { if ( !str || !*str ) return; for (char *p=str; *p; p++) { if ( strchr(".,", *p) ) putchar('\n'); else putchar(*p); } fflush( stdout ); } ... ΥΓ. Αντί για p μπορείς να δουλέψεις κι απευθείας με το str μέσα στην συνάρτηση. Ευχαριστώ πολύ για την απάντηση σου. Τι εννοείς με το αντί για p, ότι γίνεται και απευθείας με το str?
Star_Light Δημοσ. 14 Νοεμβρίου 2013 Δημοσ. 14 Νοεμβρίου 2013 Εννοει οτι αντι να βάλεις εναν δεικτη να δειχνει στον πινακα χαρακτήρων str μπορεις να δουλεψεις απευθειας με αυτον. for (int i = 0; i < LEN ; i++) { if ( strchr(".,", str[i]) ) putchar('\n'); else putchar(str[i]);
migf1 Δημοσ. 14 Νοεμβρίου 2013 Δημοσ. 14 Νοεμβρίου 2013 Βασικά εννοούσα αυτό εδώ... void print_nopunct( const char *str ) { if ( !str || !*str ) return; for (; *str; str++) { if ( strchr("., \n\t", *str) ) putchar('\n'); else putchar(*str); } fflush( stdout ); } ... ή αυτό που έδωσε ο StarLight αλλά χωρίς το LEN (το LEN καθυστερεί αχρείαστα τη συνάρτηση, γιατί πρέπει να υπολογιστεί πρώτα)... void print_nopunct( const char *str ) { if ( !str || !*str ) return; for (int i=0; str[i]; i++) { if ( strchr("., \n\t", str[i]) ) putchar('\n'); else putchar(str[i]); } fflush( stdout ); }
lektikos Δημοσ. 14 Νοεμβρίου 2013 Μέλος Δημοσ. 14 Νοεμβρίου 2013 Ευχαριστώ πολύ και τους δυο σας. Κάτι τελευταίο, όταν ξεκινάει μια for με το ερωτηματικό ως πρώτο όρισμα μέσα στην παρένθεση, δηλ for(; ... ...) τι ακριβώς κάνει αυτό το ; ? Ευχαριστώ εκ των προτέρων.
Star_Light Δημοσ. 14 Νοεμβρίου 2013 Δημοσ. 14 Νοεμβρίου 2013 Ευχαριστώ πολύ και τους δυο σας. Κάτι τελευταίο, όταν ξεκινάει μια for με το ερωτηματικό ως πρώτο όρισμα μέσα στην παρένθεση, δηλ for(; ... ...) τι ακριβώς κάνει αυτό το ; ? Ευχαριστώ εκ των προτέρων. Ξεκιναει απο εκει που ο str ειναι ηδη αρχικοποιημενος δηλαδη απο την αρχη του πινακα. int i = 0; for( ; i<4; i++) // do sth Το i πιο πανω ειναι ηδη αρχικοποιημενο αρα η for θα χρησιμοποιησει την τιμη που έχει ηδη.
lektikos Δημοσ. 14 Νοεμβρίου 2013 Μέλος Δημοσ. 14 Νοεμβρίου 2013 #include <stdio.h>#include <ctype.h>char print_nopunct( const char *str ){ char *p; int i; if ( !str || !*str ) return 0; for (*p=str; *p; p++) { if ( ispunct(*p) ) putchar('\n'); else putchar(*p); } fflush( stdout );}int main(){char k;const char *pin ="Winter.Autumn,Spring,Summer.";print_nopunct(pin); //pin=k; printf("[%s]\n",pin); return 0;} Ακολούθησα τον τρόπο με τη συνάρτηση ispunct, αλλά δεν τρέχει σωστά. Τυπώνει "σκουπίδια" στην αρχή και έπειτα τα[Winter.Autumn,Spring,Summer] μαζί με τα σημεία στίξης. Κάνω κάτι λάθος στην κλήση της συνάρτησης, στη main?
imitheos Δημοσ. 14 Νοεμβρίου 2013 Δημοσ. 14 Νοεμβρίου 2013 for (char *p=str; *p; p++) { for (*p=str; *p; p++) { Η δήλωση του migf1 με τη δική σου είναι τελείως διαφορετική. Ο migf χρησιμοποιεί μια μαγκιά της έκδοσης C99 του προτύπου που επιτρέπει να δηλώνεις μια μεταβλητή μέσα στο for αντί για την αρχή. Από εκεί και πέρα όταν έχεις μια δήλωση της μορφής τύπος *μεταβλητή = κάτι; αυτό σημαίνει τύπος *μεταβλητή; μεταβλητή = κάτι; Βλέπεις την διαφορά με το δικό σου κώδικα ?
lektikos Δημοσ. 14 Νοεμβρίου 2013 Μέλος Δημοσ. 14 Νοεμβρίου 2013 Ναι, το έπιασα! Ευχαριστώ. Αντικατέστησα στον έλεγχο της for (*p=str; *p; p++) , το *p με p και "έτρεξε" μια χαρά.
imitheos Δημοσ. 14 Νοεμβρίου 2013 Δημοσ. 14 Νοεμβρίου 2013 Ναι, το έπιασα! Ευχαριστώ. Αντικατέστησα στον έλεγχο της for (*p=str; *p; p++) , το *p με p και "έτρεξε" μια χαρά. Ωραία. Κατάλαβες όμως ποιο ήταν το λάθος στο *p και γιατί έπρεπε αφενός να αλλάξει και αφετέρου να αλλάξει σε p και όχι σε κάτι άλλο ?
lektikos Δημοσ. 14 Νοεμβρίου 2013 Μέλος Δημοσ. 14 Νοεμβρίου 2013 Ωραία. Κατάλαβες όμως ποιο ήταν το λάθος στο *p και γιατί έπρεπε αφενός να αλλάξει και αφετέρου να αλλάξει σε p και όχι σε κάτι άλλο ? Θα ήθελα να αναλύσουμε αν γίνεται όλο τον έλεχγο for. Γιατί περνάμε την str στην p και όχι στο δείκτη *p. To δεύτερο όρισμα της for, *p ; μόνο του τι κάνει?
imitheos Δημοσ. 14 Νοεμβρίου 2013 Δημοσ. 14 Νοεμβρίου 2013 Θα ήθελα να αναλύσουμε αν γίνεται όλο τον έλεχγο for. Γιατί περνάμε την str στην p και όχι στο δείκτη *p. Ανάλυσε μας τι είναι το str, τι το p και τι το *p To δεύτερο όρισμα της for, *p ; μόνο του τι κάνει? for(ανάθεση εκκίνησης; συνθήκη ελέγχου; δήλωση αύξησης) Όταν έχεις for(i = 0; i < 5; i++) είναι σαν να έχεις i = 0; Τρέξε τις παρακάτω εντολές ..... { σώμα του for } i++ μέχρι το i να γίνει 5. Το πρώτο τμήμα του for θέτει μια αρχική τιμή εκκίνησης στην μεταβλητή index που χρησιμοποιείς και υπάρχει για ευκολία. Όπως ρώτησες σε προηγούμενο μήνυμα, μπορεί να είναι κενό αν η μεταβλητή έχει αρχικοποιηθεί πιο μπροστά. Το τρίτο τμήμα είναι εκτελείται στο τέλος κάθε φοράς και (στην πλειοψηφία των περιπτώσεων) δηλώνει πώς αυξάνεται το index. Το δεύτερο τμήμα είναι η συνθήκη ελέγχου. Όσο αυτή δεν είναι ψευδής (0) τόσο θα τρέχει η ανακύκλωση. Για πες μας λοιπόν τι σημαίνει το *p που υπάρχει στο 2ο όρισμα της for ?
lektikos Δημοσ. 14 Νοεμβρίου 2013 Μέλος Δημοσ. 14 Νοεμβρίου 2013 Η str είναι μια σταθερά δείκτης τυπου char η οποία "δείχνει" τη συμβολοσειρα(το 1ο στοιχειο της). Η p είναι δείκτης τύπου char(τοπικη μεταβλητης της print_nopunct) και όσο δεν δείχνει σε στοιχειο εκτος συμβολοσειρας(να το πούμε έτσι?), αυξάνεται και στην ουσία σαρώνει τη συμβολοσειρα και αν βρει σημειο στιξης, αλλάζει γραμμή και τυπώνονται μόνο τα στοιχεία χωρίς όμως τα . και , Θα μπορούσαμε να πούμε ότι το δεύτερο όρισμα της for , είναι το p>0; ? Tώρα, βέβαια γιατί p=str και όχι *p=str, δεν το 'χω "πιάσει" πλήρως... Ανάλυσε μας τι είναι το str, τι το p και τι το *p for(ανάθεση εκκίνησης; συνθήκη ελέγχου; δήλωση αύξησης)Όταν έχεις for(i = 0; i < 5; i++) είναι σαν να έχεις i = 0; Τρέξε τις παρακάτω εντολές ..... { σώμα του for } i++ μέχρι το i να γίνει 5. Το πρώτο τμήμα του for θέτει μια αρχική τιμή εκκίνησης στην μεταβλητή index που χρησιμοποιείς και υπάρχει για ευκολία. Όπως ρώτησες σε προηγούμενο μήνυμα, μπορεί να είναι κενό αν η μεταβλητή έχει αρχικοποιηθεί πιο μπροστά. Το τρίτο τμήμα είναι εκτελείται στο τέλος κάθε φοράς και (στην πλειοψηφία των περιπτώσεων) δηλώνει πώς αυξάνεται το index. Το δεύτερο τμήμα είναι η συνθήκη ελέγχου. Όσο αυτή δεν είναι ψευδής (0) τόσο θα τρέχει η ανακύκλωση.Για πες μας λοιπόν τι σημαίνει το *p που υπάρχει στο 2ο όρισμα της for ?
Star_Light Δημοσ. 15 Νοεμβρίου 2013 Δημοσ. 15 Νοεμβρίου 2013 @lektikos το σύμβολο / μπορει να χρησιμοποιηθει και σαν διαιρεση και στα σχολια (με ενα αστερακι μετα). Ετσι και το συμβολο * . Μπορει να χρησιμοποιηθει και στον πολλαπλασιασμο και στην δηλωση ενος δεικτη και στην αποαναφοροποιηση του δεικτη (που παιρνεις το περιεχομενο της διευθυνσης που δειχνει ο δεικτης). Οταν δηλωνεις εναν δεικτη ο μεταγλωτιστης ξέρει οτι αυτο το συμβολο ειναι για αυτη την δουλεια επομενως κατα την στιγμη της δηλωσης του μπορει να αρχικοποιησεις τον δεικτη με μια διευθυνση στην προκειμενη με την διευθυνση του string. To str ειναι μια σταθερη διευθυνση και αντιμετωπιζεται σαν δεικτης ΜΟΝΟ οταν περνάει σαν ορισμα σε μια συνάρτηση σε ολες τις υπολοιπες περιπτωσεις ειναι πίνακας και οχι δεικτης. Για παράδειγμα αμα δηλωθει ενας πινακας στην main και δεν τον περνάς σε καποια συνάρτηση τοτε ειναι πινακας. Επισης το συμβολο * διπλα στον p ΣΕ ΟΛΕΣ τις αλλες περιπτωσεις (εκτος της δηλωσης του που εγραψα πριν) αντιμετωπιζεται ως συμβολο αποαναφοροποιησης του δεικτη. Οποτε το χρησιμοποιεις δηλαδη θα παιρνεις το περιεχομενο του. Φυσικα η κατασταση αλλαζει οταν μιλαμε για διπλους δεικτες αλλα αυτο δεν σε απασχολει προς το παρον. Το for ή ανακυκλωση θα σταματησει οταν το *p γινει 0. Δωσει δηλαδη μη αληθη τιμη. Εκτιμηθει σε 0 που ειναι ο ASCII του null character '\0' για αυτο το λογο θα πρεπει ένα εγκυρο C-string να τερματιζει με αυτο τον χαρακτηρα σαν τελευταιο του. Ο βροχος θα σταματησει οταν το string φτασει στο τέλος του.
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα