Comment extraire des champs dans une chaîne séparée par des virgules à l’aide de sscanf et de scanset lorsque certains champs sont vides

Je suis capable d’extraire des champs au format séparé par des virgules à l’aide de sscanf (voir ci-dessous) si tous les champs sont remplis. Mais si un champ est vide, seul le champ vide est renseigné. Existe-t-il un moyen de continuer en ignorant le problème des champs vides afin que les champs suivants soient remplis?

#include  int main(int argc, char* argv[]) { char* s = "Apple,Pear,Potato,11"; char fruit1[10]; char fruit2[10]; char vegetable[10]; int size; int num = sscanf(s, "%20[^,],%20[^,],%20[^,],%d", fruit1, fruit2, vegetable, &size); if (num == 4) { printf("This record contains 4 items\n"); printf("first fruit: %s, second fruit: %s, vegetable: %s, size = %d\n", fruit1, fruit2, vegetable, size); } else { printf("This record does not contain 4 items\n"); } // but here it fails - blank vegetable char* t = "Plum,Orange,,12"; num = sscanf(t, "%20[^,],%20[^,],%20[^,],%d", fruit1, fruit2, vegetable, &size); if (num == 4) { printf("This record contains 4 items\n"); printf("first fruit: %s, second fruit: %s, vegetable: %s, size = %d\n", fruit1, fruit2, vegetable, size); } else { printf("This record does not contain 4 items\n"); } return 0; } /* Prints: This record contains 4 items first fruit: Apple, second fruit: Pear, vegetable: Potato, size = 11 This record does not contain 4 items */ 

Vous pouvez créer votre propre fonction d’parsing à l’aide de strchr . Notez que l’ scan remplace par \0 dans la chaîne d’origine. Par conséquent, si vous souhaitez créer un littéral de chaîne (en lecture seule), vous avez besoin d’un tampon intermédiaire:

 #include  #include  #include  char *scan(char **pp, char c) { char *s = *pp, *p; p = strchr(*pp, c); if (p) *p++ = '\0'; *pp = p; return s; } int main(void) { char s1[] = "Apple,Pear,Potato,11"; char s2[] = "Plum,Orange,,12"; char fruit1[10]; char fruit2[10]; char vegetable[10]; int size; char *p; p = s1; strcpy(fruit1, scan(&p, ',')); strcpy(fruit2, scan(&p, ',')); strcpy(vegetable, scan(&p, ',')); size = strtol(scan(&p, ','), NULL, 10); printf("first fruit: %s, second fruit: %s, vegetable: %s, size = %d\n", fruit1, fruit2, vegetable, size); p = s2; strcpy(fruit1, scan(&p, ',')); strcpy(fruit2, scan(&p, ',')); strcpy(vegetable, scan(&p, ',')); size = strtol(scan(&p, ','), NULL, 10); printf("first fruit: %s, second fruit: %s, vegetable: %s, size = %d\n", fruit1, fruit2, vegetable, size); return 0; } 

Vous pouvez simplifier votre code en utilisant des pointeurs:

 #include  #include  #include  char *scan(char **pp, char c) { char *s = *pp, *p; p = strchr(*pp, c); if (p) *p++ = '\0'; *pp = p; return s; } int main(void) { char s1[] = "Apple,Pear,Potato,11"; char s2[] = "Plum,Orange,,12"; char *v[4], *p; int i; p = s1; for (i = 0; i < 4; i++) v[i] = scan(&p, ','); printf("first fruit: %s, second fruit: %s, vegetable: %s, size = %d\n", v[0], v[1], v[2], atoi(v[3])); p = s2; for (i = 0; i < 4; i++) v[i] = scan(&p, ','); printf("first fruit: %s, second fruit: %s, vegetable: %s, size = %d\n", v[0], v[1], v[2], atoi(v[3])); return 0; } 

Évitez de le faire manuellement et utilisez strtok :

 char str[] = "Apple,Pear,Potato,11"; char* tokens = strtok (str,","); // iterate over tokens ... while (tokens != NULL) { printf ("%s\n",tokens); tokens = strtok (NULL, ","); } 

Modifier:

si vous devez conserver des champs vides, considérez la solution de cette autre discussion .