¿Cómo escanear comas, pero con comas no asignadas a una estructura? do

Quiero una entrada de scanf como: “John, Apellidos, 9999″ y las comas no deben asignarse a la variable escaneada; los espacios al final y al inicio de la entrada se eliminaron … Ahora, para estructurar student_t en una forma de p-> nombre, se asignará “John”, con esta coma, en lugar de “John”. ¿Cómo hacerlo de manera que el usuario inserte una coma como en el ejemplo de entrada, pero no está asignado a p-> nombre? Ni siquiera sé cómo encerrar con palabras mi punto. Estoy golpeando mi cabeza con esto por cerca de 50 horas ahora.

struct student_t { char name[20]; char surname[40]; int index; }; struct student_t* read(struct student_t* p, int *err_code) { *err_code=0; printf("Please enter data in a format: '[Name], [Surname], [index]':\n"); int c=scanf("%s, %s, %i", &p->name, &p->surname, &p->index); return p; } void show(const struct student_t* p) { printf("%s %s, %i\n", p->name, p->surname, p->index); } 

ejemplo de entrada:

 Name, Surname, 9999 

salida a este ejemplo:

 Name Surname, 9999 

en cambio, mi salida es algo como:

 Name, , 0 

así que la primera “coma” escrita por el usuario se asigna a p-> nombre, y el espacio en blanco es p-> apellido, la segunda coma es probablemente p-> índice que es de tipo “int”, tal vez por eso es 0. Si lo hago :

 char comma1, comma2, space1, space2; int c=scanf("%c%s%c%s%c%i%c", &space1, &p->name, &comma1, &p->surname, &comma2, &p->index, &space2); 

la salida es:

 ame, Surname,, 9999 

edit1: Agradezco a todos desde el fondo de mi corazón. Ahora, no mencioné que también quiero manejar los errores, aunque podría arrojar más luz si el enfoque es para decidir.

* err_code =

0 – todo está cargado a la estructura correctamente
1 – algo salió mal, por ejemplo. el usuario no usó comas al escribir en formato: ‘[Nombre], [Apellido], [índice]’
2 – solo el nombre cargado correctamente
3 – nombre y apellidos cargados correctamente (el índice salió mal)

Teniendo en cuenta eso, creo que manejar estos errores utilizando scanf sería bastante problemático.
En el tema utilicé “cómo escanear” porque no sé cómo express correctamente los datos de escaneo del usuario a la estructura.
Ahora, siguiendo la sabiduría de Stephan Lechner, asisto a este enfoque de una manera:

 char buffer[1024], *pch1, *pch2; if (fgets(buffer,1024, stdin)) { pch1=strchr(buffer, ','); pch2=strrchr(buffer, ','); if (pch1!=pch2 && pch1!=NULL) { char *name = strtok(buffer,","); // returns pointer to the beginning of the token if (name) { //the place where "," is occured becomes a "NULL" character sscanf(name," %19s", p->name); // skip leading spaces char *surname = strtok(NULL,","); if (surname) { sscanf(surname," %39s", p->surname); // skip leading spaces char *index = strtok(NULL,","); if (index) { p->index = (int)strtol(index, NULL, 10); } //else *err_code=3; } //else *err_code=2; } } else *err_code=1; } 

scanf tiene varios escollos, especialmente cuando se usa para escanear varios campos de entrada separados usando una sola cadena de cadena / formato. Por ejemplo, el nuevo carácter de línea se trata como un espacio en blanco simplemente como un espacio en blanco, y esto puede lograr resultados extraños al leer en varias líneas. Además, probablemente querrá proteger su código para que no se rompa con una entrada de usuario “demasiado larga”; así que escribiría "%19s ..." , pero luego el rest de la entrada pasará al siguiente especificador de formato …

Estos escollos hacen que las personas tiendan a decir “use fgets y analice la entrada por su cuenta, por ejemplo, utilizando strtok . El código se vuelve” más largo “, pero tiene mucho más control sobre los casos de borde.

Vea el siguiente código utilizando este enfoque:

 int main() { struct student_t s; struct student_t *p = &s; char buffer[1000]; if (fgets(buffer,1000, stdin)) { char *name = strtok(buffer,","); if (name) { sscanf(name," %19s", p->name); // skip leading spaces char *surname = strtok(NULL,","); if (surname) { sscanf(surname," %39s", p->surname); // skip leading spaces char *index = strtok(NULL,","); if (index) { p->index = (int)strtol(index, NULL, 10); } } } } return 0; } 

Puede especificar que coincida con todo excepto comas :

 int c = scanf("%[^,], %[^,], %i", &p->name, &p->surname, &p->index); 

Ahora que tengo la statement de struct student_t (¡y una copa de vino!)

Debería ser

  int c = scanf("%19[^,], %39[^,], %i", p->name, p->surname, &p->index); 

Y luego verifica si c es 3