User inserts data in a format:" [NAME], [SURNAME], [INDEX] ". Errors codes:
0 -- everything is loaded to the structure properly
1 -- not loaded to structure properly (user did not use commas or p->name went wrong)
2 -- only name loaded properly
3 -- name and surname loaded properly (index went wrong)
struct student_t
{
char name[20];
char surname[40];
int index;
};
exapmples:
input: John, Deep
err_code: 2
input: John, Deep, 999
err_code: 0
input: NULL //(nothing)
err_code: 1
... so I'm unable to detect if user inserts for example: "John, Deep" (err 2) or "John, Deep, "(err 3) or "John, " (err 2),..(it results in err 1; or if everything is fine, err 0)
My attempts: //edit1: working version using this approach, further below this one.
char buffer[1024], *pch1, *pch2;
if (fgets(buffer,1024, stdin)!=NULL)
{
pch1=strchr(buffer, ',');
pch2=strrchr(buffer, ',');
if (pch1!=pch2 && pch1!=NULL) //detects if inserted are 2 different commas
{
char *name = strtok(buffer,","); // returns pointer to the beginning of the token
if (name) {//the place where "," occurs, 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; return NULL;} //only NAME and SURNAME correctly, INDEX is loaded wrong
} else {*err_code=2; return NULL;} //only NAME loaded correctly
}
} else if (pch1==pch2 && pch1!=NULL)
{//but if there is 1 comma, input may be like: "John, Deep" so name'd be ok
char *name = strtok(buffer,",");
if (name) {
sscanf(name," %19s", p->name);
char *surname = strtok(NULL,",");
if (surname) {
sscanf(surname," %39s", p->surname);
char *index = strtok(NULL,",");
if (index) {
p->index = (int)strtol(index, NULL, 10);
}else if (p->index==0||p->index==0||p->index==' ') {*err_code=2; return NULL;}
}
}
} else {*err_code=1; return NULL;} //if there were 0 commas, err_code=1
}
if (p==NULL || p->name==NULL)
{
*err_code=1;
return NULL;
}
if (p->surname && p->name==NULL)
{
*err_code=2;
return NULL;
}
//because the above "if" construction didn't work, I added another one here:
if (p->index==NULL || p->index==0) //so if input was "John, Deep" then p->index should be NULL?
{
*err_code=3;
return NULL;
}
//edit1: Okay, this code works for me, everything goes as enwisaged. However it is very messy, so I'll try to adopt and use answers in another versions...
char buffer[1024], *pch1, *pch2;
if (fgets(buffer,1024, stdin)!=NULL)
{
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," %39[^\t\n]", p->surname); // skip leading spaces
char *index = strtok(NULL,",");
if (index) {
p->index = (int)strtol(index, NULL, 10);
if (p->index==0) {*err_code=3; return NULL;}
} //else {*err_code=3; return NULL;} //only NAME and SURNAME correctly, INDEX is loaded wrong
} else {*err_code=2; return NULL;} //only NAME loaded correctly
}
} else 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," %39[^\t\n]", p->surname); // skip leading spaces
char *index = strtok(NULL,",");
if (index) {
p->index = (int)strtol(index, NULL, 10);
} else if (p->index==0||p->index==' ') {*err_code=2; return NULL;}
} else {*err_code=1; return NULL;}
} else {*err_code=2; return NULL;}
} else {*err_code=1; return NULL;}
}
if (p==NULL || p->name==NULL)
{
*err_code=1;
return NULL;
}
I have a feeling it could be done in a totally different way... I'll take all hints and answers to my heart and do my best to understand and learn them all.
//edit1: if my ugly code infuriated someone, I'd really be happy to do some gardener work and cut off some of these demonic bushes, to clean it a bit. I think some of if cases are not at all necessary for it to work...
PS. (It's a continuation of my previous problem where typed commas were assigned to structure: How to scanf commas, but with commas not assigned to a structure? C but in this topic there, I ask about doing it in a way that there'd be an information what user typed wrong)