问题描述
我正在尝试从文件中读取用户登录数据(用户名,密码,一些整数,安全性答案)并将其存储在链接列表中。文件validation.txt保存所有用户的数据,其中每个用户都有一行自己的一行,以该格式(无空格)保存该用户的所有字段:
user1 _ $ _ password1 _ $ _ 42 _ $ _ answer1
user2 _ $ _ password2 _ $ _ 21 _ $ _ answer2
各个字段将作为包含链接列表的结构(名为“用户”)的成员存储(每个结构还具有一个成员“ 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,currPtr->secAns);
}
return Users;
}
输出:
当我在调用此函数后遍历列表并仅打印每个结构的用户名成员时,将打印整行(用户名= user1 _ $ _ password1 _ $ _ 42 _ $ _ answer1而不是仅user1)。有人知道这是怎么回事吗?
解决方法
从不 ever ,不检查返回值就调用*scanf()
。
%s
与任何非空白字符序列匹配,即fscanf()
始终与前%s
匹配,甚至在格式字符串中都没有“看到”下面的下划线。
您可以 使用%[^_]
来匹配所有内容而不是下划线,但通常来说,最好使用fgets()
阅读整行输入,然后将其解析为使用各种字符串函数存储。 *scanf()
在从格式错误的输入中恢复的能力相当有限。