【问题标题】:Read space on fscanf读取 fscanf 上的空间
【发布时间】:2014-01-29 00:02:11
【问题描述】:

我的文本文件中有一个允许空格的字段,即“citepage”。 fscanf 是否可以读取选项卡之间有空格的字段,然后在 printf 中显示? citepage 正在获取时间戳数据。

示例.txt:

1[tab]AAAI[tab]Low-cost Outdoor Robot Platform for the Penn State Abington Mini Grand Challenge[tab]2005[tab]Robert Avanzato[tab]1[tab][espaco][tab]2013-03-07 16:49:1

我当前的代码:

while (!feof(fp)){
    fscanf(fp,"%d\t %19[^\t]\t %300[^\t]\t %d\t %100[^\t]\t %d\t %s\t %19[^\t]\n  ",&artigos.id,artigos.sigla,artigos.titulo,&artigos.ano,artigos.autores,&artigos.citacoes,artigos.citepage,artigos.timestamp);        
    printf("\nid: %d ",artigos.id);
    printf("\nsigla: %s ",artigos.sigla);
    printf("\ntitulo: %s ",artigos.titulo);
    printf("\nano: %d ",artigos.ano);
    printf("\nautores: %s ",artigos.autores);
    printf("\ncitacoes: %d ",artigos.citacoes);
    printf("\ncitepage: %s ",artigos.citepage);
    printf("\ntimestamp: %s ",artigos.timestamp);   
}

【问题讨论】:

    标签: c scanf


    【解决方案1】:

    fscanf 不适合基于制表符或换行符而不是空格来分隔内容,因为它将所有空格视为相同 - 可以跳过和忽略的内容。每当您的格式字符串中有空格字符时(不管它是空格、制表符还是换行符;它们都做同样的事情), fscanf 将读取并丢弃空格,直到找到非空格字符。因此,在您的情况下,当它在读取citacoes%d 之后到达\t 时,它将跳过输入中的以下
    \t \t,并且要读取的下一个字符将是@ 987654326@,因此它将从那里开始读取citepage

    现在您可以在格式字符串中使用%*1[\t] 来跳过单个制表符(而不是所有空格),但这样做很麻烦且容易出错。它也很容易被不正确的输入混淆,使得几乎不可能为用户提供有关格式错误的输入的正确诊断。但是,如果您想这样做,请将格式字符串中的所有制表符替换为 %*1[\t] 并删除所有空格,它应该可以工作。

    更好的选择是将整行读入缓冲区(使用 fgets),然后使用strsep 将其拆分为制表符。

    你也不应该使用feof——直到你尝试读取文件末尾但失败后它才会返回true。始终检查 fscanf 或 fgets 调用的返回值。

    【讨论】:

    • strsep 便携吗?
    【解决方案2】:

    '\t'' ' 指令做同样的事情:跳过任何空白。要在scanf() 中使用制表符作为分隔符,需要使用"%*1[\t]"strtok() 或简单的循环可能更容易。见@Chris Dodd

    建议fgets()/sscanf() 更好地处理错误,尤其是针对这种复杂的扫描。
    此外,artigos.citepage 的格式说明符需要调整。

    char buf[200];
    if (fgets(buf, sizeof buf, fp) == NULL) Handle_EOFIOError();
    
    // scan, but do not save 1 `\t`
    #define TF   "*1[\t]"
    if (8 == sscanf(buf,
        "%d"        TF "%19[^\t]" TF "%300[^\t]" TF "%d" TF
        "%100[^\t]" TF "%d"       TF "%19[^\t]"  TF "%19[^\t]",
        &artigos.id, artigos.sigla, artigos.titulo, &artigos.ano, 
        artigos.autores, &artigos.citacoes, artigos.citepage, artigos.timestamp) {
      Success();
    } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-26
      • 2021-05-03
      • 2018-03-21
      • 2015-07-20
      • 2010-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多