如何从文本文件中的选项卡分隔字段正确获取数据

时间:2014-06-18 10:44:48

标签: c file-io io

我正在尝试学习如何从文本文件中的制表符分隔字段导入数据。这是我尝试从名为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

任何人都可以帮我弄清楚为什么会这样?导入此类格式化数据的正确方法是什么?

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',直到您遇到其他内容丢弃它们。