Newsgroup: it.comp.lang.c
Titolo: Domanda semplice

Ciao
Premetto che ho utilizzato Visual Basic, e il C l'ho sto imparando ora.
Ammesso di avere una char : mela mela2 mela3
io con vb non avevo problemi a trovare il simbolo " ",  e quindi
spezzettare la stringa in 3 stringhette.
Ma con il C qual'é il comando per trovare in una stringa un determinato
simbolo? e che mi ridia la posizione del primo simbolo
che trova? In questo modo posso prendere la prima parola e inglobarla in
una stringhetta.
Grazie
Ciao


(PS: Il VB è una brutta bestia (parere personale ed OT) :-)

Dovresti però tener conto che in C le stringhe non sono definite dal
linguaggio, quindi o ricorri a char* oppure agli array di caratteri.
Detto questo hai a disposizione un header di libreria standard chiamato
string.h dove hai a disposizione funzioni come:
char* strcpy( char *string1, char* string2 ); // copia la stringa 2 in 1
int strlen(char * string); // lunghezza stringa
char* strncpy(char *string1, char* string2, int size_tn); // copia i primi
N caratteri in string1 di string2
char *strrchr(char *string, int c); // cerca l'ultima occorrenza del
carattere c in string
Distinti Saluti.
Francesco Agostino Fassi.
 

Se devo dividere token separati da ":" e ho alcuni token
vuoti, ad esempio
pippo:pluto::minnie
strtok fallisce con un bel core. C'e' qualcosa che mi sfugge?


 strtok fallisce con un bel core. C'e' qualcosa che mi sfugge?
strtok NON accetta tokens "vuoti".  Prova con questo sostituto:
----------------------Begin file: getdelim.c
/*------------------------------------------------------*
 | Author: Maurizio Loreti, aka MLO or (HAM) I3NOO      |
 | Work:   University of Padova - Department of Physics |
 |         Via F. Marzolo, 8 - 35131 PADOVA - Italy     |
 | Phone:  
+39 (049) 827-7216
   FAX: 
+39 (049) 827-7102
 |
 | EMail:  
lor...@padova.infn.it
                        |
 | WWW:    
http://wwwcdf.pd.infn.it/~loreti/mlo.html
    |
 *------------------------------------------------------*
 Successive calls to getDelim() get each the next "token"
 in the string to which "pStart" points; a token is here
 defined as the sequence from the first to the last
 non-whitespace character between the start of that string
 and one of the characters contained in "sep".
 getDelim will return a pointer to the first character of
 the token or NULL (if no token has been found); a zero
 byte is also stored after the end of the token (over the
 terminating character).  *pStart will moreover be updated,
 and will point where a search for the following token
 should start.
 "Null tokens", i.e. nothing or whitespace only between two
 separators, are allowed from getDelim; in these cases the
 returned function value points to the null string (to a
 zero byte).
 Usage example:
    char string[WHATEVER], sep[]=",;/", *pc, *pStart;
    ...
    pStart = string;
    while ((pc = getDelim(&pStart, sep)) != NULL) {
      printf("\"%s\"\n", pc);
    }
 $Id: getdelim.c,v 1.2 1999/09/17 06:14:19 loreti Exp $
 *------------------------------------------------------*/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
char *getDelim(char **, char *);
#ifdef TEST
#include <stdlib.h>
int main(                       /* Quick and dirty. Sorry. */
  int    argc,
  char **argv
){
  char string[128], sep[16], *pStart, *pc;
  for (;;) {
    printf("String ('\\' to exit) ? ");
    fgets(string, 128, stdin);
    if ((pc = strchr(string, '\n')) != 0) *pc = '\0';
    if (!strcmp(string, "\\")) exit(0);
    printf("Delims ? ");
    fgets(sep, 16, stdin);
    if ((pc = strchr(sep, '\n')) != 0) *pc = '\0';
    pStart=string;
    while ((pc = getDelim(&pStart, sep)) != NULL) {
      printf("\"%s\"\n", pc);
    }
    printf("- THE END -\n");
  }
}
#endif /* TEST */
char *getDelim(
  char **pStart,                /* Points to the start of the string */
  char  *sep                    /* Separator characters              */
){
  register char *retVal;
  register char *pc;
  register char *fb = NULL;
/**
 | - Checks pStart, *pStart and sep: they cannot be NULL;
 | - skips leading whitespace;
 | - if the string's trailing zero has been reached, returns NULL
 |   (for 'no more tokens').
**/
  if (!pStart  ||  !(retVal = *pStart)  ||  !sep)       return NULL;
  while (*retVal  &&  isspace((unsigned char) *retVal)) retVal++;
  if (!*(pc = retVal))                                  return NULL;
/**
 | - Scans the token up to its end, the trailing zero or a separator:
 |   takes a pointer to the first whitespace found after a non-whitespace
 |   character (fb);
 | - if a separator has been found, it is substituted by a '\0';
 | - if whitespace has been found after the end of the token, a '\0' is
 |   stored there too.
**/
  while (*pc) {
    if (isspace((unsigned char) *pc)) {
      if (!fb) fb = pc;
    } else {
      if (strchr(sep, *pc)) {
        *pc++ = '\0';
        break;
      }
      fb = NULL;
    }
    pc++;
  }
  if (fb) *fb = '\0';
  *pStart = pc;
  return retVal;
}
----------------------End file: getdelim.c
-- 
Maurizio Loreti                         
http://www.pd.infn.it/~loreti/mlo.html
Univ. of Padova, Dept. of Physics - Padova, Italy            
lor...@pd.infn.it

ti ringrazio Fox
ciao

Massimiliano wrote:

Il fatto che tu ottenga un SIGSEGV non dipende da strtok(),
ma probabilmente dal fatto che la stringa che e' stata dichiarata
come di seguito
   char* testStrP = "tok1:tok2:tok3::tok4";
oppure
   char testStr[] = "tok1:tok2:tok3::tok4";
Con questo tipo di dichiarazione, certi compilatori (gcc ad es.),
allocano una stringa non modificabile.
La strtok ha il brutto vizio di modificare la stringa che gli
viene data in pasto, se questa e' a sola lettura ...
Il programma riportato di seguito funziona perfettamente e, come
vedi, di porcheria ne e' stata messa in abbondanza.
Questo dimostra anche che non e' vero che la strtok() non accetta
campi vuoti: questi vengono allegramente skippati.
#include <string.h>
#include <stdio.h>
int main(void)
{
  char  testString[50] = "tok1:tok2:tok3;:;:;:;:;:tok4";
  char* tokP           = NULL;
  tokP = strtok(testString, ";:");
  while(NULL != tokP)
  {
     printf("%s\n", tokP);
     tokP = strtok(NULL, ":;");
  }
   return 0;
}
C:\>iao Angelo

 campi vuoti: questi vengono allegramente skippati.
Il tuo concetto di "accetta" e' differente dal mio.  Io vorrei che
venissero interpretati e non skippati, allegramente o meno (cosa che
infatti deve accadere secondo ISO/IEC 9899-1999 7.21.5.8).
-- 
Maurizio Loreti                         
http://www.pd.infn.it/~loreti/mlo.html
Univ. of Padova, Dept. of Physics - Padova, Italy            
lor...@pd.infn.it
Murphy's law: Anything that can go wr
/bin/fortune: segmentation fault - core dumped

 allocano una stringa non modificabile.
Si, ma nel secondo caso tu poi non accedi alla stringa non modificabile
bensì questa viene utilizzata solo per copiarne i caratteri nell'array.
EMG

Grazie
