我在使用 fscanf 将数据从文件加载到结构中时遇到问题
I am having trouble using fscanf to load data from a file into structs
我在使用 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
读到一个白色的space字符;根据定义,下一个字符不是逗号。您可能需要使用(负)扫描集:%[^,]
来阅读但不包括逗号。您应该通过为 %s
和 %[…]
指定大小来避免缓冲区溢出——参见 How to prevent scanf() causing a buffer overflow in C?
内存管理问题
请注意,作为 ryyker ,您也有内存管理问题。您需要检查您的内存分配是否成功,第二个应该使用 realloc()
,而不是 malloc()
(以避免内存泄漏和已输入数据的丢失)。仍然省略了错误检查 — 最好将 realloc()
的结果分配给一个新变量,这样如果重新分配失败,您就不会丢失指向先前分配的指针。
if (db->number_of_acc == 0)
{
db->accounts = malloc(5*sizeof(acc));
db->number_of_acc = 5;
}
和
if (db->number_of_acc >= db->number_of_acc)
{
db->accounts = realloc(db->accounts, 2*db->number_of_acc*sizeof(acc));
db->number_of_acc *= 2;
}
你需要考虑关系运算符应该是>=
还是>
.
另外,复制读取数据的段落是假的:
acc.website = website;
acc.user = username;
acc.password = password;
//acc.description = description;
db->accounts = malloc(sizeof(acc));
db->number_of_acc += 1;
你没有显示结构定义,但如果它包含数组,你需要使用 strcpy()
,如果它包含指针,你需要使用 strdup()
或等效函数。您还需要分配给数组的正确元素,并将数据复制到分配的 space.
我不打算解决这个问题——关于这个主题的问题不完整,因此无法明确回答。从表面上看,您有一系列结构;您应该将新输入的数据复制到下一个可用结构中。您需要单独的计数器来计算数组中已分配结构的数量和正在使用的数量(或者,等效地,下一个要使用的条目的索引)。
如果您仍有问题,请提出一个新问题,但请阅读有关如何创建 MCVE 的信息 (Minimal, Complete, Verifiable Example — or MRE or whatever name SO now uses) or an SSCCE (Short, Self-Contained, Correct Example) — 相同的想法,但名称不同。
我在使用 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
读到一个白色的space字符;根据定义,下一个字符不是逗号。您可能需要使用(负)扫描集:%[^,]
来阅读但不包括逗号。您应该通过为 %s
和 %[…]
指定大小来避免缓冲区溢出——参见 How to prevent scanf() causing a buffer overflow in C?
内存管理问题
请注意,作为 ryyker realloc()
,而不是 malloc()
(以避免内存泄漏和已输入数据的丢失)。仍然省略了错误检查 — 最好将 realloc()
的结果分配给一个新变量,这样如果重新分配失败,您就不会丢失指向先前分配的指针。
if (db->number_of_acc == 0)
{
db->accounts = malloc(5*sizeof(acc));
db->number_of_acc = 5;
}
和
if (db->number_of_acc >= db->number_of_acc)
{
db->accounts = realloc(db->accounts, 2*db->number_of_acc*sizeof(acc));
db->number_of_acc *= 2;
}
你需要考虑关系运算符应该是>=
还是>
.
另外,复制读取数据的段落是假的:
acc.website = website;
acc.user = username;
acc.password = password;
//acc.description = description;
db->accounts = malloc(sizeof(acc));
db->number_of_acc += 1;
你没有显示结构定义,但如果它包含数组,你需要使用 strcpy()
,如果它包含指针,你需要使用 strdup()
或等效函数。您还需要分配给数组的正确元素,并将数据复制到分配的 space.
我不打算解决这个问题——关于这个主题的问题不完整,因此无法明确回答。从表面上看,您有一系列结构;您应该将新输入的数据复制到下一个可用结构中。您需要单独的计数器来计算数组中已分配结构的数量和正在使用的数量(或者,等效地,下一个要使用的条目的索引)。
如果您仍有问题,请提出一个新问题,但请阅读有关如何创建 MCVE 的信息 (Minimal, Complete, Verifiable Example — or MRE or whatever name SO now uses) or an SSCCE (Short, Self-Contained, Correct Example) — 相同的想法,但名称不同。