我在使用fscanf将数据从文件加载到结构中时遇到问题

我在使用fscanf将数据从文件加载到结构中时遇到问题,c,scanf,C,Scanf,我在使用fscanf时遇到问题,如果有任何帮助,我将不胜感激。我试图从我控制的文件中读取。因为我知道格式,这就是我试图从文件中读取的内容 typedef struct { char *website; char *user; char *password; char *description; } Account; typedef struct Database Database; struct Database { int number_of_ac

我在使用fscanf时遇到问题,如果有任何帮助,我将不胜感激。我试图从我控制的文件中读取。因为我知道格式,这就是我试图从文件中读取的内容

typedef struct {
    char *website;
    char *user;
    char *password;
    char *description;
} Account;

typedef struct Database Database;

struct Database { 
    int number_of_acc;
    Account **accounts;
};



int 
load_database(Database *db, FILE *fp) {
    char website[MAX_BUFFER_SIZE], username[MAX_BUFFER_SIZE], password[MAX_BUFFER_SIZE];
    Account acc;

    if (db->number_of_acc == 0)
        db->accounts = malloc(5*sizeof(acc));

    while(fscanf(fp, "%s: %s, %s", website, username, password ) == 3) {

        if(db->number_of_acc > 5) 
            db->accounts = malloc(2*db->number_of_acc*sizeof(acc));

        acc.website = website;
        acc.user = username;
        acc.password = password;
        //acc.description = description;
        db->accounts = malloc(sizeof(acc));
        db->number_of_acc += 1;
    }

    return Success;
}
然而,当通过gdb时,fscanf没有返回3,因此while循环被忽略。这是输入文件

Reddit: Username, Password
非常感谢您就我的代码提供的任何建议和帮助。感谢您抽出时间。

将评论转换为答案

fscanf()出现问题

第二个
%s
最多读取一个空白字符;根据定义,下一个字符不是逗号。您可能需要使用一个(负)扫描集:
%[^,]
读取最多但不包括逗号。您应该通过为
%s
%[…]指定大小来避免缓冲区溢出-请参阅

内存管理问题 请注意,作为一个例子,您也有内存管理问题。您需要检查内存分配是否成功,第二个应该使用
realloc()
,而不是
malloc()
(以避免内存泄漏和丢失已输入的数据)。错误检查仍然省略-最好将
realloc()
的结果分配给一个新变量,以便在重新分配失败时不会丢失指向先前分配的指针

if (db->number_of_acc == 0)
{
    db->accounts = malloc(5*sizeof(acc));
    db->number_of_acc = 5;
}

您需要考虑关系运算符是否应该是<代码> > <代码> > <代码> > /代码> ./P> 此外,复制读取的数据的段落是虚假的:

acc.website = website;
acc.user = username;
acc.password = password;
//acc.description = description;
db->accounts = malloc(sizeof(acc));
db->number_of_acc += 1;
不显示结构定义,但如果它包含数组,则需要使用
strcpy()
,如果它包含指针,则需要使用
strdup()
或等效函数。您还需要分配给数组的正确元素,并将数据复制到分配的空间中

我不打算解决这个问题-这个问题在这个主题上是不完整的,因此不能得到明确的回答。表面上看,你有一系列的结构;您应该将新输入的数据复制到下一个可用的结构中。对于数组中已分配的结构数和正在使用的结构数(或下一个要使用的项的索引),需要使用单独的计数器

如果您仍然有问题,可以问一个新问题,但请阅读如何创建MCVE(-或MRE或现在使用的任何名称)或SSCCE()-以不同的名称创建相同的想法。

将注释转换为答案

fscanf()出现问题

第二个
%s
最多读取一个空白字符;根据定义,下一个字符不是逗号。您可能需要使用一个(负)扫描集:
%[^,]
读取最多但不包括逗号。您应该通过为
%s
%[…]指定大小来避免缓冲区溢出-请参阅

内存管理问题 请注意,作为一个例子,您也有内存管理问题。您需要检查内存分配是否成功,第二个应该使用
realloc()
,而不是
malloc()
(以避免内存泄漏和丢失已输入的数据)。错误检查仍然省略-最好将
realloc()
的结果分配给一个新变量,以便在重新分配失败时不会丢失指向先前分配的指针

if (db->number_of_acc == 0)
{
    db->accounts = malloc(5*sizeof(acc));
    db->number_of_acc = 5;
}

您需要考虑关系运算符是否应该是<代码> > <代码> > <代码> > /代码> ./P> 此外,复制读取的数据的段落是虚假的:

acc.website = website;
acc.user = username;
acc.password = password;
//acc.description = description;
db->accounts = malloc(sizeof(acc));
db->number_of_acc += 1;
不显示结构定义,但如果它包含数组,则需要使用
strcpy()
,如果它包含指针,则需要使用
strdup()
或等效函数。您还需要分配给数组的正确元素,并将数据复制到分配的空间中

我不打算解决这个问题-这个问题在这个主题上是不完整的,因此不能得到明确的回答。表面上看,你有一系列的结构;您应该将新输入的数据复制到下一个可用的结构中。对于数组中已分配的结构数和正在使用的结构数(或下一个要使用的项的索引),需要使用单独的计数器


如果您仍然有问题,可以问一个新问题,但请阅读如何创建MCVE(-或MRE或现在使用的任何名称)或SSCCE()-使用不同的名称创建相同的想法。

第二个
%s
最多读取一个空白字符;根据定义,下一个字符不是逗号。您可能需要使用一个(负)扫描集:
%[^,]
读取最多但不包括逗号。您应该通过为
%s
%[…]
指定大小来避免缓冲区溢出-请看,我不确定我是否遵循了您的意图:
如果(db->number\u of_acc==5)db->accounts=malloc(2*db->number\u of_acc*sizeof(acc))?@ryker多亏了Johnathan,我才解决了我的fscanf问题。如果账户数量超过5个,该代码行打算增加分配规模。我知道在5个帐户结构之后不会再这样做了,但我在那里进行了测试。@JonathanLeffler感谢您的评论,我已经修复了我的fscanf问题。有没有办法相信你的帮助?我已将我的评论复制到一个答案中,你可以接受。第二个
%s
最多可以读取一个空格字符;根据定义,下一个字符不是逗号。您可能需要使用一个(负)扫描集:
%[^,]
读取最多但不包括逗号。您应该通过为
%s
%[…]
指定大小来避免缓冲区溢出-请看,我不确定我是否遵循了您的意图:
如果(db->number\u of_acc==5)db->accounts=malloc(2*db->number\u of_acc*sizeof(acc))?@RYKER I hav