如何扫描逗号,但是没有分配给结构的逗号? C

我想扫描输入如:“John,Surname,9999”并且不应将逗号分配给扫描变量; 最后的空格和输入的开始被删除… 现在以p-> name的forms构造student_t,将使用此逗号分配“John”,而不是“John”。 如何以用户在输入示例中插入逗号的方式执行此操作,但是它未分配给p-> name? 我甚至不知道如何用言语掩盖我的观点。 我现在正用这个锤击我大约50个小时。

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); } 

示例输入:

 Name, Surname, 9999 

输出到这个例子:

 Name Surname, 9999 

相反,我的输出是这样的:

 Name, , 0 

所以用户输入的第一个“逗号”被分配给p-> name,而空白是p-> surname,第二个逗号可能是p-> index,它是’int’类型,也许这就是为什么它是0.如果我这样做的话:

 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); 

输出是:

 ame, Surname,, 9999 

edit1:我衷心感谢所有人。 现在,我没有提到我也想要处理错误,尽管它可能会更加轻松,无论方法决定。

* err_code =

0 – 所有内容都正确加载到结构中
1 – 出了问题,例如。 用户在输入格式时没有使用逗号:'[Name],[Surname],[index]’
2 – 仅正确加载名称
3 – 正确加载名称和姓氏(索引出错)

鉴于此,我认为使用scanf处理这些错误会很成问题。
在主题中我使用了“如何扫描”,因为我不知道如何正确地表达从用户到结构的扫描数据。
现在,按照Stephan Lechner的智慧,我以某种方式参与这种方法:

 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有几个缺陷,特别是当使用它来使用单个语句/格式字符串扫描几个单独的输入字段时。 例如,新行字符被视为空白,就像空白一样,当读取多行时,这可以获得奇怪的结果。 此外,您可能希望保护您的代码不被“太长”的用户输入破坏; 所以你要编写"%19s ..." ,但输入的其余部分将被传递给下一个格式说明符……

这些陷阱让人们倾向于说“使用fgets并自己解析输入,例如使用strtok 。代码变得更长”,但你可以更好地控制边缘情况。

使用这种方法查看以下代码:

 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; } 

您可以指定匹配除逗号之外的所有内容:

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

现在我有struct student_t的声明(和一杯酒!)

它应该是

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

然后检查c是否为3