在C中将字符串解析为typedef结构

时间:2013-08-01 05:18:27

标签: c debugging parsing

如何将包含字符和数字的文件中的字符串解析为typedef结构。

这两行是需要解析的数据示例:

Pebbles Flintstone4Female
Bam-Bam Rubble3Male

首先是姓名,然后是空格,然后是姓氏,然后是年龄和性别。

姓名,姓氏,年龄和性别是typedef的一部分,需要存储。

总共有七个字符串,如上面那两个存储在.txt文件中的字符串。

如何编写正确的缓冲区来分隔字符串?

这是我到目前为止所得到的

sscanf(buffer, "%[^ ]%*[^1234567890]%d%s", buff_name, buff_surname, buff_age, buff_gender);

但它似乎无法正常工作,我无法访问有关它的任何信息。

1 个答案:

答案 0 :(得分:3)

  1. 始终检查sscanf()及其亲属的返回值。
  2. 启用编译器警告。一个好的编译器会告诉你下一个问题:
  3. 如果您希望阅读姓氏,请勿使用*中的%*[0-9]取消分配。
  4. 请注意,您的sscanf()行不使用您提及的数据结构。但是,此示例代码确实:

    #include <stdio.h>
    
    typedef struct who
    {
        char name[20];
        char surname[20];
        int  age;
        char gender[7];
    } who;
    
    int main(void)
    {
        const char *data[2] = 
        {
            "Pebbles Flintstone4Female",
            "Bam-Bam Rubble3Male",
        };
        const char *fmt[2] =
        {
            "%[^ ]%*[^1234567890]%d%s",
            "%[^ ]%[^1234567890]%d%s",
        };
    
        for (int i = 0; i < 2; i++)
        {
            for (int j = 0; j < 2; j++)
            {
                who buff;
                int n;
                if ((n = sscanf(data[j], fmt[i], buff.name, buff.surname, &buff.age, buff.gender)) != 4)
                    printf("Oops: format \"%s\", n = %d: %s\n", fmt[i], n, data[j]);
                else
                    printf("Format \"%s\": data %s: %s %s %d %s\n",
                           fmt[i], data[j], buff.name, buff.surname, buff.age, buff.gender);
            }
        }
        return 0;
    }
    

    示例输出:

    Oops: format "%[^ ]%*[^1234567890]%d%s", n = 3: Pebbles Flintstone4Female
    Oops: format "%[^ ]%*[^1234567890]%d%s", n = 3: Bam-Bam Rubble3Male
    Format "%[^ ]%[^1234567890]%d%s": data Pebbles Flintstone4Female: Pebbles  Flintstone 4 Female
    Format "%[^ ]%[^1234567890]%d%s": data Bam-Bam Rubble3Male: Bam-Bam  Rubble 3 Male
    

    如果使用sscanf()格式的字符串文字进行编译,GCC会警告您这个问题:

    td.c: In function ‘main’:
    td.c:23: warning: format ‘%d’ expects type ‘int *’, but argument 4 has type ‘char *’
    td.c:23: warning: format ‘%s’ expects type ‘char *’, but argument 5 has type ‘int *’
    td.c:23: warning: too many arguments for format
    

    上面的代码使用不同的格式字符串无法给出警告。

    应修改格式字符串以避免缓冲区溢出:

    "%19[^ ] %19[^0-9] %d %6s"