我有一个字段,允许在我的文本文件中使用空格,那就是'citepage‘。fscanf是否可以读取制表符之间有空白的字段,然后在printf中显示它?城市网页正在获取时间戳数据。
示例.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);
}发布于 2014-01-29 08:25:42
fscanf不适合于基于制表符或换行符而不是空格来分隔事物,因为它将所有空格视为相同的空格--可以跳过和忽略这些空格。只要格式化字符串中有一个空格字符(不管是空格、制表符还是换行符,它们都做同样的事情),fscanf将读取并丢弃空格,直到找到一个非空格字符。因此,在您的示例中,当它在读取citacoes的%d之后到达\t时,它将跳过以下内容
输入中的\t \t,下一个要读取的字符将是2,因此它将从这里开始读取citepage。
现在,您可以在格式字符串中使用%*1[\t]来跳过单个制表符(而不是所有空格),但是这样做既混乱又容易出错。它也很容易被不正确的输入所混淆,这使得它几乎不可能为用户提供关于格式错误的输入的正确诊断。但如果你想这样做,用%*1[\t]替换格式字符串中的所有制表符,并删除所有空格,它应该可以工作。
一个更好的选择是将整个行读入缓冲区(使用fgets),然后使用strsep将其拆分到制表符上。
此外,您永远不应该使用feof --只有在您尝试读取文件末尾之后才会返回true。请始终检查fscanf或fgets调用的返回值。
发布于 2014-01-29 08:26:59
'\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();
} https://stackoverflow.com/questions/21419495
复制相似问题