Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1522735
  • 博文数量: 226
  • 博客积分: 3997
  • 博客等级: 少校
  • 技术积分: 2369
  • 用 户 组: 普通用户
  • 注册时间: 2010-06-19 17:26
个人简介

Never save something for a special occasion. Every day in your life is a special occasion.

文章分类

全部博文(226)

文章存档

2018年(5)

2017年(11)

2016年(1)

2015年(17)

2014年(14)

2013年(30)

2012年(5)

2011年(52)

2010年(107)

分类: C/C++

2010-08-01 18:02:22

scanf错误
 
相关: sscanf 
 
 
采用fscanf读串中的"特殊数字"

// ...

while(!feof(fp))
{
fscanf(fp, "%*[^www]www%d", &iv);
printf("%d ", iv);
}


一个文件内容是
fjkdwww100kfldwww2000fkdwww3000 fjdkljf10
显示 100 2000 3000 3000
另一个是
www1000wwwfrequenc200kkkfrequenc100fdf
死循环
 
有的文件读出来是正确的,有的文件却是死循环,什么原因?
 
 
see fscanf(2)
...
RETURN VALUE
  These functions return the number of input items successfully matched and assigned, which can be fewer than provided for, or even zero in the event of an early matching failure.
如果fscanf 返回0 意味未读取失败(即没有一个是matched 的), 那下次调用fscnf仍然是这个结果,因为fscanf遇到一个不matched的时候,它不会跳到下一个token,故死在那个里了(光标不能向前移了)。
光标永远不能向前称, fscanf就不能读出数据,故!eof(fp)永远为true。
可以说,没有对fscanf 的返回值进行处理是一种失误。
 
此漏洞的测试代码:
 
int i;
int count= 0
while(count < 10)
{
  scanf("%d", &i);
  printf("%d ", i);
  count++;
}
print("\n");
 
运行时输入:
1 2 a 4 5 6 7 8 9 0 
输出是
1 2 2 2 2 2 2 2 2 2
 
 
可以检查和设置文件指针以避免死循环。
代码如下:

while(!feof(fp))
{
 pos=ftell(fp);
 cntGet = fscanf(fp, "%*[^www]www%d", &iv);
 if(cntGet == 0)
  puts("读取失败");
#if 1
 if(pos==ftell(fp))
  fseek(fp,1,1);
 else
  printf("iv %d\n", iv);
#endif
}


测试数据1:
www1000wwwfrequenc200kkkfrequenc333fdf
结果1:
读取失败          
读取失败
读取失败
读取失败
iv -858993460
读取失败
iv -858993460
Press any key to continue
------ 第一个失败?
 
测试数据2:
Twww1000wwwfrequenc200kkkfrequenc333fdf
结果2:
iv 1000
读取失败
读取失败
读取失败
读取失败
iv 1000
Press any key to continue

------ 最后似乎也成功了?
 
测试平台:
VC6.0
 
结论:
疑惑中...
 
 
阅读(1086) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~