这是我的代码:

#include <stdio.h>

int main(int argc, char **argv)
{
    const char example[]="13902796D ; Josefa Moral Fidalgo ; [email protected] ; 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: [email protected]
Date: 01/03/2001
Gender: 0
Uni: 1

我是C的新手,但是在Internet上也找不到任何答案,在Stackoverflow上也找不到这里,并查看了一些书,但找不到代码的原因
 sscanf(example, "%[^;] ; %[^;] ; %[^;] ; %[^;] ; %d ; %d ; ",
            DNI, name, email, date, &gender, &uni);

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

最佳答案

缓冲区溢出。

代码如何知道不过度填充DNI[]?仅DNI的地址被传递给sscanf()。由于OP的代码没有为输入提供足够的空间,因此DNI[]被覆盖,导致未定义行为(UB)。

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

而是传递要读取的最大字符数,即宽度。 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要处理的另一个问题。

08-27 03:40