使用m中的mmap或fscanf读取文件

时间:2014-10-12 16:02:40

标签: c mmap scanf

我同时提出建议和意见

我有一个由整数组成的文件,例如

1 2
1 3
4 7
2 5
3 10 

现在,我想阅读它,但我能想到的每一种方法都有自己的问题。

使用mmap()函数,它返回一个字符串,但从中提取数字似乎非常痛苦,因为我不知道它们的长度,所以使用atoi()或经典Number-& #39; 0'似乎还不够。

另一方面,fscanf的使用直接给了我整数形式的数字,但我总是有终止问题。你怎么知道什么时候读完了?它会返回' \ 0'或者EOF还是其他什么?根据经验,在我看来,它的行为是随机的。使用一个计算文件行数的函数可能很有用,但这样做是否存在?

现在,给你。您更喜欢使用哪种方法?你将如何解决上述问题?

3 个答案:

答案 0 :(得分:2)

您可以使用strtol转换mmap() ped缓冲区中的数字以及您通过传统I / O读取的行数。我发现它非常方便(实际上,在大多数情况下比fscanf更方便)。如果你想在你的缓冲区中找到下一个换行符,小心(!)使用memchr是一种非常有效的方法。然后它可以为您提供传递给strtol的下一个指针。

如果你想要普遍性,你应该采取预防措施,不是每个文件都可以mmap() ped(例如管道)。因此,一个健壮的程序应该尝试mmap()该文件,如果失败,则回退到传统的I / O.

答案 1 :(得分:1)

具有ad-hoc解析器的

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是文件指针,而int1int2int类型的变量。