我有一个字段允许我的文本文件中的空格是'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);
}
答案 0 :(得分:0)
fscanf
不适合基于制表符或换行符而不是空格来分隔内容,因为它将所有空格视为相同 - 要跳过和忽略的内容。每当你的格式字符串中有空白字符时(如果它是空格或制表符或换行符都无关紧要;它们都做同样的事情),fscanf会读取并丢弃空格,直到找到非空格字符。因此,在您的情况下,当\t
读取%d
之后到达citacoes
时,它将跳过输入中的以下
\t \t
,并且要读取的下一个字符为2
,因此它将开始为citepage
读取。
现在,您可以在格式字符串中使用%*1[\t]
来跳过单个制表符(而不是所有空格),但这样做很麻烦且容易出错。它也很容易被不正确的输入混淆,几乎不可能为用户提供有关格式错误输入的正确诊断。但是如果你想这样做,用%*1[\t]
替换格式字符串中的所有选项卡,并删除所有空格,它应该可以工作。
更好的选择是将整行读入缓冲区(使用fgets),然后使用strsep
将其拆分为制表符。
此外,您永远不应该使用feof
- 在 之后,您尝试读取文件末尾未成功后才会返回true。请务必检查fscanf或fgets调用的返回值。
答案 1 :(得分:0)
'\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();
}