【问题标题】:How to properly fetch data from tab separated fields in text file如何从文本文件中的制表符分隔字段中正确获取数据
【发布时间】:2014-06-18 10:44:47
【问题描述】:

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

谁能帮我弄清楚为什么会这样?导入此类格式化数据的正确方法是什么?

【问题讨论】:

  • @user3121023 是的!谢谢你!为什么格式化字符串开头有多余的空格?那是为了什么?
  • %d 本身不应该已经丢弃前面的空格吗?

标签: c file-io io


【解决方案1】:

我会使用fgets 将每一行读入一个字符串,然后使用strtok\t 作为分隔符来提取标记;每行中的第一个标记可以使用atoi 转换为数字。

注意:使用atoi() 表示无效数字将作为 zaero 值返回,因此如果没有额外的逻辑,您无法区分它们

【讨论】:

    【解决方案2】:

    您的格式字符串的问题是您使用的最后一个扫描集是%[^\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匹配任何(如果有)' ''\t''\n',直到遇到其他东西并丢弃它们。

    【讨论】:

      猜你喜欢
      • 2021-12-21
      • 2016-09-20
      • 1970-01-01
      • 1970-01-01
      • 2020-12-15
      • 2012-08-19
      • 1970-01-01
      • 2012-12-01
      • 2013-09-14
      相关资源
      最近更新 更多