Προς το περιεχόμενο

Αφαίρεση NULL απο string σε C?


sp_steve

Προτεινόμενες αναρτήσεις

Γειά σας,

 

Μήπως μπορεί κάποιος να με βοηθήσει στο πώς μπορώ να αφαιρέσω τον χαρακτήρα NULL απο το τέλος ενός string στη C?

 

Δηλ. έχω char *str και θέλω με κάποιο τρόπο να βγάλω απο το τέλος του string το Null για να το περάσω σαν όρισμα σε κάποια συνάρτηση γιατι αλλιώς δεν το δέχεται...

 

Ευχαριστώ.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Ενα string στην C ειναι στην ουσια ενα array απο characters. To NULL υποδηλωνει το τελος του string. Καθε χαρακτηρας έχει καθε στιγμη μια τιμή, οποτε ο μονος τροπος για να "φυγει" το NULL οπως λες, πρεπει να μπει μια αλλη τιμη στη θέση του. Ωστόσο έχω την αισθηση πως κατι άλλο τρεχει στην περιπτωση σου.

Μπορεις να παραθεσεις τον κωδικα σου ώστε να δουμε τι τρεχει; Δηλ τον κωδικα της συναρτησης που θες να καλεσεις, τον κωδικα που δημιουργει το string και τον κωδικα που καλεις την συναρτηση.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Ας υποθέσουμε ότι κάπως γίνεται. Καλείς λοιπόν τη συνάρτηση και της περνάς έναν char* χωρίς \0 στο τέλος για να διαβάσει χαρακτήρες απο κει.

 

Πώς θα ξέρει η συνάρτηση πότε να σταματήσει να διαβάζει;

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Μια περιπτωση που μπορω να στεφτω ειναι πως η εν λογω συναρτηση δεν παιρνει ως ορισμα "string" αλλα "char array", ενα buffer δηλαδη. Σε αυτη τη περιπτωση ομως θα πρεπει να περνιεται ως επιπλεον ορισμα και το πληθως των στοιχειων αυτου του buffer, εκτος και αν ειναι global setting, οριζεται δηλαδη ως μεταβλητη καπου αλλου globally.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

@georgemarios: Ακριβώς, η ερώτησή μου είχε το νόημα να σκεφτεί ο steve την απάντηση και μετά να σκεφτεί τις συνέπειές της. Όπως π.χ. αν περνάς το μήκος ξεχωριστά γιατί να αρχίσεις να σκέφτεσαι "τι να κάνω με το null" αντί απλά να περάσεις μήκος - 1.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Ολο αυτό εχει να κάνει με την υλοποίηση ενός server-client. Ο client στέλνει αίτημα στον server για να μάθει κάτι με την εξής μορφή

είδος_εντολής hostname. Εγώ θέλω μετά τον διαχωρισμό του μηνύματος που λαμβάνει ο εξυπηρετητής, το όρισμα hostname να το βάζω στην συνάρτηση gethostbyname() η οποία δεν βγάζει σωστό αποτέλεσμα αν υπάρχει μέσα null χαρακτήρα...

 

Δεν ξέρω αν σας βοήθησα καθόλου να καταλάβετε το πρόβλημα μου...

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Μιλας για Link.png Site: αυτην τη συναρτηση?

Αν ναι, θα δεις πως παιρνει ως ορισμα ενα null-terminated string.

Αυτο που πρεπει να τσεκαρεις ειναι μηπως δε κανεις σωστα το διαχωρισμο και το ορισμα ειναι NULL altogether.....

 

Πως κανεις το διαχωρισμο; Πως καλεις τη συναρτηση;

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Ναι αυτή είναι... ο διαχωρισμός γίνεται με 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");
}
}

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Σου παραθέτω συνάρτηση που επιστρέφει ως πίνακα χαρακτήρων απαλλαγμένο από 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, δεν τη χρειάζεσαι τη δική μου συνάρτηση.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Όπως ανέφεραν και τα άλλα παιδιά, μάλλον το πρόβλημά σου είναι κάποιο άλλο από το 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)

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Παιδιά ευχαριστώ για την βοήθεια αλλα το βρήκα το πρόβλημα...

 

Όταν έγραφα είδος_εντολής hostnam έπρεπε μετα να βάλω και ένα κενο και μετα να πατήσω enter για να σταλει η αίτηση γιατί έτσι έπαιρνε όλο το μέγεθος του buffer που χρησιμοποιούσα.

 

Ευχαριστώ για τον χρόνο σας...

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...