fscanf上的读取空间

fscanf上的读取空间,c,scanf,C,Scanf,我的文本文件中有一个允许空白的字段,即“citepage”。fscanf是否可以读取选项卡之间带有空格的字段,然后在printf中显示?citepage正在获取时间戳的数据 example.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]20

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

example.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);   
}
fscanf不适合基于制表符或换行符而不是空格来分隔内容,因为它将所有空格视为相同的内容,可以跳过或忽略这些内容。每当你的格式字符串中有一个空白字符时,不管它是空格、制表符还是换行符;它们都做同样的事情,fscanf将读取并丢弃空白,直到找到一个非空白字符。因此,在您的情况下,当它到达读取citacoes的%d之后的\t时,它将跳过输入中的以下\t\t,下一个要读取的字符将是2,因此它将开始读取citepage

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

更好的选择是使用fgets将整行读入缓冲区,然后使用strep在制表符上将其拆分

此外,您永远不应该使用feof-它不会返回true,直到您尝试读取文件末尾之后才返回true。请始终检查fscanf或fgets调用的返回值。

“\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();
} 
STREP是便携式的吗?