logo 广告
Loading...
 导航 所在位置:论坛首页 -> ┈┋电脑网络┋┈ -> 图象媒体技术应用 -> 请问:怎么从某一确定的行开始读文件?
回复
标题:请问:怎么从某一确定的行开始读文件?收藏 编辑 删除 楼主 | 上一篇 下一篇
会飞的猪
头像
等级:
权限:贵宾
积分:-1119
金钱:-980
声望:-16
经验:-1254
发帖数:907
注册:2006年10月1日
资料 短消息2007-10-24 16:29:46

比如从第10行开始读?
谢谢 ◆

C里面不是有一个对文件进行移位的涵数吗?
如果再不行就要笨一点用fgets(), 因为这个涵数是每次读取一行.
你设的buffer要足够的大.

for(10次)
{

fgets(放入buffer);
清空buffer;


}




fgets 可以指定最大行长。 ◆

LZ提出的问题也是常见滴....看看还有那些伙们弄个运行时间短一点的方法....






QUOTE:原帖由 linuxcici 于 2007-4-7 09:54 发表
C里面不是有一个对文件进行移位的涵数吗?
如果再不行就要笨一点用fgets(), 因为这个涵数是每次读取一行.
你设的buffer要足够的大.

for(10次)
{

fgets(放入buffer);
清空buffer;


}




不如直接 getchar() 并判断,这样还可以省栈空间
那个检索函数不能判断行数。 ◆



QUOTE:原帖由 soul_of_moon 于 2007-4-7 10:17 发表

这位大哥.小弟菜嘛...

fgets()每次读入一行就会指向下一行. 所以把前面10行读进去了就清除. 然后下一次fgets()就是第十一行了.
你有更好的办法么? 请贴出来可以么? 嘻嘻~~






QUOTE:原帖由 linuxcici 于 2007-4-7 10:21 发表





这位大哥.小弟菜嘛...

fgets()每次读入一行就会指向下一行. 所以把前面10行读进去了就清除. 然后下一次fgets()就是第十一行了.
你有更好的办法么? 请贴出来可以么? 嘻嘻~~ fgets()怎么每次都是读一行?你怎么设定?






QUOTE:原帖由 soul_of_moon 于 2007-4-7 10:23 发表

fgets()怎么每次都是读一行?你怎么设定? 把fgets() 里的buffer设得足够大不就OK了? 我半年前做过是这样子的呢.
半年没有写过C代码和看书了,书还在学校......哎...那请问你是怎么搞的呢?






QUOTE:原帖由 linuxcici 于 2007-4-7 10:36 发表



把fgets() 里的buffer设得足够大不就OK了? 我半年前做过是这样子的呢.
半年没有写过C代码和看书了,书还在学校......哎...那请问你是怎么搞的呢? buffer设得足够大
------------------------
这不是好习惯





窃以为用getchar就不错了, 缓冲的事都有系统干了. ◆



QUOTE:原帖由 soul_of_moon 于 2007-4-7 11:03 发表

buffer设得足够大
------------------------
这不是好习惯 那请问大侠你说该怎么办?

还有位同志说用getch().本来就是读入一个字符....速度可以知道能多快






QUOTE:原帖由 linuxcici 于 2007-4-7 11:36 发表




那请问大侠你说该怎么办?

还有位同志说用getch().本来就是读入一个字符....速度可以知道能多快 是说 getchar() 吧,一般都是有缓冲的。getch() 不是 ANSI C 的库函数。 ◆



QUOTE:原帖由 bGFuZ3Vl 于 2007-4-7 11:44 发表


是说 getchar() 吧,一般都是有缓冲的。getch() 不是 ANSI C 的库函数。 你的意思是说用getchar来解决?






QUOTE:原帖由 linuxcici 于 2007-4-7 11:48 发表




你的意思是说用getchar来解决? fgetc()

-- ◆



QUOTE: The getchar() function is equivalent to getc() with the argument stdin.man 3 getchar

P.S. 个人认为这里 getc() 应该写成 fgetc()

OpenBSD

--

[ 本帖最后由 bGFuZ3Vl 于 2007-4-7 11:54 编辑 ] ◆



QUOTE:原帖由 bGFuZ3Vl 于 2007-4-7 11:53 发表


man 3 getchar

P.S. 个人认为这里 getc() 应该写成 fgetc()

OpenBSD

--

好。 找天有空试几行来看看运行速度。




缓冲区足够大是错的,足够大只能针对一个已知的文件,比如(如果你告诉我一行是一个名字,而且告诉我世界上最长的名字是20个字节)
否则没有足够大,只有更大。

肯定不能用fgets,要用还要判断是不是真的一行了,应该是fgetc,应该没有更好的方法。 ◆



QUOTE:原帖由 flw2 于 2007-4-7 12:21 发表
缓冲区足够大是错的,足够大只能针对一个已知的文件,比如(如果你告诉我一行是一个名字,而且告诉我世界上最长的名字是20个字节)
否则没有足够大,只有更大。

肯定不能用fgets,要用还要判断是不是真的一行 ... 那是啊。 我的只是判断一个已知的文件滴。 这位大哥你能100%确定是用你的方法么?




用fgetc是比较直观的方法。
但用fgets是比较快速的方法。

虽然标准C库有缓冲,但用fgetc毕竟会比fgets多N倍的函数调用,速度慢是正常的。

用fgets,设置大的buffer思路是错误的。
正确的做法应该是读取到buffer后,查找'\n'。每找到一次,标志着读取到了一行。







QUOTE:原帖由 assiss 于 2007-4-7 13:39 发表
用fgetc是比较直观的方法。
但用fgets是比较快速的方法。

虽然标准C库有缓冲,但用fgetc毕竟会比fgets多N倍的函数调用,速度慢是正常的。

用fgets,设置大的buffer思路是错误的。
正确的做法应该是读取到 ... 这位大哥每行是\n 啊? 但我有时读取的是什么LF之类的(line feed)






QUOTE:原帖由 linuxcici 于 2007-4-7 13:44 发表



这位大哥每行是\n 啊? 但我有时读取的是什么LF之类的(line feed) 有时候看你的头像就觉得恶心啊,提两点意见:
1、能不能换个头像?
2、能不能不要这么死板教条?谁告诉你一定、只能比较'\n'?查查strpbrk() 函数是干什么的。






QUOTE:原帖由 assiss 于 2007-4-7 13:50 发表

有时候看你的头像就觉得恶心啊,提两点意见:
1、能不能换个头像?
2、能不能不要这么死板教条?谁告诉你一定、只能比较'\n'?查查strpbrk() 函数是干什么的。 不喜欢看没人叫你留意我喔。。。。




晕~为一个 fgets 的细节讨论半天,至于嘛。

for i = 1 to 9:
while( fgets( buffer, sizeof(buffer), fp ) && buffer[strlen(buffer)-1] != '\n' );

// 现在就位于第十行开始处了。






QUOTE:原帖由 flw 于 2007-4-7 14:06 发表
晕~为一个 fgets 的细节讨论半天,至于嘛。

for i = 1 to 9:
while( fgets( buffer, sizeof(buffer), fp ) && buffer[strlen(buffer)-1] != '\n' );

// 现在就位于第十行开始处了。 版主是偶像,好厉害! ◆



QUOTE:原帖由 flw 于 2007-4-7 14:06 发表
晕~为一个 fgets 的细节讨论半天,至于嘛。

for i = 1 to 9:
while( fgets( buffer, sizeof(buffer), fp ) && buffer[strlen(buffer)-1] != '\n' );

// 现在就位于第十行开始处了。 还是市长姐姐牛呢。。。我已把你列入牛人名单了嘻嘻~~~






QUOTE:原帖由 flw 于 2007-4-7 14:06 发表
晕~为一个 fgets 的细节讨论半天,至于嘛。

for i = 1 to 9:
while( fgets( buffer, sizeof(buffer), fp ) && buffer[strlen(buffer)-1] != '\n' );

// 现在就位于第十行开始处了。 for (i=0; i<3; i++)
fgets( buffer, sizeof(buffer), fp);

这样好像也行,要判断那个回车干啥? ◆



QUOTE:原帖由 samuel1004 于 2007-4-7 14:36 发表


for (i=0; i<3; i++)
fgets( buffer, sizeof(buffer), fp);

这样好像也行,要判断那个回车干啥? flw,看到没?前面的细节讨论马上就显示出重要性来了。






QUOTE:原帖由 samuel1004 于 2007-4-7 14:36 发表


for (i=0; i<3; i++)
fgets( buffer, sizeof(buffer), fp);

这样好像也行,要判断那个回车干啥? 这位兄弟没看前几贴有人说。 你这样写那buffer要一定的大才行呢。
而且不能是动态滴。 小那个市长小姐写的while里面要不断的fgets()直到
遇到/n。目的是buffer可以任意value






QUOTE:原帖由 linuxcici 于 2007-4-7 14:40 发表




这位兄弟没看前几贴有人说。 你这样写那buffer要一定的大才行呢。
而且不能是动态滴。 小那个市长小姐写的while里面要不断的fgets()直到
遇到/n。目的是buffer可以任意value Thanks,市长姐姐 so 强啊。 ◆




QUOTE:原帖由 flw 于 2007-4-7 14:06 发表
晕~为一个 fgets 的细节讨论半天,至于嘛。

for i = 1 to 9:
while( fgets( buffer, sizeof(buffer), fp ) && buffer[strlen(buffer)-1] != '\n' );

// 现在就位于第十行开始处了。 挑个毛病,别介意。
strlen是个隐患






QUOTE:原帖由 soul_of_moon 于 2007-4-7 15:17 发表

挑个毛病,别介意。
strlen是个隐患 strlen("") -1 = -1?
呵呵,那应该特殊处理一下。






QUOTE:原帖由 flw 于 2007-4-7 15:19 发表

strlen("") -1 = -1?
呵呵,那应该特殊处理一下。 怎么怎么看不懂。。。。。?汗。。






QUOTE:原帖由 flw 于 2007-4-7 15:19 发表

strlen("") -1 = -1?
呵呵,那应该特殊处理一下。 刚试了一下,不会呀!
你说的隐患到底是指什么呢?






QUOTE:原帖由 flw 于 2007-4-7 15:26 发表

刚试了一下,不会呀!
你说的隐患到底是指什么呢? 文件里有0x00的字符




就是查找第N次'\n'的出现位置,具体使用哪个库函数我不好说,对这个没有研究.






QUOTE:原帖由 soul_of_moon 于 2007-4-7 15:27 发表

文件里有0x00的字符 哦,这种文件就不应该用 fgets 来读取了吧?

QUOTE:NAME
fgetc, fgets, getc, getchar, gets, ungetc - input of characters and strings







QUOTE:原帖由 flw 于 2007-4-7 15:31 发表

哦,这种文件就不应该用 fgets 来读取了吧?
这个就不一定了。像你如果要分析log文件,很有可能在log文件的某个地方存了个0x00






QUOTE:原帖由 soul_of_moon 于 2007-4-7 15:34 发表

这个就不一定了。像你如果要分析log文件,很有可能在log文件的某个地方存了个0x00 那是写 log 的人的问题
呵呵,有点强词夺理了。
其实我的意思是说,我写程序很注重“语义”。用合适的函数去做合适的事。
像 fgets,就没法读取中间包含有 '\0' 的行——它不是 fread,它返回的只能是字符串,而不是 byte 流。
既然用了 fgets,那么你就不应该说后续的 strlen 有问题了。






QUOTE:原帖由 flw 于 2007-4-7 15:39 发表

那是些 log 的人的问题
呵呵,有点强词夺理了。
其实我的意思是说,我写程序很注重“语义”。用合适的函数去做合适的事。
像 fgets,就没法读取中间包含有 '\0' 的行——它不是 fread,它返回的只能是字 ... 我只是举个例子。
因为以前写过一个测试程序,就因为文档改了,把'0'->NULL,结果导致我的测试程序老是down







QUOTE:原帖由 flw 于 2007-4-7 15:39 发表

那是写 log 的人的问题
呵呵,有点强词夺理了。
其实我的意思是说,我写程序很注重“语义”。用合适的函数去做合适的事。
像 fgets,就没法读取中间包含有 '\0' 的行——它不是 fread,它返回的只能是字 ... 市长姐。 那到底你写的能否正确呢?如果文中包含0x00的确是有可能。
fgets()读到0x00那里会停了? 应该是吧。 但多不影响吧。 最多是多了一次while.
啊。 你判断的是\n才结束啊。 应该没错吧?




flw好像不务正业哈
身为perl版的版主
我一般都在这个版看到她 ◆



QUOTE:原帖由 linuxcici 于 2007-4-7 15:54 发表

市长姐。 那到底你写的能否正确呢?如果文中包含0x00的确是有可能。
fgets()读到0x00那里会停了? 应该是吧。 但多不影响吧。 最多是多了一次while.
啊。 你判断的是\n才结束啊。 应该没错吧? fgets 在包含 '\0' 的时候不能正确工作(虽然它能读出一行,但是它无法告诉你它究竟读了几个字节)。
因此可能包含有 '\0' 时用 fgets 本来就是错误的选择。






QUOTE:原帖由 yecheng_110 于 2007-4-7 15:58 发表
flw好像不务正业哈
身为perl版的版主
我一般都在这个版看到她 我都说了flw是本版的老版主,感情深厚啊






QUOTE:原帖由 soul_of_moon 于 2007-4-7 16:04 发表

我都说了flw是本版的老版主,感情深厚啊 关键是 Perl 版的帖子太少,不够我看的。






QUOTE:原帖由 flw 于 2007-4-7 16:03 发表

fgets 在包含 '\0' 的时候不能正确工作(虽然它能读出一行,但是它无法告诉你它究竟读了几个字节)。
因此可能包含有 '\0' 时用 fgets 本来就是错误的选择。 abcdef\0ijk\n
sdfedfesse\n
.
.
.
如果用fgets() 怎么不行呢?遇到\0的话只会使while()多运行一次吧。但就不能用 && strlen...

&& buffer[strlen(buffer)-1]!='\n' || buffer[strlen(buffer)-1]=='\0')不就行了?

[ 本帖最后由 linuxcici 于 2007-4-7 16:17 编辑 ]




这个可以减少很多IO操作

CODE:
char *p,*pp;
stat st;
int fd;
stat("..",&st);
p =(char *)malloc(sizeof(char)*st.st_size);
fd = open("...",...);
read(fd,p,st.st_size);
int i = 1;
pp=strtok(p,"\n");
while( pp != NULL )
{
pp=strtok(NULL,"\n")
if( ++i == 10 )
{
.....
}
}
free(p);
close(fd); ◆



QUOTE:原帖由 C_C 于 2007-4-7 16:19 发表
这个可以减少很多IO操作

[code]
char *p,*pp;
stat st;
int fd;
stat("..",&st);
p =(char *)malloc(sizeof(char)*st.st_size);
fd = open("...",...);
read(fd,p,st.st_size) ... read 不行,得 fread。






QUOTE:原帖由 linuxcici 于 2007-4-7 16:14 发表




abcdef\0ijk\n
sdfedfesse\n
.
.
.
如果用fgets() 怎么不行呢?遇到\0的话只会使while()多运行一次吧。但就不能用 && strlen...

&& buffer[strlen(buffer)-1]!='\n' || buffer[ ... 第二次循环的话,就从第下一行开始了,fgets 会把 '\0' 连同它后面的东西都吃进来,但就是不告诉你它吃了多少。






QUOTE:原帖由 C_C 于 2007-4-7 16:19 发表
这个可以减少很多IO操作

[code]
char *p,*pp;
stat st;
int fd;
stat("..",&st);
p =(char *)malloc(sizeof(char)*st.st_size);
fd = open("...",...);
read(fd,p,st.st_size) ... 你也太狠了些吧。一下子全读进来?
那还不如用mmap呢。







QUOTE:原帖由 assiss 于 2007-4-7 16:21 发表

你也太狠了些吧。一下子全读进来?
那还不如用mmap呢。 一下子都读进来也不算很狠吧?一般的文本文件如配置文件之类的都没多大的,日志除外。
不过“那还不如用mmap”倒是真的。






QUOTE:原帖由 assiss 于 2007-4-7 16:21 发表

你也太狠了些吧。一下子全读进来?
那还不如用mmap呢。 这只是个例子,如果文件有一定格式的话可以分段读的 ◆



QUOTE:原帖由 C_C 于 2007-4-7 16:24 发表

这只是个例子,如果文件有一定格式的话可以分段读的 问题是你用 read 能保证全读进来吗?
我记得 read 是不保证的哦。






QUOTE:原帖由 flw 于 2007-4-7 16:20 发表

read 不行,得 fread。 为什么? ◆



QUOTE:原帖由 C_C 于 2007-4-7 16:25 发表

为什么? fread 是库缓冲的,如果读不到,那肯定是没有了。
read 是系统调用,有时候会没读完就返回,比如收到信号。






QUOTE:原帖由 flw 于 2007-4-7 16:27 发表

fread 是库缓冲的,如果读不到,那肯定是没有了。
read 是系统调用,有时候会没读完就返回,比如收到信号。 一直没注意这个问题,谢谢提醒 ◆



QUOTE:原帖由 C_C 于 2007-4-7 16:30 发表

一直没注意这个问题,谢谢提醒 搞网络编程的都知道,read/write 一般都要配合循环使用才保险的。普通的文件设备要比网络稳定得多,但是如果要符合 read 的语义,那么还是 while 一下比较好,因为 read 的 man 手册里没有提到一定会读取指定数量的字节。






QUOTE:原帖由 flw 于 2007-4-7 16:33 发表

搞网络编程的都知道,read/write 一般都要配合循环使用才保险的。普通的文件设备要比网络稳定得多,但是如果要符合 read 的语义,那么还是 while 一下比较好,因为 read 的 man 手册里没有提到一定会读取指定数 ... 在网络上我一直都用while,读文件我还真没想到


to > flw
《unix 高级环境编程》第4。2的说明在读常规文件时不会出现这个问题 ◆



QUOTE:原帖由 C_C 于 2007-4-7 16:45 发表
to > flw
《unix 高级环境编程》第4。2的说明在读常规文件时不会出现这个问题 你看的是哪一版?
我这里有一份电子的,我看了一下,第 4.2 节讲的是 stat fstat 和 lstat 啊。没有说 read。
考虑到你有可能是 4.20 节的手误,我还特意看了一下,讲的是 mkdir。





我刚才把书说错了,是《unix 高级编程》,书上是这么说的:
read( int fd,void *buf,size_t nbytes )
在某些读环境,可能受到的字节数少于nbytes参数请求字节数。
从常规文件读时,当尝试满足计数到达了文件尾时,就可能发生
这种情况。在其他情况下,当从常规文件读时,保证直到nbytes
返回时,函数不会返回。

我对红字部分的理解是:当文件的字节没有nbytes这么大时,读到了文件尾函数便会返回,
但这时已经确保的文件已经可以完整的读入buf中。

[ 本帖最后由 C_C 于 2007-4-7 18:35 编辑 ] ◆

用 getline吧 每次读一行




我想起来了. 第三版好象有说这样的问题.......汗..不年多没看了




C里面有个函数叫fseek(),用来移动文件位置的,你可以用他来移到需要读取的行好,在调用read() ◆

1,第九行结束之后,就是第十行。
2,记住前一个新行位置,到10的时候,回去。
3,如果遇到'\0'呢?

[ 本帖最后由 yuanchengjun 于 2007-4-10 23:20 编辑 ] ◆



QUOTE:原帖由 pianoguy 于 2007-4-10 21:28 发表
C里面有个函数叫fseek(),用来移动文件位置的,你可以用他来移到需要读取的行好,在调用read() 那只能用来移动字节,不是行。











QUOTE:原帖由 tianxiaogang12 于 2007-4-7 21:01 发表
用 getline吧 每次读一行 这个的移植性不太好。

QUOTE:Both getline() and getdelim() are GNU extensions. They are available since libc 4.6.27.




签名

2007-10-24 16:29:46 顶部
第1页 共页 共0个回复     <<    >>    
 快速回复
  • 支持UBB,HTML标签

  • 高级回复

  • 操作选项:评分 加精 解精 奖惩 设专题 设公告 解公告 固顶 总固顶 解固顶 结帖 解结帖 锁帖 解锁 移帖 删帖
      首页 | 购买指南 | 虚拟主机 | 特色介绍 | 下载中心 | 支付方式
    Copyright 2004-2008 BBSGood.com Powered By: BBSGood.Speed Version 5.0
      咨询电话:0575-85513832、0575-85513825(传真)、7*24小时咨询服务:13606552007 不良信息举报中心 浙ICP备05029817号
      业务QQ:38958768、客服QQ1:415896239、客服QQ2:343896043、MSN:jccsxx@hotmail.com