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

我最难理解不同的 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]);

第一个格式项查找一个或多个非 <字符,但如果输入的第一个字符是 < ,匹配立即失败。如果<前有空格或其他字符,那么某些转换将起作用。然而,决定哪些数据包含哪些内容变得非常复杂。我认为第三个%c会读到一片空白;以下%[^>]会读到空白,gpa , <和学校名称到 > ,这与您的想法不太一样。

你真的需要这样的东西:

matchcount = scanf(" <%19[^>]> gpa %5s <%29[^>]> SAT math %9[0-9] reading %9[0-9]",
                   &name[0], &GPA[0], &school[0], &SATmath[0], &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);
}

封装scanf()语句,然后在循环条件中使用它:

while (get_info(name, GPA, school, SATmath, SATreading) == 5)
     printf(…);

关于创建 scanf 以格式化文本文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27957623/

相关文章:

Java正则表达式替换全部

c - Scanf 总是跳过第二行输入

c - 如何在 C 中清空标准输入/输出缓冲区

objective-c - 如何开始在 iOS 上使用 ARM?

c - 如何将指向结构的指针数组初始化为零

javascript - 在javascript中用正则表达式替换字符串中的数字

regex - 我需要一个地址匹配算法

c - 如何在C语言的main函数中使用包含scanf()的函数

c - ruby FFI : Pointer to an array of unsigned integer

c - 使用 2 个字符随机化 2D 数组?