c语言文件操作详细

文件操作有多种形式首先解释文本文件操作
当操作的文件时文本文件时,会将数据转换为ascii字符的值存放到文件中,在使用时在转换会原来的值。这里和printf函数的执行过程很相似
所以在讲解文件之前先讲解两个相关函数
1.
//int printf(const char *_Format,…) 参数中的…是可变参
比如
int a=10;
printf(“a=%d\n”,a);
在执行时printf函数会开辟一个临时空间,来存放printf函数中的双引号中的字符,并且以ascii值的方式存放,并且10在函数中存放时会将其分为1和0,然后通过itoa函数转换为ascii,所以当我们在屏幕上看到的值是,那些都是一个个字符所组成的内容。
并且,printf函数是有返回值的,他的返回值是int类型用于计算“”之间字符的个数。

2
int sprintf( char *str,const char * format,…);
sprintf()会根据参数format字符串来转换并格式化数据, 然后将结果复制到参数str所指的字符串数组, 直到出现字符串结束(’\0’)为止。关于参数format字符串的格式请参考printf()。
成功则返回参数str字符串长度, 失败则返回-1, 错误原因存于errno中。
所以sprintf函数的作用和printf函数有一些类似,但是他不输出,他只是将“ ”之间的字符串转换为单个字符包括空格,存入sprintf函数指定的数组中,存储是以ascii方式存放的

3
记住关键是在理解写入和读取时我们需要站在程序的角度来看待,写入就是将程序数据存放到文件中,读取就是将文件内容读入程序中,文件开辟时一般开辟4k大小的磁盘空间(这和文件磁盘格式有关),如果不够则会在磁盘中在开辟一个空间,但是电脑显示时是只有一个文件的

FILE * fopen(const char * path,const char * mode);
表头文件:
#include<stdio.h>
说明:
参数path字符串包含欲打开的文件路径及文件名, 参数mode字符串则代表着流形态。
mode有下列几种形态字符串:
r 打开只读文件, 该文件必须存在。
r+ 打开可读写的文件, 该文件必须存在。
w 打开只写文件, 若文件存在则文件长度清为0, 即该文件内容会消失。若文件不存在则建立该文件。
w+ 打开可读写文件, 若文件存在则文件长度清为零, 即该文件内容会消失。若文件不存在则建立该文件。
a 以附加的方式打开只写文件。若文件不存在, 则会建立该文件, 如果文件存在, 写入的数据会被加到文件尾, 即文件原先的内容会被保留。
a+ 以附加方式打开可读写的文件。若文件不存在, 则会建立该文件, 如果文件存在, 写入的数据会被加到文件尾后, 即文件原先的内容会被保留。
上述的形态字符串都可以再加一个b字符, 如rb、w+b或ab+等组合, **加入b 字符用来告诉函数库打开的文件为二进制文件, 而非纯文字文件。**不过在POSIX系统, 包含Linux都会忽略该字符。由fopen()所建立的新文件会具有
rb+打开一个用于读写的二进制文件
wb+创建一个用于读写的二进制文件
ab+打开一个用于读写的二进制文件

文件顺利打开后, 指向该流的文件指针就会被返回。若果文件打开失败则返回NULL, 并把错误代码存在errno 中。

但是要注意的时r操作(不管有没有w或者+)都不能用于创建一个新的文件,当文件存在时返回真,无则返回空指针

//FILE *fp=fopen("yhp.tx","w");//yhp.txt时相对路径,在存放时是放在程序对应的文件中的
int ar[]={12,23,34,45,56};
FILE *fp=fopen("C:text//yhp.tx","w");//这就是绝对路径,文件存放在指定的地方
if(NULL==fp)//文本文件存放的都ascii值
return -1;
for(int i=-;i<10;i++)
{
fprintf(fp,"%d ",ar[i];
}
fclose(fp);
fp=NULL;

下面是二进制文件的写入操作,二进制文件操作的区别在于,二进制文件在存放数据是不会将数据转换为ascii的值存放而是内存中是什么样的,二进制文件就是如何存放的

//FILE *fp=fopen("yhp.tx","wb");//yhp.txt时相对路径,在存放时是放在程序对应的文件中的
int ar[]={12,23,34,45,56};
int n=sizeof(ar)/sizeof(ar[0]);
FILE *fp=fopen("C:text//yhp.dat","wb");//这就是绝对路径,文件存放在指定的地方
if(NULL==fp)//文本文件存放的都ascii值
return -1;
fwrite(ar,sizeof(int),n,fp);//这是一个专门处理二进制文件写入的函数,但是有要求是,写入目标必须是连续的
fclose(fp);
fp=NULL;

另外,值创建文件时,文件名的后缀时无所谓的,因为我们使用文件时不会单独将文件打开而是使用程序打开,但是比如我们文件的创建时是以二进制操作的,但是我们将其命名为。txt文件,那么在打开文件是会将二进制写入的16进制数当做ascii的值然后表现而ascii字符

然后进行文本文件的读取操作

int br[5];
FILE *fp=fopen("C:text//yhp.txt","r");//这就是绝对路径,文件存放在指定的地方
if(NULL==fp)//文本文件存放的都ascii值
return -1;
for(int i=-;i<10;i++)
{
fscanf(fp,"%d ",br[i];
}
fclose(fp);
fp=NULL;

但是在使用fsacnf是需要记住fprintf输入时双引号%d后面的间隔是用是么来间隔的,如果符后错误,那么在读取是就会出现错误,所以在读取是我们一般使用fgetc函数,fgetc函数在读取时时一个个字符进行读取如果文本文件中需要存放的数据本身就是文本(也就是字符和字符串)时,他是不会进行itoa转换的,而实直接将字符的ascii的值存放,所以在存放文本数据时,使用文本文件进行存放较为方便

#include<windows.h>
int br[5];
FILE *fp=fopen("C:text//yhp.txt","r");//这就是绝对路径,文件存放在指定的地方
if(NULL==fp)//文本文件存放的都ascii值
return -1;
char ch;
while(!feof(fp))//判断文件是否读到末尾,如果未读到末尾,则返回假,然后求反
{
ch=fgetc(fp);//在读取文件(使用时fgetc),存在一个文件定位指针(下标),会在文件操作中每读取一个字节字符。该下标就会向后移动一个字节
cout<<ch;
Sleep(100);//<windows.h>文件中包含的睡眠函数,可以让程序进行延缓100ms
}
fclose(fp);
fp=NULL;

上面的程序我们发现ch为char类型,那么在读取时我们需要一个个字符的读取,那么速率就较为缓慢,所以为了应对这种问题我们采取下面的操作

#include<windows.h>
FILE *fp=fopen("C:text//yhp.txt","r");//这就是绝对路径,文件存放在指定的地方
const int n=10;
if(NULL==fp)//文本文件存放的都ascii值
return -1;
char buff[n];//用于存放读取的数据
while(!feof(fp))//判断文件是否读到末尾,如果未读到末尾,则返回假,然后求反
{
fets(buff,n,fp);//给buff这个字符串了十个空间但实际它之存放9个数据,
printf("%s",buff);
Sleep(100);//<windows.h>文件中包含的睡眠函数,可以让程序进行延缓100ms
}
fclose(fp);
fp=NULL;

fgets函数在执行时,因为buff这个字符串的空间为10所以在fgets读取九个字符时,会在第十个空间赋值一个0(也就是\0)字符串的终止符,还有另一个情况就是在读取文件时buff这个字符串存放九个字符,而某一行有13个字符那么在第二次读取时就会用新4个字符来替换前四个字符,当读取时碰到换行字符(ascii值为10,\n)就会在下一个空间赋值\0,使该字符串终止,应为在printf函数读取%s时,是根据\0来终止读取数据的,下面我附上调试截图,这是第一次buff读取数据
在这里插入图片描述这是第二次读取数据在这里插入图片描述
我们可以看到,当第二次读取是碰见了\n符号,所以选择了在第九个位置赋值了\0,然后第三次又继续读取
在这里插入图片描述
另外需要知道的是buff的空间是循环利用的,所以当fgets函数在第二次读取时发现第八个空间的位置是\n,所以在第九个空间赋值为\0,如果第五个空间是\n,则在第六个空间赋值为\0,而第六个之后的空间内容是上一次读取的内容没有被覆盖

**在这里我要着重说明一个东西,我们平时使用回车键是,其实是使用了两个功能,一个是\r回车符,它是将光标移动到这一行的首位另一个是\n换行,在使用

fgets和fgetc时都不会在读取\r回车符,但是回车符的函数最用依旧存在,因为在读取时我们需要\r符来使光标回到行首

**

在读取数据时,存放的数据类型是什么样子的,在读取是类型就是那么样子,比如存放的时int类型那么在读取是我们不能把他读取为double类型,因为不同类型的数据所占用的内存大小是不同的,double的识别能力时8字节,而int的识别能力时4字节,如果在读去时会出现识别范围错误,当第一个识别错误时会造成连续效应,导致后面的数据读取都会出现错误,而不仅仅时一个类型转换的误差

下面我们来写另一个函数,函数目的是将一个文件的内容写入到另一个文件中

#include<windows.h>
void main()
{
FILE *rfp=fopen("C:text//yhp.txt","r");//这就是绝对路径,文件存放在指定的地方
FILE *wfp=fopen("C:text//llj.txt","w");
const int n=10;
if(NULL==fp)//文本文件存放的都ascii值
return -1;
char buff[n];//用于存放读取的数据
while(!feof(fp))//判断文件是否读到末尾,如果未读到末尾,则返回假,然后求反
{
fets(buff,n,rfp);//给buff这个字符串了十个空间但实际它之存放9个数据
fputs(buff,wfp);//fputs不需要指定buff的大小是因为在读取时函数会根据\0来判断是否终止,所以不需要给定大小
Sleep(100);//<windows.h>文件中包含的睡眠函数,可以让程序进行延缓100ms
}
fclose(fp);
fp=NULL;
}

在上面的函数很好理解,但是有一个地方需要我们注意,fputs函数在写入时,虽然fgets函数在传值时不会传\r回车符,但是在写入时放fputs函数在遇见\n换行符时,会自动加上一个\r回车符这就让程序的读取写入时不会缺少内容

int main(int argc,char argv[],char envp)
首先这三个参数都存放在数据区
argc表示有多少个命令行参数,第一个就是执行程序名,所以argc最少为1。
argv指向一个指针数组的首元素,数组中每个元素都是 char * 指针,指向整个命令行参数字符串。
envp[]环境参数,envp[],这个数组与刚才的argv[]有些相似,它的最后一个元素也储存的空指针

需要了解的函数,getc,getch,getchar

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值