带结构的Fscan
我从包含3列(坐标id、x线和y线)的文本文件中读取。 所有值都用制表符(\t)隔开。当我尝试使用fscanf()生成列表时,它不会打印我的第一行,而会打印最后一行两次带结构的Fscan,c,scanf,singly-linked-list,C,Scanf,Singly Linked List,我从包含3列(坐标id、x线和y线)的文本文件中读取。 所有值都用制表符(\t)隔开。当我尝试使用fscanf()生成列表时,它不会打印我的第一行,而会打印最后一行两次 while ((fgets(buffer, BUFFER_SIZE, fptr)) != NULL) { fscanf(fptr,"%d%f%f", &id, &xc, &yc); tempValue.xyID = id; tempValue.x = xc; tempVal
while ((fgets(buffer, BUFFER_SIZE, fptr)) != NULL)
{
fscanf(fptr,"%d%f%f", &id, &xc, &yc);
tempValue.xyID = id;
tempValue.x = xc;
tempValue.y = yc;
addToList(nodeID++, tempValue);
}
printList();
上面的代码不适用于scanf,但当我这样做时:
while ((fgets(buffer, BUFFER_SIZE, fptr)) != NULL)
{
tempValue.xyID = atoi(strtok(buffer,"\t"));
tempValue.x = atoi(strtok(NULL, "\t"));
tempValue.y = atoi(strtok(NULL, "\t"));
addToList(nodeID++, tempValue);
}
printList();
上面的代码工作得很好,我想知道我在fscanf上做错了什么。谢谢 如果使用fgets()
将文件中的一行读取到内存中,则需要使用sscanf(buffer…)
扫描该行。如果调用fscanf(fptr,…)
,基本上就是丢弃刚才读取的行,并从文件中读取下一位数据
您看到最后一行两次的原因很可能是因为在您已经到达文件末尾时调用了fscanf()
。如果无法读取任何数据,则传递给fscanf()
的变量将不会被覆盖。您没有检查fscanf()
的返回值以确保实际读取新数据,而是始终调用addToList()
,然后它将使用上一次调用fscanf()
存储的值向列表中添加项
您的第二次尝试是有效的,因为您现在实际上正在解析读入缓冲区的数据。请注意,您没有再次检查所调用函数的所有返回值是否存在错误。如果您试图读取一个包含少于三个项目的行的文件,那么您的第二个版本将崩溃,因为
strtok()
将返回NULL
,然后您实际上正在调用atoi(NULL)
。另外,atoi()
会自动忽略任何错误,例如当它试图解析的字符串不包含有效数字时,它将返回0。如果要确保正确解析了值,最好使用strtol()
。您忘记了fscanf调用中的\t
分隔符…fscanf(fptr、%d\t%f\t%f、&id、&xc、&yc),尝试了相同的方法:/请提供正确的答案,包括a)您给出的输入,b)您得到的输出以及id
,xc
,yc
和tempValue
的定义。感谢您的回复。但是为什么它仍然打印最后一行2次呢?如果调用了fscanf()
,但未能读取数据,它将返回一个错误值,但不会更改您尝试读取的变量。您忽略了返回值,只是打印了上一次调用fscanf()
的值。正如您所说,我用sscanf替换了fscanf。我不再在程序中使用fscanf了。确保还检查了sscanf()的返回值。
!