如何扫描逗号,但未将逗号分配给结构?C

如何扫描逗号,但未将逗号分配给结构?C,c,C,我想扫描输入,比如:“John,姓氏,9999”和逗号不应该分配给扫描的变量;已删除输入末尾和开头的空格。。。 现在,如果要将学生\u t构造为p->name的形状,将使用此逗号而不是“John”指定为“John”。如何让用户像输入示例中那样插入逗号,但不将其指定给p->name? 我甚至不知道如何用语言表达我的观点。我用这个敲了我的头大约50个小时了 struct student_t { char name[20]; char surname[40]; int inde

我想扫描输入,比如:“John,姓氏,9999”和逗号不应该分配给扫描的变量;已删除输入末尾和开头的空格。。。 现在,如果要将学生\u t构造为p->name的形状,将使用此逗号而不是“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->姓氏,第二个逗号可能是p->index,它是“int”类型,可能这就是为什么它是0。 如果我这样做:

输出为:

ame, Surname,, 9999
编辑1: 我衷心感谢每一个人。现在,我并没有提到我也希望处理错误,尽管这可能会让我们更清楚地知道该方法是否适用于决策

*错误代码=

0——所有内容都正确加载到结构中
1--出现问题,例如,用户在输入格式时未使用逗号:“[姓名],[姓氏],[索引]”
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;
}

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

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

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

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

现在我有了
struct student\u t
的声明(还有一杯葡萄酒!)

应该是

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

然后检查
c
是否为3

现在我有了
struct student\u t
的声明(还有一杯葡萄酒!)

应该是

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

然后检查
c
是否为3

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

scanf
有几个缺陷,尤其是在使用单个语句/格式字符串扫描多个分离的输入字段时。例如,新行字符被视为空白,在多行读取时可能会产生奇怪的结果。此外,您可能希望保护您的code不会被“太长”的用户输入破坏;因此您需要编写
%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;
}

如果您不使用
scanf
,这将容易得多。请使用
fgets
strtok
struct student\u t
->请提供声明使用scanf优于其他方法的任何特殊原因?不,没有理由使用scanf优于其他方法。(我需要处理错误:0--一切正常,1--输入时出错,例如没有逗号,2--姓氏和索引加载错误,3--只有索引加载错误)。我使用scanf是因为我不知道其他方法(我认为fgets只用于文件)。谢谢你的帮助!如果您不使用
scanf
,这将容易得多。请使用
fgets
strtok
struct student\u t
->请提供声明使用scanf优于其他方法的任何特殊原因?不,没有理由使用scanf优于其他方法。(我需要处理错误:0--一切正常,1--输入时出错,例如没有逗号,2--姓氏和索引加载错误,3--只有索引加载错误)。我使用scanf是因为我不知道其他方法(我认为fgets只用于文件)。谢谢你的帮助!您可以使用
“%[^,],%[^,],%i”
跳过任何前导空格。
%[/code>需要指向字符的指针,但
&p->name
是指向字符数组的指针(在编辑问题之后)。您可以使用
“%[^,],%[^,],%i”
跳过任何前导空格。
%[
需要一个指向字符的指针,但
&p->name
是指向字符数组的指针(在对问题进行编辑之后)。如果为
名称
实际输入超过19个字符,则不会正确扫描输入。但是,如果为
名称
实际输入超过19个字符,则不会正确扫描输入。但是,如果输入是由多个字除以空白,例如Arnold,G.Deep,999?如果我理解,sscanf将姓:G.Deep下的内容放在p->姓中,但是在接近空白时停止?啊,使用sscanf(姓,“%39[^\t\n]”,p->姓);似乎改变了这一点;首先,我写道它没有,但我的代码中有一个混乱。下面是我进一步使用它的尝试。似乎有效。见鬼,是的,正式有效:如果输入是由多个单词除以空格组成的名称,例如Arnold