sp_steve Δημοσ. 16 Νοεμβρίου 2012 Δημοσ. 16 Νοεμβρίου 2012 Γειά σας, Μήπως μπορεί κάποιος να με βοηθήσει στο πώς μπορώ να αφαιρέσω τον χαρακτήρα NULL απο το τέλος ενός string στη C? Δηλ. έχω char *str και θέλω με κάποιο τρόπο να βγάλω απο το τέλος του string το Null για να το περάσω σαν όρισμα σε κάποια συνάρτηση γιατι αλλιώς δεν το δέχεται... Ευχαριστώ.
georgemarios Δημοσ. 16 Νοεμβρίου 2012 Δημοσ. 16 Νοεμβρίου 2012 Ενα string στην C ειναι στην ουσια ενα array απο characters. To NULL υποδηλωνει το τελος του string. Καθε χαρακτηρας έχει καθε στιγμη μια τιμή, οποτε ο μονος τροπος για να "φυγει" το NULL οπως λες, πρεπει να μπει μια αλλη τιμη στη θέση του. Ωστόσο έχω την αισθηση πως κατι άλλο τρεχει στην περιπτωση σου. Μπορεις να παραθεσεις τον κωδικα σου ώστε να δουμε τι τρεχει; Δηλ τον κωδικα της συναρτησης που θες να καλεσεις, τον κωδικα που δημιουργει το string και τον κωδικα που καλεις την συναρτηση.
defacer Δημοσ. 16 Νοεμβρίου 2012 Δημοσ. 16 Νοεμβρίου 2012 Ας υποθέσουμε ότι κάπως γίνεται. Καλείς λοιπόν τη συνάρτηση και της περνάς έναν char* χωρίς \0 στο τέλος για να διαβάσει χαρακτήρες απο κει. Πώς θα ξέρει η συνάρτηση πότε να σταματήσει να διαβάζει;
georgemarios Δημοσ. 16 Νοεμβρίου 2012 Δημοσ. 16 Νοεμβρίου 2012 Μια περιπτωση που μπορω να στεφτω ειναι πως η εν λογω συναρτηση δεν παιρνει ως ορισμα "string" αλλα "char array", ενα buffer δηλαδη. Σε αυτη τη περιπτωση ομως θα πρεπει να περνιεται ως επιπλεον ορισμα και το πληθως των στοιχειων αυτου του buffer, εκτος και αν ειναι global setting, οριζεται δηλαδη ως μεταβλητη καπου αλλου globally.
defacer Δημοσ. 16 Νοεμβρίου 2012 Δημοσ. 16 Νοεμβρίου 2012 @georgemarios: Ακριβώς, η ερώτησή μου είχε το νόημα να σκεφτεί ο steve την απάντηση και μετά να σκεφτεί τις συνέπειές της. Όπως π.χ. αν περνάς το μήκος ξεχωριστά γιατί να αρχίσεις να σκέφτεσαι "τι να κάνω με το null" αντί απλά να περάσεις μήκος - 1.
sp_steve Δημοσ. 16 Νοεμβρίου 2012 Μέλος Δημοσ. 16 Νοεμβρίου 2012 Ολο αυτό εχει να κάνει με την υλοποίηση ενός server-client. Ο client στέλνει αίτημα στον server για να μάθει κάτι με την εξής μορφή είδος_εντολής hostname. Εγώ θέλω μετά τον διαχωρισμό του μηνύματος που λαμβάνει ο εξυπηρετητής, το όρισμα hostname να το βάζω στην συνάρτηση gethostbyname() η οποία δεν βγάζει σωστό αποτέλεσμα αν υπάρχει μέσα null χαρακτήρα... Δεν ξέρω αν σας βοήθησα καθόλου να καταλάβετε το πρόβλημα μου...
georgemarios Δημοσ. 16 Νοεμβρίου 2012 Δημοσ. 16 Νοεμβρίου 2012 Μιλας για Site: αυτην τη συναρτηση? Αν ναι, θα δεις πως παιρνει ως ορισμα ενα null-terminated string. Αυτο που πρεπει να τσεκαρεις ειναι μηπως δε κανεις σωστα το διαχωρισμο και το ορισμα ειναι NULL altogether..... Πως κανεις το διαχωρισμο; Πως καλεις τη συναρτηση;
sp_steve Δημοσ. 16 Νοεμβρίου 2012 Μέλος Δημοσ. 16 Νοεμβρίου 2012 Ναι αυτή είναι... ο διαχωρισμός γίνεται με strtok()... αυτός είναι ο κώδικας μου... > if(FD_ISSET(i, &master)) { char * pch; pch = strtok (buf," "); const char * service; service = strstr( pch, "res_name" ); if( strcmp(service , "res_name" ) == 0 ) { char *host_name = "\0"; pch = strtok (NULL, " "); printf (" pch %s \n",pch); host_name = pch; int l = strlen(host_name); printf("lsize %d " , l); printf ("\n host_name you looking for %s \n",host_name); memset(&whereto, 0, sizeof(struct sockaddr)); to = (struct sockaddr_in *)&whereto; to->sin_family = AF_INET; to->sin_addr.s_addr = inet_addr(temp); if (to->sin_addr.s_addr != -1) hostname = host_name; else { hp = gethostbyname(host_name); if (!hp) printf("unknown host %s\n", host_name); else { to->sin_family = hp->h_addrtype; memcpy(&(to->sin_addr.s_addr), hp->h_addr, hp->h_length); hostname = hp->h_name; printf("name: %s\n", hp->h_name); while (*hp->h_aliases) printf("alias: %s\n", *hp->h_aliases++); while (*hp->h_addr_list) { bcopy(*hp->h_addr_list++, (char *) &a, sizeof(a)); printf("address: %s\n", inet_ntoa(a)); } printf("\n %s : ",hp->h_name); //puts(hostname); printf("gethostbyname was successful\n"); } }
migf1 Δημοσ. 16 Νοεμβρίου 2012 Δημοσ. 16 Νοεμβρίου 2012 Σου παραθέτω συνάρτηση που επιστρέφει ως πίνακα χαρακτήρων απαλλαγμένο από nul-characters το όρισμα που της περνάς ως c-string (πρέπει να τον κάνεις free τον πίνακα όταν κάνεις τη δουλειά σου)... > char *s_dupToCharArray( const char *s, size_t *lenOut ) { char *ret = NULL; if ( !s || !*s ) { *lenOut = 0; return NULL; } *lenOut = strlen(s); if ( NULL == (ret = malloc(*lenOut)) ) { *lenOut = 0; return NULL; } memcpy(ret, s, *lenOut); return ret; } Κι εδώ ένα δείγμα χρήσης της... > #include <stdio.h> #include <string.h> #include <stdlib.h> /* --------------------------------------------- */ void arrChar_print( const char *arrChar, size_t len ) { if ( !arrChar || 0 == len ) { printf( "[ %s() found nothing to print ]\n", __func__ ); return; } for (size_t i=0; i < len; i++) putchar( arrChar[i] ); } /* --------------------------------------------- */ char *s_dupToCharArray( const char *s, size_t *lenOut ) { char *ret = NULL; if ( !s || !*s ) { *lenOut = 0; return NULL; } *lenOut = strlen(s); if ( NULL == (ret = malloc(*lenOut)) ) { *lenOut = 0; return NULL; } memcpy(ret, s, *lenOut); return ret; } /* --------------------------------------------- */ int main( void ) { size_t lenArrChar = 0; char *cstring = "I am a normal c-string"; char *arrChar = s_dupToCharArray(cstring, &lenArrChar); if ( NULL == arrChar ) { puts( "*** internal error, bye..." ); exit(1); } arrChar_print( arrChar, lenArrChar ); putchar('\n'); free( arrChar ); exit(0); } EDIT: Πιθανότατα το γνωρίζεις, αλλά χωρίς nul-terminator δεν μπορείς να χρησιμοποιήσεις τον πίνακα με σχεδόν καμία από τις στάνταρ συναρτήσεις διαχείρισης strings της γλώσσας (για αυτό σου έβαλα στον παραπάνω κώδικα ειδική συνάρτηση για την εκτύπωση του πίνακα). EDIT-2 Έβαλα να σετάρει σε 0 και το *lenOut αν περαστεί ως NULL ή ως '\0' το s. Επίσης, εφόσον επιβεβαίωσες πως το θέλεις για τη συνάρτηση που είπε ο georgemarios, δεν τη χρειάζεσαι τη δική μου συνάρτηση.
imitheos Δημοσ. 16 Νοεμβρίου 2012 Δημοσ. 16 Νοεμβρίου 2012 Όπως ανέφεραν και τα άλλα παιδιά, μάλλον το πρόβλημά σου είναι κάποιο άλλο από το NULL στο τέλος μια και η συνάρτηση δέχεται κανονικό "string" όπως όλες οι συναρτήσεις της libc. Ναι αυτή είναι... ο διαχωρισμός γίνεται με strtok()... αυτός είναι ο κώδικας μου... > char * pch; pch = strtok (buf," "); char *host_name = "\0"; host_name = pch; hostname = host_name; bcopy(*hp->h_addr_list++, (char *) &a, sizeof(a)); Πέραν του στυλ του κώδικα που είναι προσωπικό οπότε ας μην πάμε ακόμη εκεί, γιατί έχεις τόσες αναθέσεις χωρίς να κάνουν τίποτα ? Θέτεις τον δείκτη host_name να δείχνει στο read-only "\0" μετά στο pch, μετά θέτεις το hostname στον host_name, κτλ. Μεσολαβούν γραμμές που δεν βλέπουμε ? Αν ναι οκ αλλιώς δεν μπορώ να καταλάβω τι θέλεις να κάνεις. Επίσης γιατί χρησιμοποιείς μια την memcpy και μια την bcopy ? Η bcopy είναι deprecated οπότε καλύτερα μην την χρησιμοποιείς. Μπορείς να περιγράψεις καλύτερα το πρόβλημα ? (ή να βάλεις ολόκληρο τον κώδικα σε spoiler)
sp_steve Δημοσ. 16 Νοεμβρίου 2012 Μέλος Δημοσ. 16 Νοεμβρίου 2012 Παιδιά ευχαριστώ για την βοήθεια αλλα το βρήκα το πρόβλημα... Όταν έγραφα είδος_εντολής hostnam έπρεπε μετα να βάλω και ένα κενο και μετα να πατήσω enter για να σταλει η αίτηση γιατί έτσι έπαιρνε όλο το μέγεθος του buffer που χρησιμοποιούσα. Ευχαριστώ για τον χρόνο σας...
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα