PDA

View Full Version : [C]puntatore a stringa stampa stringhe diverse senza esser stato modificato..


santaclause83
20-07-2007, 11:05
alloco spazio e inizializzo un char* msg con una stringa con questo formato:
"PIDdelprocesso CONNECT nomeutente"
per poi inviarla al server.

PROBLEMA: proprio all'inizio quando inizializzo la variabile msg,se controllo come è stata inizializzata con delle stampe su schermo vedo che la prima stampa mi dà il messaggio pulito così come deve essere,ma poche righe sotto se ristampo la stringa vedo che è stato aggiunto un carattere indecifrabile alla fine

la cosa strana è che tra le due stampe la variabile msg non è stata toccata,sotto il codice:

//-->creazione messaggio "PID CONNECT USER",msg occupa lo spazio di " connect user"+sizeof(int) del pid

if((msg = (char *)malloc(sizeof(char)*((strlen(argv[1])+strlen(" CONNECT ")+1))+sizeof(int)*1)) == NULL){
printf("malloc di msg fallita,terminazione client");
exit(1);
}

sprintf(msg,"%d",pid);
strncat(msg," CONNECT ",strlen(" CONNECT "));
strncat(msg,utente,strlen(utente));//adesso msg == "PID CONNECT USER"


printf("messaggio da inoltrare = %s;\n",msg);//stampa di controllo
//regolare


----->sotto alloco lo spazio per il nome della pipe per le comunicazioni con il server [SERVERCLIENTPID] e ristampo la variabile msg per controllare,vedo che è stata modificata

if((dir_letture = (char *)malloc(sizeof(char)*(strlen("serverclient")+1)+sizeof(int)*1)) == NULL){
printf("malloc per letture dal server fallita,terminazione client");
exit(1);
}
printf("messaggio da inoltrare = %s;\n",msg);//stampa di controllo con carattere
indecifrabile

STAMPE SU SHELL:
messaggio da inoltrare = 6652 CONNECT silvio;
messaggio da inoltrare = 6652 CONNECT silvio[carattereindecifrabile];

andbin
20-07-2007, 12:22
sprintf(msg,"%d",pid);
strncat(msg," CONNECT ",strlen(" CONNECT "));
strncat(msg,utente,strlen(utente));Il problema è nella parte che ho quotato: alla strncat hai specificato di copiare esattamente il numero di caratteri della stringa ma così non viene copiato il carattere nullo! Quindi fai:

strncat(msg," CONNECT ",strlen(" CONNECT ")+1);

o ancora più semplicemente:

strcat(msg," CONNECT ");

Idem per la strncat sotto.

cionci
20-07-2007, 12:24
sizeof(int) ritorna sempre 4, mentre il pid può essere anche più di 4 caratteri ;)
Devi convertire il pid ad intero in una stringa temporanea e misurarne la lunghezza.

cionci
20-07-2007, 12:27
Il problema è nella parte che ho quotato: alla strncat hai specificato di copiare esattamente il numero di caratteri della stringa ma così non viene copiato il carattere nullo!
strncat dovrebbe appenderlo da solo il terminatore:

char * strncat ( char * destination, char * source, size_t num );

Appends the first num characters of source to destination, plus a terminating null-character. If the length of the C string in source is less than num, only the content up to the terminating null-character is copied.

andbin
20-07-2007, 13:15
strncat dovrebbe appenderlo da solo il terminatore:

char * strncat ( char * destination, char * source, size_t num );

Appends the first num characters of source to destination, plus a terminating null-character. If the length of the C string in source is less than num, only the content up to the terminating null-character is copied.Sì vero. Ho confuso con strncpy.

cionci
20-07-2007, 13:20
Sì vero. Ho confuso con strncpy.
Non me lo ricordavo anche io...sono dovuto andare a vedere ;)

santaclause83
20-07-2007, 13:38
la cosa assurda è che stamattina dopo aver scritto il post,l'ho collaudato senza toccarlo e non mi faceva più sto scherzo....

credendolo "risolto" sono stato a lavorare su altre cose del programma e ad un tratto ha iniziato a ridare lo stesso problema!

sizeof(int) ritorna sempre 4, mentre il pid può essere anche più di 4 caratteri
Devi convertire il pid ad intero in una stringa temporanea e misurarne la lunghezza.

come faccio a prestabilire la lunghezza massima di una stringa temporanea che possa contenere ogni possibile pid?

andbin
20-07-2007, 13:58
come faccio a prestabilire la lunghezza massima di una stringa temporanea che possa contenere ogni possibile pid?il tipo pid_t che io sappia è un typedef per int. Però non ho mai visto pid con valori altissimi e in effetti, ad esempio, il comando 'ps' mostra il pid con max 5 digit.
Dovrei andare a cercare della documentazione (per essere sicuro al 100%) ma ho la netta sensazione che più di 32767 non si possa avere per un pid.

trallallero
21-07-2007, 08:05
il tipo pid_t che io sappia è un typedef per int. Però non ho mai visto pid con valori altissimi e in effetti, ad esempio, il comando 'ps' mostra il pid con max 5 digit.
Dovrei andare a cercare della documentazione (per essere sicuro al 100%) ma ho la netta sensazione che più di 32767 non si possa avere per un pid.
se non sbaglio pid_t è unsigned int come tutti i <...>_t (time_t, size_t, etc) ma non ne sono sicuro al 100%

EDIT: confermo che la Borland lo typedeffa così:
typedef unsigned pid_t;

cionci
21-07-2007, 08:11
se non sbaglio pid_t è unsigned int come tutti i <...>_t (time_t, size_t, etc) ma non ne sono sicuro al 100%
Infatti direi che tanto per essere sicuri basta allocare un numero di byte pari a 12.
Poi scrivendo con sprintf l'intero nel buffer basta usare strlen per scoprirne la lunghezza effettiva da aggiungere al resto delle lunghezze.