创建scanf以格式化文本文件

创建scanf以格式化文本文件,c,regex,scanf,C,Regex,Scanf,我必须格式化一行,如下所示: <Ana Baldwin> gpa 3.71 <Modesto Adventist Academy> SAT math 553 SAT reading 766 Ana Baldwin 3.71 Modesto Adventist Academy 553 766 到目前为止,我的代码是: int main(void) { int matchcoun

我必须格式化一行,如下所示:

<Ana Baldwin>        gpa    3.71      <Modesto Adventist Academy>       SAT math  553     SAT reading  766
Ana Baldwin   3.71   Modesto Adventist Academy      553    766
到目前为止,我的代码是:

int main(void)
{
    int     matchcount;
    char    name[20], GPA[6], school[30], SATmath[10], SATreading[10];

    char    dontcareGPA, dontcareSATmath, dontcareSATreading;
    char    dontcare1, dontcare3;
    char    dontcare2[40], dontcare4[40];

    matchcount = scanf ("%[^<]%c%[^>]%c%c%[^<]%c%[^>]%c%[^0-9]%[0-9]%c%[^0-9]%[0-9] ",
                                  &dontcare1,
                                  &name[0], &dontcare2[0], &dontcareGPA,
                                  &GPA[0], &dontcare3,
                                  &school[0], &dontcare4[0], &dontcareSATmath,
                                  &SATmath[0], &dontcareSATreading,
                                  &SATreading[0]);
    while  ((matchcount != 0) && (matchcount != EOF))
    {
        printf ("%-20.20s %-6.6s %-30.30s %-10.10s %-10.10s\n", name, GPA, school, SATmath, SATreading);

        matchcount = scanf ("%[^<]%c%[^>]%c%c%[^<]%c%[^>]%c%[^0-9]%[0-9]%c%[^0-9]%[0-9] ",
                                      &dontcare1,
                                      &name[0], &dontcare2[0], &dontcaregpa,
                                      &GPA[0], &dontcare3,
                                      &school[0], &dontcare4[0], &dontcareSATmath,
                                      &SATmath[0], &dontcareSATreading,
                                      &SATreading[0]);
    }

    return 0;
}
int main(无效)
{
整数匹配计数;
字符名称[20]、GPA[6]、学校[30]、SATmath[10]、SATreading[10];
char dontcareGPA、dontcarestmath、dontcarestrading;
char dontcare1,dontcare3;
char dontcare2[40],dontcare4[40];
matchcount=scanf(“%[^]%c%c%[^]%c%[^0-9][0-9]%c%[^0-9][0-9]”,
&dontcare1,
&名称[0],&dontcare2[0],&dontcareGPA,
&GPA[0],&dontcare3,
&学校[0],&dontcare4[0],&Dontcarestmath,
&SATmath[0],&DontCaresTreading,
&卫星阅读[0];
而((匹配计数!=0)和(&(匹配计数!=EOF))
{
printf(“%-20.20s%-6.6s%-30.30s%-10.10s%-10.10s\n”,姓名、GPA、学校、SATmath、SATreading);
matchcount=scanf(“%[^]%c%c%[^]%c%[^0-9][0-9]%c%[^0-9][0-9]”,
&dontcare1,
&名称[0],&dontcare2[0],&dontcaregpa,
&GPA[0],&dontcare3,
&学校[0],&dontcare4[0],&Dontcarestmath,
&SATmath[0],&DontCaresTreading,
&卫星阅读[0];
}
返回0;
}

我在理解不同的scanf格式时遇到了最大的困难。

你有一些好主意,有些不太好。通过在格式字符串中使用
*
抑制相应的赋值,可以避免“不在乎”输入。或者,您可以精心设计格式字符串,使它们完全不需要

您目前有:

matchcount = scanf ("%[^<]%c%[^>]%c%c%[^<]%c%[^>]%c%[^0-9]%[0-9]%c%[^0-9]%[0-9] ",
                              &dontcare1,
                              &name[0], &dontcare2[0], &dontcareGPA,
                              &GPA[0], &dontcare3,
                              &school[0], &dontcare4[0], &dontcareSATmath,
                              &SATmath[0], &dontcareSATreading,
                              &SATreading[0]);
我已将字符串限制为小于变量声明大小的一个字符串

您的循环条件当前为:

while  ((matchcount != 0) && (matchcount != EOF))
它需要:

while (matchcount == 5)
几乎总是要测试您是否获得了预期数量的转换项。您确实希望避免
scanf()
语句的大量重复。我想你还没有学过结构,所以我想我应该写一个函数:

int get_info(char *name, char *GPA, char *school, char *SATmath, char *SATreading)
{
    return scanf(" <%19[^>]> gpa %5s <%29[^>]> SAT math %9[0-9] reading %9[0-9]",
                 name, GPA, school, SATmath, SATreading);
}

你的问题有点让人困惑,因为你的标题是文本文件,但你的代码使用了
printf()
/
scanf()
。从技术上讲,这并没有问题,但通常我们在处理文件时使用
f…()
系列

离开该部分,如果您不介意使用第二种方法,而不是使用
scanf()
,则可以按照以下步骤操作:

  • 使用读取输入
  • 使用适当的分隔符标记输入
  • 根据收到的令牌[有效或空],将令牌复制到存储变量。或者,您可以使用
    strtol()
    /
    strtod()
    转换为
    int
    /
    浮点值
    /
    双精度

  • 注意:在使用
    fgets()
    时,您应该采取一些预防措施来处理传输
    \n

    问题似乎很广泛,请询问您对格式字符串的具体疑问(例如,如何读取括号之间的字符串等)。我明白,在放入%[^]时,将读取到括号内。这是否会使用scanf?将它们读入一个字符,并在
    scanf
    调用中使用
    name
    而不是
    &name[0]
    。其他论点也是如此。这是一种风格选择,@RSahu。
    &strvar[0]
    表示法的优点是,每个参数都以
    &
    开头,
    [0]
    下标正确地避免了将
    字符**
    字符(*)[20]
    传递给
    scanf()
    ,而不是
    字符*
    。因此,它提供了一个简单的视觉检查:除了格式字符串之外,
    scanf()
    的所有参数前面是否都有一个
    &
    。是的,很好!不坏;错误因此,虽然我通常不会这样编写代码,但对于学习C的人来说,它有着明确的优点。@JonathanLeffler,我同意这是一种风格选择。感谢您添加额外的说明。我们正在使用终端读取文本文件。因此,在本例中,我的文件名是readappender.c,我将创建一个gcc-o readappender readappender.c,然后使用./readappenderint get_info(char *name, char *GPA, char *school, char *SATmath, char *SATreading) { return scanf(" <%19[^>]> gpa %5s <%29[^>]> SAT math %9[0-9] reading %9[0-9]", name, GPA, school, SATmath, SATreading); }
    while (get_info(name, GPA, school, SATmath, SATreading) == 5)
         printf(…);