如何通过电子邮件解决sscanf问题?

时间:2016-11-10 16:22:52

标签: c scanf

这是我的代码:

#include <stdio.h>

int main(int argc, char **argv)
{
    const char example[]="13902796D ; Josefa Moral Fidalgo ; someone@server.com ; 01/03/2001 ; 0 ; 1 ;";
    char DNI[10];
    char name[100];
    char email[100];
    char date[10];
    int gender;
    int uni;

    sscanf(example, "%[^;] ; %[^;] ; %[^;] ; %[^;] ; %d ; %d ; ",
        DNI, name, email, date, &gender, &uni);

    printf("DNI: %s\n", DNI);
    printf("Name: %s\n", name);
    printf("Email: %s\n", email);
    printf("Date: %s\n", date);
    printf("Gender: %d\n", gender);
    printf("Uni: %d\n", uni);
    return 0;
}

结果如下:

DNI: 13902796D
Name: Josefa Moral Fidalgo
Email:
Date: 01/03/2001
Gender: 0
Uni: 1

但我期待结果:

DNI: 13902796D
Name: Josefa Moral Fidalgo
Email: someone@server.com
Date: 01/03/2001
Gender: 0
Uni: 1

我是C的新手,但我无法在互联网上找到任何答案,也无法在Stackoverflow上找到答案,并检查一些书籍,但无法找到代码的原因

 sscanf(example, "%[^;] ; %[^;] ; %[^;] ; %[^;] ; %d ; %d ; ",
            DNI, name, email, date, &gender, &uni);

不起作用。谁能帮我?我无法使用sscanf之外的其他功能,这是我的教授想要在代码中使用的功能。

1 个答案:

答案 0 :(得分:3)

缓冲区溢出。

代码如何知道不会溢出DNI[]?只有DNI的地址已传递给sscanf()。由于OP的代码没有为输入提供足够的空间,DNI[]被覆盖导致未定义的行为(UB)。

sscanf(example, "%[^;] ... ", DNI, ....

相反,传递要读取的最大字符数, width 。 A 9将限制扫描最多9个字符。由于数组大小为10,因此将有足够的内存用于9个字符和附加的空字符。代码还需要使缓冲区更大以适应用户输入。

char DNI[10*2];
sscanf(example, "%19[^;] ... ", DNI, ....

但是整个扫描是对的吗? 一种简单的方法是使用" %n"记录扫描的偏移量。如果扫描到达"%n",则n会有新值。

int n = -1;
sscanf(example, "%9[^;] ;...  %n", DNI, ..., &n);

把它放在一起

int main(int argc, char **argv) {
    const char example[]="13902796D ; 1 ;";
    char DNI[10*2];
    int uni;

    int n = -1;
    sscanf(example, "%19[^;] ; %d ; %n", DNI, &uni, &n);
    if (n < 0) {
      puts("Fail");
    } else {
      printf("DNI: %s\n", DNI);
      printf("Uni: %d\n", uni);
    }
    return 0;
}

代码仍有问题,因为DNI[]可能"13902796D "(请注意尾随空格),但这是OP要处理的另一个问题。