linux 文件读写
来源:互联网 发布:数控g76内螺纹编程实例 编辑:程序博客网 时间:2024/05/19 15:40
两种I/O文件函数
ANSI I/O本质
文件类型FILE
包含一个指针
包含一个stream (C语言把文件看成stream)
file open
r Open text file for reading
r+ Open for reading and writing
w Truncatefile to zero length or create text file for writing
w+ The file is created if it does not exist,otherwise it is truncated
a Open for appending (writing at end of file).
The stream is positioned at the end of the file.
fopen三种基本模式r,w,a只允许针对文本文件
C语言允许最大同时打开16个文件
实际只允许同时打开13个文件,因为有另外三个标准文件stdout,stdin,stderr
文件读写的基本语句
1#include <stdio.h>
FILE *stream; 注意类型是大写 2
if((stream=fopen("testtmp","r+"))==NULL)
{ printf("open file error/n");
return;
}
3int ret;
if ((ret=fclose(stream))==-1) printf("close fileerror/n");
顺序读文件(按字符)
while((c=fgetc(stream))!=EOF)printf("%c",c); 每读一个字符,文件指针会(自动)移动一格
顺序读文件(按字符串)-------从一个文件依次读一行,直到读到NULL
char record[100],*re;
while ((re=fgets(record,100,stream))!=NULL)
printf("%s",record);
读一行,以回车换行作为读一行的尾部标志
从文件中fgets的字符串是读一行,即包括了回车
所以printf("%s")即可,不用"%s/n",因为字符串里面带了回车了
这也是个漏洞,字符串里带了回车
所以非常不利于字符串比对strcmp
scanf读文件,文件指针不移动,需要手动fseek移指针
fseek(stream,3,SEEK_SET);
fscanf(stream,"%c",&c[0]);
fseek(stream,11,SEEK_SET);
fscanf(stream,"%c",&c[1]);
文件读写到文件末尾
文件指针会指到NULL(而不是EOF,EOF不是地址,而是结尾字符)
linux和DOS对文件的结束判别是不同的
linux没有文件结束符,是以目录项的文件长度做为文件结束的判别手段
DOS看0x1a文件结束符
linux 和DOS的换行符的区别
linux DOS0x0a 即10
即’/n’
即LF CR,LF双码
读文件时, 不能用unsigned char c作为返回值,因为EOF不在unsigned范围内
char c;
c=getc(stream);
fscanf读文本文件里面的数字,既可以直接用%c,也可以用%d
用%c(char)读,可以读出3,1
用%d(int)读,也可以读出3,1
fseek(stream,3,SEEK_SET);
fscanf(stream,"%c",&c[0]);
fseek(stream,11,SEEK_SET);
fscanf(stream,"%c",&c[1]);
fseek(stream,ii,SEEK_SET);
fscanf(stream,"%d",&ln[i].frame);
fseek(stream,ii+8,SEEK_SET);
fscanf(stream,"%d",&ln[i].line);只不过这两个3,1,一个是实际值3,1,一个是'3','1'
几个常见特殊字符的整型数字
char int 空格' '
32 TAB键 9 回车 10文件结束EOF
-1字符串结束符号
数字0(不是字符‘0’)
TAB字符处理要小心,经过到记事本copy/paste后,TAB键被转化成几个空格
for(;str[i]==''||str[i]==' ';i++);
但经过到记事本copy/paste后,TAB键被转化成几个空格
所以系统总报warning:
tmp.c:58: warning: comparison is always false due to limited rangeof data type
tmp.c:59:27: warning: character constant too long for itstype
fgets字符串指针改成字符串数组,消灭了Segmentationfault错误
char *re,*rec;
re=fgets(rec,100,srcstream);
出Segmentation fault错误
改成
char *re,rec[100];
re=fgets(rec,100,srcstream);
错误消失
一个普通的显示文件内容的函数
printfile(FILE *stream,char *filename,int or)
{
int i,re;
char rec[100];
FILE *tmpstream;
if (or)
{
if((tmpstream=fopen(filename,"r"))==NULL)
{printf("open file error/n");
return 0;
}
for(i=0;(re=fgets(rec,100,tmpstream))!=NULL;i++)printf("[%d]:%s",i,rec);
显示文件内容时,每行加行号
if ((re=fclose(tmpstream))==-1) printf("closefile error/n");
} else
{
fseek(stream,0,SEEK_SET);
for(i=0;(re=fgets(rec,100,stream))!=NULL;i++)printf("[%d]:%s",i,rec);
}
}
printfile(NULL,"testtmp.tmp",1);
[0]:total 48
[1]:1 macg macg 3301 Jan 16 02:16 file.c
[2]:-rw-rw-r-- 1 macgmacg 52 Jan 16 02:19Makefile
[3]:1 macg macg 0 Jan 16 02:56 testtmp
[4]:this is a testthis is a testthis is a testthis is a testthis isa testth
[5]:-rw-rw-r-- 1 macg macg 1428 Jan 16 02:56tmp.oif((stream=fopen("testtmp","r+"))==NULL)
{ printf("open file error/n");
return 0;
}
printfile(stream,NULL,0);
[0]:total 48
[1]:-rw-rw-r-- 1 macg macg 3301 Jan 1602:16 file.c
[2]:-rw-rw-r-- 1 macgmacg 52 Jan 16 02:19Makefile
[3]: -rw-rw-r-- 1 macgmacg 0 Jan16 02:56 testtmp
[4]:this is a testthis is a testthis is a testthis is a testthis isa testth
[5]:-rw-rw-r-- 1 macg macg 1428 Jan 16 02:56tmp.o
按SED/AWK原理,读记录/行的函数——是从文件中取第recno行
int getrecord(char *rec,FILE *stream,int recno)
{
int i,ret;
char *re;
for(i=0;i<=recno;i++) re=fgets(rec,100,stream);数行,并一边数一边读行
if(re==NULL) return 0; 如果所取行超过文件长度,则返回0
else return 1;
}
getrecord(record,stream,4); 取记录/行,取文件第四行
printf("record is %s/n",record);
printf("/n/n/n");$ ./tmp
recordis -rw-rw-r-- 1 macgmacg 0 Jan16 02:56 testtmp
按SED/AWK原理,读字段的函数——从字符串中取第valueno字段
int getvalue(char *str,int valueno,char *value)
{
int i,j,vali;
数字段
for(i=0,vali=0;vali<valueno;vali++)
{
for(;str[i]==' '||str[i]==9;i++);
for(;str[i]!=''&&str[i]!=9&&str[i]!=0;i++);
if(str[i]==0) return 0;
}
取字段
for(;str[i]==' '||str[i]==9;i++);
for(j=0;str[i]!=''&&str[i]!=9&&str[i]!=0;i++,j++)
{
value[j]=str[i];
}
value[j]=0;
}
for(i=0;i<20;i++)
{
if(getvalue(record,i,val)) printf("no %d is %s/n",i,val);
}
$ ./tmp
recordis -rw-rw-r-- 1 macgmacg 0 Jan16 02:56 testtmp 事先故意编辑过此行,加了几个TAB,连行尾也含TAB
no 0 is -rw-rw-r--
no 1 is 1
no 2 is macg
no 3 is macg
no 4 is 0
no 5 is Jan
no 6 is 16
no 7 is 02:56
no 8 is testtmp
no 9 is
fputs(stren,streamwrite)写入的串不带回车,fprintf(strea,"%s",str)写入的串也不带回车,所以,要写入文件回车,必须写入/n
fputs(stren,streamwrite);
cat aaa.txt
008421aa
fprintf(streamwrite,"%s/n",stren);
cat aaa.txt
008421
aa
文件很难进行“修改写”,建议文件追加
最好的办法就是写到新文件,或写到stdout再重定向入文件。然后把新文件覆盖旧文件
writefile(char *tmpfilename,char*srcfilename,struct Filerecord *frs,intfrsi)-------修改文件的函数
实际是从 srcfile读出文件
把其中符合frs[j].recno的行,修改成frs[j].record
其他行不变,仍旧用srcfile读出的行
然后把这些行重新写入一个新文件tmpfile
writefile(char *tmpfilename,char*srcfilename,struct Filerecord *frs,int frsi
o tmpfilename新文件名
o srcfilename旧文件名
o structFilerecord *frs 放置要修改的行的结构体数组
struct Filerecord{
char record[100];
int recno;
};
struct Filerecord fr[20];
o frsi 结构体数组的元素数量writefile(char *tmpfilename,char *srcfilename,struct Filerecord*frs,int frsi)
{
int no,ret,i,j,bol;
char *re,rec[100];
FILE *tmpstream,*srcstream;
if((tmpstream=fopen(tmpfilename,"w+"))==NULL) 写入一个新
{ printf("open file error/n");
return 0;
}
if((srcstream=fopen(srcfilename,"r"))==NULL)
{ printf("open file error/n");
return 0;
}
for(no=0;(re=fgets(rec,100,srcstream))!=NULL;no++)
{
for(j=0,bol=1;j<frsi&&bol;j++)
{
if(no==frs[j].recno) {
bol=0;
strcpy(rec,frs[j].record);
}
}
fputs(rec,tmpstream);
}
if ((ret=fclose(tmpstream))==-1) printf("close fileerror/n");
if ((ret=fclose(srcstream))==-1) printf("close fileerror/n");
}
例子:去掉文件中行的TAB键和起首空格或TAB
执行:
读出原文件每行,checkinvaild() ,看是否含有TAB,起首空格/TAB
如果确实有,就对此行处理,重新组合,去掉TAB,起首空格/TAB,然后写入struct person fr[20]数组
writefile("testtmp.tmp","testtmp",fr,fri);
------------------the sickfile----------------------------------------
[0]:total 48
[1]:-rw-rw-r-- 1 macg macg 3301 Jan 1602:16 file.c
[2]:-rw-rw-r-- 1 macgmacg 52 Jan 16 02:19Makefile
[3]: -rw-rw-r-- 1 macgmacg 0 Jan16 02:56 testtmp
[4]:this is a testthis is a testthis is a testthis is a testthis isa testth
[5]:-rw-rw-r-- 1 macg macg 1428 Jan 16 02:56tmp.o
--------------------modifyline--------------------------------------
fri is 2,the new line is following:
[1]row:1 macg macg 3301 Jan 16 02:16 file.c
[3]row:1 macg macg 0 Jan 16 02:56 testtmp
-------------------newfile---------------------------------------
[0]:total 48
[1]:1 macg macg 3301 Jan 16 02:16 file.c
[2]:-rw-rw-r-- 1 macgmacg 52 Jan 16 02:19Makefile
[3]:1 macg macg 0 Jan 16 02:56 testtmp
[4]:this is a testthis is a testthis is a testthis is a testthis isa testth
[5]:-rw-rw-r-- 1 macg macg 1428 Jan 16 02:56tmp.o
fseek(stream,offset,mode)的三个mode
SEEK_SET:从开头数第几个offset
SEEK_CUR: 从当前数第几个offset
SEEK_END: 从结尾倒数第几个offset
文件指针位置是从0(文件头)开始算的
fseek(stream,0,SEEK_SET);
int ftell(FILE*stream) 返回stream的当前指针位置
简单的取文件大小size的操作
fseek(stream,0,SEEK_END);先将指针指向文件尾部
ret=ftell(stream); 再获得指针所指的当前地址
这个指向文件尾部的指针地址就是文件大小 取文件大小的操作对读写文件很有用,因为读写文件很不好判定文件结尾。
文件例子
$ cat tmp.c
#define DEBUG 0
#include <stdio.h>
#include <string.h>
#include <unistd.h>
struct Filerecord{
char record[100];
int recno;
};
main()
{
char directory[100];
#ifdef SYST
getcwd(directory,100);
printf("current directory is %s/n",directory);
#endif
filemanage();
}
filemanage()
{
int i,j,fri,ret;
char record[100],val[50],modi_rec[100];
FILE *stream;
struct Filerecord fr[20];
if((stream=fopen("testtmp","r+"))==NULL)
{ printf("open file error/n");
return 0;
}
printf("------------------the sickfile-----------------------/n");
printfile(stream,NULL,0);
for(i=0,fri=0;getrecord(record,stream,i);i++)
{
if (DEBUG) printf("no %d row is:%s/n",i,record);
if(ret=findinvalid(record))
{
for(j=0;getvalue(record,j,val);j++)
{
if (DEBUG) printf("no %d's val is %s%d/n",j,val,val[0]);
if(j==1) strcpy(modi_rec,val);
if(j>1) {
strcat(modi_rec," ");
strcat(modi_rec,val);
}
}
fr[fri].recno=i;
strcpy(fr[fri].record,modi_rec);
if (DEBUG) printf("fr[%d] is %d %s/n",fri,fr[fri].recno,fr[fri].record);
fri++;
}
if (DEBUG) printf("---------------------------------/n");
}
printf("--------------------modifyline--------------------/n");
printf("fri is %d,the new line is following: /n",fri);
for(i=0;i<fri;i++)
printf("[%d]row:%s",fr[i].recno,fr[i].record);
if ((ret=fclose(stream))==-1)
{
printf("close file error/n");
return 0;
}
writefile("testtmp.tmp","testtmp",fr,fri);
printf("-------------------new file-----------------/n");
printfile(NULL,"testtmp.tmp",1);
}
int findinvalid(char *str)
{
int i,ret;
i=0;
if(str[i]==' ')
{
if (DEBUG) printf("str[%d] == %d/n",i,str[i]);
return 32;
}
for(i=0;str[i]!=9&&str[i]!=0;i++);
if(str[i]==9)
{
if (DEBUG) printf("str[%d] == %d/n",i,str[i]);
return 9;
} else
{
if (DEBUG) printf("str[%d] == %d/n",i,str[i]);
return 0;
}
}
$ make
gcc -g -c tmp.c
tmp.c: In function 鈥榩rintfile鈥?
tmp.c:158: warning: assignment makes integer from pointer without acast
tmp.c:158: warning: comparison between pointer and integer
tmp.c:165: warning: assignment makes integer from pointer without acast
tmp.c:165: warning: comparison between pointer and integer
gcc -o tmp tmp.o -g
$ ./tmp
------------------the sick file----------------------
[0]:total 48
[1]:-rw-rw-r-- 1 macg macg 3301 Jan 1602:16 file.c
[2]:-rw-rw-r-- 1 macgmacg 52 Jan 16 02:19Makefile
[3]: -rw-rw-r-- 1 macgmacg 0 Jan16 02:56 testtmp
[4]:this is a testthis is a testthis is a testthis is a testthis isa testth
[5]:-rw-rw-r-- 1 macg macg 1428 Jan 16 02:56tmp.o
--------------------modify line--------------------
fri is 2,the new line is following:
[1]row:1 macg macg 3301 Jan 16 02:16 file.c
[3]row:1 macg macg 0 Jan 16 02:56 testtmp
-------------------new file-------------------------
[0]:total 48
[1]:1 macg macg 3301 Jan 16 02:16 file.c
[2]:-rw-rw-r-- 1 macgmacg 52 Jan 16 02:19Makefile
[3]:1 macg macg 0 Jan 16 02:56 testtmp
[4]:this is a testthis is a testthis is a testthis is a testthis isa testth
[5]:-rw-rw-r-- 1 macg macg 1428 Jan 16 02:56tmp.o
- fopen ANSI 标准文件I/O,基于低层次I/O
- open 低层次I/O
ANSI I/O本质
- DOS/WINDOWS平台,MS DOS 文件读写, 汇编语言编写
- LINUX平台,unix/linux文件读写,C语言编写
文件类型FILE
包含一个指针
包含一个stream (C语言把文件看成stream)
file open
r Open text file for reading
r+ Open for reading and writing
w Truncatefile to zero length or create text file for writing
w+ The file is created if it does not exist,otherwise it is truncated
a Open for appending (writing at end of file).
The stream is positioned at the end of the file.
fopen三种基本模式r,w,a只允许针对文本文件
C语言允许最大同时打开16个文件
实际只允许同时打开13个文件,因为有另外三个标准文件stdout,stdin,stderr
文件读写的基本语句
1#include <stdio.h>
FILE *stream; 注意类型是大写 2
if((stream=fopen("testtmp","r+"))==NULL)
{ printf("open file error/n");
return;
}
3int ret;
if ((ret=fclose(stream))==-1) printf("close fileerror/n");
顺序读文件(按字符)
while((c=fgetc(stream))!=EOF)printf("%c",c); 每读一个字符,文件指针会(自动)移动一格
顺序读文件(按字符串)-------从一个文件依次读一行,直到读到NULL
char record[100],*re;
while ((re=fgets(record,100,stream))!=NULL)
printf("%s",record);
读一行,以回车换行作为读一行的尾部标志
从文件中fgets的字符串是读一行,即包括了回车
所以printf("%s")即可,不用"%s/n",因为字符串里面带了回车了
这也是个漏洞,字符串里带了回车
所以非常不利于字符串比对strcmp
scanf读文件,文件指针不移动,需要手动fseek移指针
fseek(stream,3,SEEK_SET);
fscanf(stream,"%c",&c[0]);
fseek(stream,11,SEEK_SET);
fscanf(stream,"%c",&c[1]);
文件读写到文件末尾
文件指针会指到NULL(而不是EOF,EOF不是地址,而是结尾字符)
- fput(),fgetc()会返回EOF
- fgets()会返回NULL
linux和DOS对文件的结束判别是不同的
linux没有文件结束符,是以目录项的文件长度做为文件结束的判别手段
DOS看0x1a文件结束符
linux 和DOS的换行符的区别
linux DOS0x0a 即10
即’/n’
即LF CR,LF双码
读文件时, 不能用unsigned char c作为返回值,因为EOF不在unsigned范围内
char c;
c=getc(stream);
fscanf读文本文件里面的数字,既可以直接用%c,也可以用%d
用%c(char)读,可以读出3,1
用%d(int)读,也可以读出3,1
fseek(stream,3,SEEK_SET);
fscanf(stream,"%c",&c[0]);
fseek(stream,11,SEEK_SET);
fscanf(stream,"%c",&c[1]);
fseek(stream,ii,SEEK_SET);
fscanf(stream,"%d",&ln[i].frame);
fseek(stream,ii+8,SEEK_SET);
fscanf(stream,"%d",&ln[i].line);只不过这两个3,1,一个是实际值3,1,一个是'3','1'
几个常见特殊字符的整型数字
char int 空格' '
32 TAB键 9 回车 10文件结束EOF
-1字符串结束符号
数字0(不是字符‘0’)
TAB字符处理要小心,经过到记事本copy/paste后,TAB键被转化成几个空格
for(;str[i]==''||str[i]==' ';i++);
但经过到记事本copy/paste后,TAB键被转化成几个空格
所以系统总报warning:
tmp.c:58: warning: comparison is always false due to limited rangeof data type
tmp.c:59:27: warning: character constant too long for itstype
fgets字符串指针改成字符串数组,消灭了Segmentationfault错误
char *re,*rec;
re=fgets(rec,100,srcstream);
出Segmentation fault错误
改成
char *re,rec[100];
re=fgets(rec,100,srcstream);
错误消失
一个普通的显示文件内容的函数
printfile(FILE *stream,char *filename,int or)
{
int i,re;
char rec[100];
FILE *tmpstream;
if (or)
{
if((tmpstream=fopen(filename,"r"))==NULL)
{printf("open file error/n");
return 0;
}
for(i=0;(re=fgets(rec,100,tmpstream))!=NULL;i++)printf("[%d]:%s",i,rec);
显示文件内容时,每行加行号
if ((re=fclose(tmpstream))==-1) printf("closefile error/n");
} else
{
fseek(stream,0,SEEK_SET);
for(i=0;(re=fgets(rec,100,stream))!=NULL;i++)printf("[%d]:%s",i,rec);
}
}
printfile(NULL,"testtmp.tmp",1);
[0]:total 48
[1]:1 macg macg 3301 Jan 16 02:16 file.c
[2]:-rw-rw-r-- 1 macgmacg 52 Jan 16 02:19Makefile
[3]:1 macg macg 0 Jan 16 02:56 testtmp
[4]:this is a testthis is a testthis is a testthis is a testthis isa testth
[5]:-rw-rw-r-- 1 macg macg 1428 Jan 16 02:56tmp.oif((stream=fopen("testtmp","r+"))==NULL)
{ printf("open file error/n");
return 0;
}
printfile(stream,NULL,0);
[0]:total 48
[1]:-rw-rw-r-- 1 macg macg 3301 Jan 1602:16 file.c
[2]:-rw-rw-r-- 1 macgmacg 52 Jan 16 02:19Makefile
[3]: -rw-rw-r-- 1 macgmacg 0 Jan16 02:56 testtmp
[4]:this is a testthis is a testthis is a testthis is a testthis isa testth
[5]:-rw-rw-r-- 1 macg macg 1428 Jan 16 02:56tmp.o
按SED/AWK原理,读记录/行的函数——是从文件中取第recno行
int getrecord(char *rec,FILE *stream,int recno)
{
int i,ret;
char *re;
for(i=0;i<=recno;i++) re=fgets(rec,100,stream);数行,并一边数一边读行
if(re==NULL) return 0; 如果所取行超过文件长度,则返回0
else return 1;
}
getrecord(record,stream,4); 取记录/行,取文件第四行
printf("record is %s/n",record);
printf("/n/n/n");$ ./tmp
recordis -rw-rw-r-- 1 macgmacg 0 Jan16 02:56 testtmp
按SED/AWK原理,读字段的函数——从字符串中取第valueno字段
int getvalue(char *str,int valueno,char *value)
{
int i,j,vali;
数字段
for(i=0,vali=0;vali<valueno;vali++)
{
for(;str[i]==' '||str[i]==9;i++);
for(;str[i]!=''&&str[i]!=9&&str[i]!=0;i++);
if(str[i]==0) return 0;
}
取字段
for(;str[i]==' '||str[i]==9;i++);
for(j=0;str[i]!=''&&str[i]!=9&&str[i]!=0;i++,j++)
{
value[j]=str[i];
}
value[j]=0;
}
for(i=0;i<20;i++)
{
if(getvalue(record,i,val)) printf("no %d is %s/n",i,val);
}
$ ./tmp
recordis -rw-rw-r-- 1 macgmacg 0 Jan16 02:56 testtmp 事先故意编辑过此行,加了几个TAB,连行尾也含TAB
no 0 is -rw-rw-r--
no 1 is 1
no 2 is macg
no 3 is macg
no 4 is 0
no 5 is Jan
no 6 is 16
no 7 is 02:56
no 8 is testtmp
no 9 is
fputs(stren,streamwrite)写入的串不带回车,fprintf(strea,"%s",str)写入的串也不带回车,所以,要写入文件回车,必须写入/n
fputs(stren,streamwrite);
cat aaa.txt
008421aa
fprintf(streamwrite,"%s/n",stren);
cat aaa.txt
008421
aa
文件很难进行“修改写”,建议文件追加
最好的办法就是写到新文件,或写到stdout再重定向入文件。然后把新文件覆盖旧文件
writefile(char *tmpfilename,char*srcfilename,struct Filerecord *frs,intfrsi)-------修改文件的函数
实际是从 srcfile读出文件
把其中符合frs[j].recno的行,修改成frs[j].record
其他行不变,仍旧用srcfile读出的行
然后把这些行重新写入一个新文件tmpfile
writefile(char *tmpfilename,char*srcfilename,struct Filerecord *frs,int frsi
o tmpfilename新文件名
o srcfilename旧文件名
o structFilerecord *frs 放置要修改的行的结构体数组
struct Filerecord{
char record[100];
int recno;
};
struct Filerecord fr[20];
o frsi 结构体数组的元素数量writefile(char *tmpfilename,char *srcfilename,struct Filerecord*frs,int frsi)
{
int no,ret,i,j,bol;
char *re,rec[100];
FILE *tmpstream,*srcstream;
if((tmpstream=fopen(tmpfilename,"w+"))==NULL) 写入一个新
{ printf("open file error/n");
return 0;
}
if((srcstream=fopen(srcfilename,"r"))==NULL)
{ printf("open file error/n");
return 0;
}
for(no=0;(re=fgets(rec,100,srcstream))!=NULL;no++)
{
for(j=0,bol=1;j<frsi&&bol;j++)
{
if(no==frs[j].recno) {
bol=0;
strcpy(rec,frs[j].record);
}
}
fputs(rec,tmpstream);
}
if ((ret=fclose(tmpstream))==-1) printf("close fileerror/n");
if ((ret=fclose(srcstream))==-1) printf("close fileerror/n");
}
例子:去掉文件中行的TAB键和起首空格或TAB
执行:
读出原文件每行,checkinvaild() ,看是否含有TAB,起首空格/TAB
如果确实有,就对此行处理,重新组合,去掉TAB,起首空格/TAB,然后写入struct person fr[20]数组
writefile("testtmp.tmp","testtmp",fr,fri);
------------------the sickfile----------------------------------------
[0]:total 48
[1]:-rw-rw-r-- 1 macg macg 3301 Jan 1602:16 file.c
[2]:-rw-rw-r-- 1 macgmacg 52 Jan 16 02:19Makefile
[3]: -rw-rw-r-- 1 macgmacg 0 Jan16 02:56 testtmp
[4]:this is a testthis is a testthis is a testthis is a testthis isa testth
[5]:-rw-rw-r-- 1 macg macg 1428 Jan 16 02:56tmp.o
--------------------modifyline--------------------------------------
fri is 2,the new line is following:
[1]row:1 macg macg 3301 Jan 16 02:16 file.c
[3]row:1 macg macg 0 Jan 16 02:56 testtmp
-------------------newfile---------------------------------------
[0]:total 48
[1]:1 macg macg 3301 Jan 16 02:16 file.c
[2]:-rw-rw-r-- 1 macgmacg 52 Jan 16 02:19Makefile
[3]:1 macg macg 0 Jan 16 02:56 testtmp
[4]:this is a testthis is a testthis is a testthis is a testthis isa testth
[5]:-rw-rw-r-- 1 macg macg 1428 Jan 16 02:56tmp.o
fseek(stream,offset,mode)的三个mode
SEEK_SET:从开头数第几个offset
SEEK_CUR: 从当前数第几个offset
SEEK_END: 从结尾倒数第几个offset
文件指针位置是从0(文件头)开始算的
fseek(stream,0,SEEK_SET);
int ftell(FILE*stream) 返回stream的当前指针位置
简单的取文件大小size的操作
fseek(stream,0,SEEK_END);先将指针指向文件尾部
ret=ftell(stream); 再获得指针所指的当前地址
这个指向文件尾部的指针地址就是文件大小 取文件大小的操作对读写文件很有用,因为读写文件很不好判定文件结尾。
文件例子
$ cat tmp.c
#define DEBUG 0
#include <stdio.h>
#include <string.h>
#include <unistd.h>
struct Filerecord{
char record[100];
int recno;
};
main()
{
char directory[100];
#ifdef SYST
getcwd(directory,100);
printf("current directory is %s/n",directory);
#endif
filemanage();
}
filemanage()
{
int i,j,fri,ret;
char record[100],val[50],modi_rec[100];
FILE *stream;
struct Filerecord fr[20];
if((stream=fopen("testtmp","r+"))==NULL)
{ printf("open file error/n");
return 0;
}
printf("------------------the sickfile-----------------------/n");
printfile(stream,NULL,0);
for(i=0,fri=0;getrecord(record,stream,i);i++)
{
if (DEBUG) printf("no %d row is:%s/n",i,record);
if(ret=findinvalid(record))
{
for(j=0;getvalue(record,j,val);j++)
{
if (DEBUG) printf("no %d's val is %s%d/n",j,val,val[0]);
if(j==1) strcpy(modi_rec,val);
if(j>1) {
strcat(modi_rec," ");
strcat(modi_rec,val);
}
}
fr[fri].recno=i;
strcpy(fr[fri].record,modi_rec);
if (DEBUG) printf("fr[%d] is %d %s/n",fri,fr[fri].recno,fr[fri].record);
fri++;
}
if (DEBUG) printf("---------------------------------/n");
}
printf("--------------------modifyline--------------------/n");
printf("fri is %d,the new line is following: /n",fri);
for(i=0;i<fri;i++)
printf("[%d]row:%s",fr[i].recno,fr[i].record);
if ((ret=fclose(stream))==-1)
{
printf("close file error/n");
return 0;
}
writefile("testtmp.tmp","testtmp",fr,fri);
printf("-------------------new file-----------------/n");
printfile(NULL,"testtmp.tmp",1);
}
int findinvalid(char *str)
{
int i,ret;
i=0;
if(str[i]==' ')
{
if (DEBUG) printf("str[%d] == %d/n",i,str[i]);
return 32;
}
for(i=0;str[i]!=9&&str[i]!=0;i++);
if(str[i]==9)
{
if (DEBUG) printf("str[%d] == %d/n",i,str[i]);
return 9;
} else
{
if (DEBUG) printf("str[%d] == %d/n",i,str[i]);
return 0;
}
}
$ make
gcc -g -c tmp.c
tmp.c: In function 鈥榩rintfile鈥?
tmp.c:158: warning: assignment makes integer from pointer without acast
tmp.c:158: warning: comparison between pointer and integer
tmp.c:165: warning: assignment makes integer from pointer without acast
tmp.c:165: warning: comparison between pointer and integer
gcc -o tmp tmp.o -g
$ ./tmp
------------------the sick file----------------------
[0]:total 48
[1]:-rw-rw-r-- 1 macg macg 3301 Jan 1602:16 file.c
[2]:-rw-rw-r-- 1 macgmacg 52 Jan 16 02:19Makefile
[3]: -rw-rw-r-- 1 macgmacg 0 Jan16 02:56 testtmp
[4]:this is a testthis is a testthis is a testthis is a testthis isa testth
[5]:-rw-rw-r-- 1 macg macg 1428 Jan 16 02:56tmp.o
--------------------modify line--------------------
fri is 2,the new line is following:
[1]row:1 macg macg 3301 Jan 16 02:16 file.c
[3]row:1 macg macg 0 Jan 16 02:56 testtmp
-------------------new file-------------------------
[0]:total 48
[1]:1 macg macg 3301 Jan 16 02:16 file.c
[2]:-rw-rw-r-- 1 macgmacg 52 Jan 16 02:19Makefile
[3]:1 macg macg 0 Jan 16 02:56 testtmp
[4]:this is a testthis is a testthis is a testthis is a testthis isa testth
[5]:-rw-rw-r-- 1 macg macg 1428 Jan 16 02:56tmp.o
- linux 文件读写
- linux文件读写浅析
- linux文件读写浅析
- Linux内核读写文件
- Linux内核读写文件
- linux文件读写浅析
- linux文件读写浅析
- linux文件读写浅析
- Linux内核读写文件
- linux读写大文件
- linux文件读写浅析
- Linux驱动 读写文件
- linux读写大文件
- linux文件读写浅析
- linux文件读写浅析
- linux文件读写浅析
- linux文件读写浅析
- linux 读写文件接口
- 用ActionScript3实现抽象类和抽象方法及单态模式
- Linux 终端下颜色的输出
- 大型网站性能优化 二 页面(HTML)优化的方法
- 你知道为什么考你这个?——Java面试题及答案汇总分析(1)
- JAVA做报表 -- JFreeChart 实例2
- linux 文件读写
- VC下float存储
- 关于手机软件
- 父类中调用子类构造函数实例化子类的实现
- Singleton (整理)
- 博客开张欢迎光临
- SQL SERVER 数据库 批量 脚本 升级 更新工具 (C# .Net 2.0)
- == equals null "" 比较
- 中国人被释放的个性 ----- 湖南电视台的成功(一)