fscanf 无法识别格式字符串 (

fscanf doesn't recognise delimeters defined in format string (

我正在尝试从文件中读取用户登录数据(用户名、密码、一些整数、安全答案)并将其存储在链表中。文件 validation.txt 保存所有用户的数据,其中每个用户都有自己的一行,以格式(无空格)保存该用户的所有字段:

user1_$_ password1 _$_42 _$_answer1

user2_$_ password2 _$_21 _$_answer2

各种字段将存储为包含链表的结构(名为 'user')的成员(每个结构还有一个成员“next”,指向列表中的下一个用户。

我尝试使用 fscanf 来解析每一行并将信息直接保存到结构中,但由于某种原因,fscanf 在到达 $ 时没有接收到它们,并将整行存储在“用户名”成员下,而不仅仅是字符串“user1”。我已经在线阅读了有关字符串格式的负载,但无法弄清楚。我试着在文件和格式字符串中添加空格,结果有很多不同,我真的不明白为什么它们是这样的。根据我在网上阅读的内容,应该读取字符串直到出现一个字符到达格式字符串中,然后跳过。这看起来很简单,但为什么行不通?

我的代码:

user *loadUsers(){

    user *Users, *currPtr;
    FILE *fp = fopen("validation.txt", "r");
    if(fp==NULL||feof(fp)!=0){
        return NULL;
    }
    
    Users = (user *)malloc(sizeof(user));
    currPtr = Users;
    fscanf(fp, "%s_$_%s_$_%d_$_%s\n", currPtr->username, currPtr->password, &(currPtr->randomNum), currPtr->secAns);
    while(feof(fp)==0){
        currPtr->next = (user *)malloc(sizeof(user));
        currPtr = currPtr->next;
        fscanf(fp, "%s_$_%s_$_%d_$_%s\n", currPtr->username, currPtr->password, &(currPtr->randomNum), currPtr->secAns);
    }
    return Users;
}

输出:

当我在调用此函数后遍历我的列表并仅打印每个结构的用户名成员时,我打印了整行 (username = user1_$_ password1 _$_42 _$_answer1 而不仅仅是 user1 ).有人知道这里发生了什么吗?

从不,曾经,在不检查 return 值的情况下调用 *scanf()

%s 匹配任何 non-whitespace 字符序列,即 fscanf() 保持匹配第一个 %s 并且甚至不会“看到”格式字符串中的以下下划线.

可以 使用 %[^_] 来匹配所有不是下划线的东西,但一般来说你最好阅读整行输入 fgets() 和然后使用各种字符串函数解析内存中的输入。 *scanf() 从格式错误的输入中恢复的能力相当有限。