我同时提出建议和意见
我有一个由整数组成的文件,例如
1 2
1 3
4 7
2 5
3 10
现在,我想阅读它,但我能想到的每一种方法都有自己的问题。
使用mmap()函数,它返回一个字符串,但从中提取数字似乎非常痛苦,因为我不知道它们的长度,所以使用atoi()或经典Number-& #39; 0'似乎还不够。
另一方面,fscanf的使用直接给了我整数形式的数字,但我总是有终止问题。你怎么知道什么时候读完了?它会返回' \ 0'或者EOF还是其他什么?根据经验,在我看来,它的行为是随机的。使用一个计算文件行数的函数可能很有用,但这样做是否存在?
现在,给你。您更喜欢使用哪种方法?你将如何解决上述问题?
答案 0 :(得分:2)
您可以使用strtol
转换mmap()
ped缓冲区中的数字以及您通过传统I / O读取的行数。我发现它非常方便(实际上,在大多数情况下比fscanf
更方便)。如果你想在你的缓冲区中找到下一个换行符,小心(!)使用memchr
是一种非常有效的方法。然后它可以为您提供传递给strtol
的下一个指针。
如果你想要普遍性,你应该采取预防措施,不是每个文件都可以mmap()
ped(例如管道)。因此,一个健壮的程序应该尝试mmap()
该文件,如果失败,则回退到传统的I / O.
答案 1 :(得分:1)
mmap()
尽可能快,即使它不是非常灵活。下面将解析您提供的表单以及可能没有其他的文件,但如果它是机械生成的,则可能没问题:
char*p,*e,*x;
int m,n;
x=mmap(...); /* e=end of buffer; */
for(m=n=0,p=x;p<e;++p){
if(*p==' '){m=n;n=0;}
else if(*p=='\n'){emit(m,n);m=n=0;}
else{n*=10;n+=*p-'0';}}
更好的文件格式(二进制)仍然更快。
关于你的第二个问题:我怎么知道fscanf()何时处于EOF?。这就是feof(fp)
的作用。你想要这样的东西:
while(feof(fp)&&2==fscanf(fp,"%d %d\n",&m,&n))emit(m,n);
但要注意:这比上面的多慢,并且不太健壮。慢多少?在我2012年中期的MBA课程中,我将获得600mbps,而使用fscanf
我将很幸运获得10mbps。
答案 2 :(得分:1)
使用fscanf
非常简单。 fscanf
返回成功扫描的项目数。所以在你的情况下你可以使用:
while(fscanf(fp,"%d %d",&int1,&int2)==2)
{
// successfully scanned 2 integers
}
其中fp
是文件指针,而int1
和int2
是int
类型的变量。