Newsgroup: it.comp.lang.c
Titolo: Dov'è l'inghippo

 Anto'.
? certo che restituisce la stringa con il NULL finale. Il NULL č alla fine
della stringa. strtok scorre la stringa dall'inzio verso la fine, dunque la
stringa si restringe verso la fine ma il "tappo" (il NULL) resta sempre.
Comunque pui semplicemente usare il puntatore alla stringa (es. se p č un
puntatore ad una stringa di 4 caratteri *(p+4)=0 ).
LM

 Anto'.
strtok() restituisce la stringa con il NULL finale. Il NULL č quello alla
fine
della stringa che stai scorrendo (se non c'č č questo l'errore).
strtok() scorre la stringa dall'inzio verso la fine, dunque la
stringa si *restringe* verso la fine, ma il "tappo" (il NULL) resta sempre.
Comunque puoi semplicemente usare il puntatore alla stringa.
Esempio: se p č un puntatore ad un'area di memoria contenente 4 caratteri
(ma allocata con malloc(5) perchč ci *deve* essere il posto anche per il
tappo)
allora basta scrivere:
*(p+4)=NULL.
P.S: con occhio esperto sto pensando che il tuo programma sta divergendo
verso il caos
completo della memoria. Utilizzare i puntatori significa porsi nelle
probabili condizioni per
mandare in crash un programma. Utilizzarli da inesperti significa porsi
nella condizione
necessaria e sufficiente per mandare in crash il programma. Secondo me
conviene che ti
fai prima un bel ripasso. Poi mediti un pň su come utilizzare i puntatori
nel modo corretto
e quali sono i modi sicuri perchč il programma vada in crash. Dopo puoi
pensare a come
evitare che questo succeda, utilizzando un tipo di programmazione cosidetta
*difensiva*.
In generale poi ti consiglio di utilizzare un compilatore C++ anche per
compilare i tuoi sorgenti
(magari forzando la compilazione C++) perchč scopre molti piů errori. Le
modifiche sono poche.
Ti allego un esempio modificato e compilabile in C++ del programma postato
da te nel msg
"Repost corretto", che tra l'altro compila ma fa andare in crash il SO, sul
quale non mi sono
soffermato piů di tanto (sicuramente hai di nuovo pasticciato con i
puntatori).
P.S: Piccola chicca del tuo sorgente. A che dovrebbe servire l'istruzione:
p=strtok('\0',"&");
te lo sei chiesto prima di scriverla?
P.P.S: strncpy(listaV[i],p,strlen(p)); scusa ma il tappo???????????????????
LM
// --------- compilabile con compilatore C++ -------------
#include <cstdio>
#include <cstdlib>
#include <cstring>
void TokenInput(char *ptr_c);
using namespace std;
void main ()
{
 char *tok = "Mio &Tuo &Nostro &Vostro &Loro";
 TokenInput(tok);
}
void TokenInput(char *ptr_c)
{
  char *listaV[20];
  char *p;
  int i=0;
  p=strtok(ptr_c,"&");
  listaV[0]=(char*)malloc(strlen(p));
  if (!listaV[i])
     printf("\nMemoria esaurita per il primo campo.");
  else
  {
     strcpy(listaV[i],"");
     strncpy(listaV[i],p,strlen(p));
  }
  do
  {
     i++;
     p=strtok('\0',"&");
     listaV[i]=(char*)malloc(100);
     if (!listaV[i])
     {
 printf("\nMemoria esaurita per il campo n.: %d",i);
 break;
      }
      strcpy(listaV[i],"");
      strcpy(listaV[i],p);
      if(p) printf("\n%s\n",listaV[i]);
   } while(p);
}
--
----------
Lello Mele
c/o VTM VideoTecnica Mele
Via San Sebastiano, 22
84036 Sala Consilina (SA)
Cell.:0347/643.35.25
HOMEPAGE:
http://www.lellomele.supereva.it
eMAIL:
v...@libero.it
me...@programmazione.it
-------------
"Esistono due modi per elaborare il progetto di un software.
 Il primo consiste nel renderlo semplice al punto tale che non
 manifesti lacune evidenti. Il secondo consiste nel renderlo
 complicato al punto tale che non manifesti lacune evidenti.
 Il primo metodo e' di gran lunga piu' difficile." [C.A.R. Hoare]
LM

  se faccio printf("%s",lista[0]);
ma tra queste due righe c'e' anche strcpy( lista[0],p) ? Se no, non vedo
come possa funzionare.
e poi malloca strlen(p)+1 caratteri, ci devi mettere anche il \0 finale.
ciao
donCiccio

te lo sei chiesto prima di scriverla?
E' la seconda volta in poco tempo che mi capita di imbattermi in
questa stranezza del C++. Per qualche motivo che non comprendo si
e' deciso che *qualunque* costante numerica intera uguale a zero
puo', se richiesto dal contesto, essere considerata come il
un puntatore nullo a qualunque tipo. In particolare dire '\0'
e' un modo legale in C++ di dire NULL.
Secondo me questo grado di liberta' (poter scrivere
indifferentemente '\0', 0 o anche (7*3-21) per indicare il
puntatore nullo) e' inutile e dannoso. Ogni tanto qualcuno ci
casca (in particolare ho visto un spesso gente fare confusione
fra '\0', NULL e ""). In C++ e' ad esempio compilabile anche
   if (""=='\0') { ... }
Non so perche' non si e' voluta limitare la conversione implicita
solo al literal 0 oppure (meglio ancora) non si e' usata una parola
chiave specifica.
Andrea
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff

Ciao a tutti,
mi è capitato sotto mano un codice che dovrò andare a modificare, ma trovo
che vi sono degli errori...eppur funziona.
1) char *lista[10]
    strpcy (valore1, lista[0]);
    .....
   free(lista);
   strcpy (valoreX, lista[0]);
   ...
Stando alle mie nozioni di C, che sto rinfrescando, il codice in questione
non dovrebbe funzionare...e invece funziona perfettamente!!! come mai? dopo
aver fatto il free posso ancora referenziare l'array senza errori!
2) Supponiamo che ptr_c sia un puntatore ad una stringa che contiene dei
caratteri '&' da usare come separatore,
    se faccio:
 p=strtok (ptr_c, "&");
 lista[0]=(char *) malloc(strlen(p));
 se faccio printf("%s",lista[0]);
stampa la stringa prima del separatore e una serie di caratteri
incomprensibili ....
come mai?
Thanks,
P.S. Scusatemi se vi rompo con questioni che possono essere semplici, ma è
da un po' che non lavoro in C e mi hanno commissionato un lavoretto a
scadenze impossibili sul codice fatto da altri!!!!!!

 come mai?
Bho! evidentemente il SO ti ha assegnato un blocco di memoria fisicamente
precedente a quello contenente la stringa col separatore. In realtà il tuo
codice è sbagliato perchè hai cercato il token (e p punta alla parte di
stringa successiva al token) hai allocato memoria in lista[0] per contenere
la stringa a cui punta p, ma non hai ancora effettivamente copiato la
stringa da p a lista[0] con strcpy(lista[0], p), dunque p "contiene" quello
che era presente in memoria precedentemente (vedi prima risposta). Il SO ha
semplicemente messo a disposizione del tuo programma un blocco di memoria
grande quanto tu hai richiesto e si è segnato da qualche parte questa cosa
(la cancellerà quando userai free()), niente altro. Non ha neanche aggiunto
un carattere NULL alla fine dell'area di memoria allocata, cosa che farebbe
arrestare la printf() prima di stampare monnezza (in gergo, che poi monnezza
non è, ma sono altri dati della tua applicazione o di qualche altra, dati di
qualunque tipo, non solo stringhe; stampati come stringhe appaiono in forma
di monnezza).
LM
LM


ciao visto che sei stato così gentile, c'è un espediente rapido per
