我正在尝试学习如何从文本文件中的制表符分隔字段导入数据。这是我尝试从名为users.in
的外部文件中获取的示例:
1 joshmith mypwd John Smith Awesome Road 103
2 jane_doe strongpwd Jane Doe Lucky Street 201
3 august84 goodpwd August May Red Boulevard 24
这里是应该保留数据的结构......
typedef struct User
{
int id;
char username[20];
char password[40];
char firstname[20];
char lastname[20];
char address[120];
} User;
...当然还有应该处理操作的代码:
User *u = (User *)malloc(sizeof(User)*4);
int i = 0;
while (6 == fscanf(data_file, "%d\t%[^\t]\t%[^\t]\t%[^\t]\t%[^\t]\t%[^\t]\n", &(u+i)->id, (u+i)->username, (u+i)->password, (u+i)->firstname, (u+i)->lastname, (u+i)->address))
{
fprintf(stdout, "%d %s %s %s %s %s\n", (u+i)->id, (u+i)->username, (u+i)->password, (u+i)->firstname, (u+i)->lastname, (u+i)->address);
i++;
}
循环设法完成第一次迭代......然后停止。这是输出:
1 joshmith mypwd John Smith Awesome Road 103
2
任何人都可以帮我弄清楚为什么会这样?导入此类格式化数据的正确方法是什么?
答案 0 :(得分:1)
我会使用fgets将每行读入字符串,然后使用strtok和\t
作为分隔符来提取标记;可以使用atoi将每行中的第一个标记转换为数字。
注意:使用atoi()
表示无效的号码将作为zaero值返回,因此您无法在没有额外逻辑的情况下区分这些号码
答案 1 :(得分:0)
您的格式字符串问题在于您使用的最后一个扫描设置为%[^\t]
,而最有可能以\n
结尾,但当然可能是因为它以\t
。如果确定它以\n
结尾,那么只需更改最后一个就足够了:
"%d\t%[^\t]\t%[^\t]\t%[^\t]\t%[^\t]\t%[^\n]\n"
// changed this ^ from t to n
如果它也可能是\t
,那么您可以使用以下内容:
"%d\t%[^\t]\t%[^\t]\t%[^\t]\t%[^\t]\t%[^\n\t]%*[\n\t]"
// %[^\n\t] discards and assigns whatever found until a '\t' or '\n' is encountered
// %*[\n\t] discards and only discards '\n's and '\t's
// ... until something else is encountered
作为附加信息,格式字符串中的空格' '
与任何空格字符中的零个或多个匹配,并丢弃它们。它基本上就像%*[ \t\n]
告诉-scanf
:匹配任何({1}},' '
和'\t'
,直到您遇到其他内容丢弃它们。