Day 19 fgetc, fgets, fputc, fputs, fread, fwrite, 编写一个拷贝命令,在系统中可以调用,,,

1.umask 0002(此处第一个0代表二进制) 掩码值,设置文件权限时会涉及,如果文件权限在创造文件的时候设置为 0666, 实际出来的结果为 0664 因为会减掉 0002.

2.整行对齐,在命令模式下 V -> G -> =

3.//stdin 标准输入键盘
//stdout 标准输出屏幕
//stderr 标准错误

4.文件描述符,其实就是一个整型数,当用系统函数 open(); 每打开一个文件时,就会有一个文件描述符被定义,一般为 0 ~ 1023 共1024
其中 0, 1, 2, 已经被占用由系统自动分配,对应上面的三种标准模式。

5.练习题:



(1)写函数可以读出一个文件里面字母 a~z 的个。
分析:要统计小写字母的个数,小写字母一共26个,那么用于统计的变量需要26个,每拿出来一个文本中的字符用if判断
让相应的变量加一,最后在打印出来即可。

(2)上面的方法可以实现就是太麻烦了,不仅有些low 而且效率低。
可以想到把需要存储的26个变量的值存入一个数组中。用数组a[0]元素代表字母a的个数,a[1]元素代表字母b 的个数。依次类推。
将26个字母的个数存入数组中。此方法最巧妙之处是 int ret = fgetc(fp1); ret = ret - ‘a’; a[ret] += 1; 将取到的字符个数对应
到数组中。

#include <stdio.h>
int main(int argc, const char *argv[])
{

if(argc < 2)  //判断传过来的参数是否正确
{
	printf("usage: ./a.out xxx\n"); //提醒用户如何使用。
	return 0;
}
FILE *fp1 = fopen(argv[1], "r"); //打开文件
if(NULL == fp1) //判断打开是否正确
{
	printf("fopen error");
	return 1;
}

int a[26] = {0};

while(1)
{
	int ret = fgetc(fp1);
	if(EOF == ret)
	{
		break;	
	}
    if(ret >= 'a' && ret <= 'z') //核心语法 
	{
	
		ret = ret - 'a'; //取出来的数字减去字符'a'为对应的字符,
		a[ret] += 1;     //
	//	a[ret] = a[ret] + 1;
	}

}
fclose(fp1); //关闭文件

int i;
for(i = 0; i < 26; ++i)
{

	printf("%c = %d", i + 'a', a[i]); //将字符的个数打印出来。
	puts(""); //每打印一条就换行下。
}
return 0;
}

6.函数



fgets();
char *fgets(char *s, int size, FILE *stream);
按行读, 有三个参数,第一个为缓冲指针参数,第二个为定义的缓冲区的大小, 第三个为文件流,打开文件的指针。
返回值:当发生错误和和读完时返回NULL, 否则返回读到的数据。


fputs();
int fputs(const char *s, FILE *stream);
按行写,有两个参数,第一个为缓冲的数据,第二个为要写入的文件。
返回值:成功时返回一个非负值,错误时 返回EOF


fgetc();
int fgetc(FILE *stream);
按单个字符读,一个参数为打开的文件流。
返回值为读到的字符,这里为int 是因为char 和 int 相兼容。


fputc();
int fputc(int c, FILE *stream);
按单个字符写,第一个参数为要写字符的ASCII码,'a’这种形式也可以,第二个参数为要写的文件流。



7.fread(); / fwrite();
当为非文本非字符串时一般都认为是二进制。
这一对函数比前两对函数要强大,可以读写文件也可以读写二进制(如照片)。
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

#include <stdio.h>
#include <string.h>
typedef struct PER
{
	char name[20];
	char phone[15];
	int age;
	char addr[50];
}Per; //typedef 

int main(int argc, const char *argv[])
{
	//struct PER p;
	FILE* fp = fopen("tel","r");
	if(NULL == fp)
	{
		printf("fopen error\n");
		return 1;

	}
Per  p;
fread(&p,sizeof(p),1,fp);
printf("%s:%s:%d:%s\n",p.name,p.phone,p.age,p.addr);
fclose(fp);


return 0;
}


size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);


#include <stdio.h>

#include <string.h>
typedef struct PER
{
	char name[20];
	char phone[15];
	int age;
	char addr[50];
}Per;

int main(int argc, const char *argv[])
{
	//struct PER p;
	FILE* fp = fopen("tel","w");
	if(NULL == fp)
	{
		printf("fopen error\n");
		return 1;

}
Per  p;
printf("亲,输入个名字:");
fgets(p.name,20,stdin);// zhangsan\n
p.name[strlen(p.name)-1]='\0';
printf("亲,输入电话:");
fgets(p.phone,15,stdin);
p.phone[strlen(p.phone)-1]='\0';
printf("亲,输入地址:");
fgets(p.addr,50,stdin);
p.addr[strlen(p.addr)-1]='\0';
printf("亲,输入年龄:");
char data[100];
fgets(data,5,stdin);
//data[strlen(data)-1]='\0';
p.age =  atoi(data);

fwrite(&p,sizeof(p),1,fp);  //此句可以一次把要写的数据写入不用使用 fputs多次写入。

fclose(fp);


return 0;
}


写一个拷贝函数可以拷贝文件,及二进制。

#include <stdio.h>

int main(int argc, const char *argv[])
{
	FILE* src = fopen("11.jpg","r");
	FILE* dst = fopen("2.jpg","w");
	if(NULL == src || NULL == dst)
	{
		printf("fopen error\n");
		return 1;
	}
	fseek(src,0,SEEK_END); // int fseek(FILE *stream, long offset, int whence); 
	long size = ftell(src);//long ftell(FILE *stream);
	rewind(src); // void rewind(FILE *stream);  相当于下面函数的写法。 (void) fseek(stream, 0L, SEEK_SET)	
                         
//while(1)
/*int i = 0 ;
for(i = 0 ;i<size;i++)
{
	int c =  fgetc(src);
	fputc(c,dst);
}*/
while(1)
{
	int c =  fgetc(src);
	if(feof(src))//EOF == c  
		break;
	fputc(c,dst);
	
}

fclose(src);
fclose(dst);
return 0;
}


用IO函数直接操作,完成拷贝功能。

#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

int main(int argc, const char *argv[])
{

if(argc < 3)
{
	printf("usage: ./a.out 1 2\n");
	return 1;
}
int src = open(argv[1], O_RDONLY);
if(-1 == src)
{
	printf("open errror");
}
int dst = open(argv[2], O_RDWR|O_CREAT|O_TRUNC, 0666);
if(-1 == dst)
{
	printf("open errror");
}
int ret = 0;


char s[512] = {0};
while(1)
{

//		char s[10];
		ret = read(src, s, sizeof(s));
	//	printf("ni");
		if(0 == ret)
		{
			printf("hi");
			break;
		}
		write(dst, s, ret);
	//	printf("hao");
	}
	close(src);
	close(dst);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值