C提高5 高级结构体 文件操作

1,昨天的作业题经典C语言题型

1将全局区二维字符拷贝到堆中

2将栈区二维字符拷贝到堆中

3合并栈区与全局区的二维字符数组

4把数组排序

5打印堆区的二维数组

6释放堆空间

[email protected]:~/high$ cat main.c 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/**********	释放二级指针方式1,只释放堆中内存	********/
void free_two_level_pointer01(char **p,int num)
{
	if(p == NULL) return ;
	int i =0;
	for(i = 0;i<num;i++)
	{
		if(p[i] != NULL)
		{
			free(p[i]);
			p[i] = NULL;
		}
	}
	free(p);
}

/**********	释放二级指针方式2,只释放堆中内存,同时修改实参的值	********/
void free_two_level_pointer02(char ***p,int count)
{
	int num = 0;
	if(p == NULL) return ;
	int i;
	for(i = 0;i<count;i++)//先释放几个子串的空间
	{
		if(*(p) + i != NULL)
		{
			printf("%d 正在释放 %p \n",++num,*( *(p) + i)  );
			free(*( *(p) + i));
			*( *(p) + i) = NULL;
		}
	}
	if(*p != NULL)//再释放存放子串数目的空间
	{
		printf("%d 正在释放 %p \n",++num, *(p)  );
		free(*p);
		*p = NULL;
	}
	return ;
}

int sort(char **myp1,int len1,char (*myp2)[30],int len2,char ***myp3,int *len3)
{
	if(myp1 == NULL) return -1;
	if(myp2 == NULL) return -2;
	if(myp3 == NULL) return -3;
	int i =0;
	int j =0;
	char **p3 = NULL;
	p3 = (char **)malloc((len1 + len2) * sizeof(char *));//注意这里面装的是指针
	if(p3 == NULL)
	{
		return -4;
	}
	//把全局区的字符拷贝到堆区
	for(i =0;i<len1;i++)
	{
		int tmp_len = strlen(myp1[i]) +1;
		p3[i] = (char *)malloc(tmp_len * sizeof(char));
		if(p3 == NULL)
		{
               		return -4;
        	}
		strcpy(p3[i],myp1[i]);
	}

	//把栈区的字符拷贝到堆区
	for(j =0;j<len2;j++,i++)
	{
		int tmp_len = strlen(myp2[i]) +1;
		p3[i] = (char *)malloc(tmp_len * sizeof(char));
		if(p3 == NULL)
		{
               		return -4;
        	}
		strcpy(p3[i],myp2[j]);
	}

	//把结果传回去
	*len3 = len1 + len2;

	//排序  指针
	for(i = 0;i<len1 + len2;i++)
	{
		for(j = i+1;j<len1 + len2;j++)
		{
			if( strcmp(p3[i],p3[j]) >  0 )
			{
				char *tmp_p = p3[i];
				p3[i] = p3[j];
				p3[j] = tmp_p;
			}
		}
	}
	//把结果传回去
	*myp3 = p3;
	return 0;
}

int main()
{
	int ret = 0;
	int i = 0;

	char *p1[] = {"aaaa","cccc","bbbb"};
	int len1 = sizeof(p1)/sizeof(char *);
	char p2[3][30] = {"1111","3333","2222"};
	int len2 = sizeof(p2)/sizeof(p2[0]);
	char **p3 = NULL;
	int len3 = 0;
	ret = sort(p1,len1,p2,len2,&p3,&len3);
	if(ret != 0)
	{
		printf("ERROR CODE:%d in main.c:sort(p1,len1,p2,len2,&p3,&len3 )\n",ret);
		return ret;
	}

	for(i = 0;i<len3;i++)
	{
		printf("%s\n",p3[i]);
	}

	free_two_level_pointer02(&p3,len3);

	return 0;
}

[email protected]:~/high$ 
编译运行
[email protected]:~/high$ gcc -Wall main.c  && ./a.out 
1111
2222
3333
aaaa
bbbb
cccc
1 正在释放 0x20410b0 
2 正在释放 0x20410f0 
3 正在释放 0x20410d0 
4 正在释放 0x2041050 
5 正在释放 0x2041090 
6 正在释放 0x2041070 
7 正在释放 0x2041010 
[email protected]:~/high$

这是老师的答案

[email protected]:~/high$ cat teacher.c 
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

int sort(char **myp1 /*in*/, int num1, char (*myp2)[30], int num2, char ***myp3, int *num3)
{
	int i = 0, j = 0, k= 0;
	int  tmplen = 0;
	char **p3 = NULL;
	char *tmpP = NULL;
	p3 = (char **)malloc( (num1 + num2) * sizeof(char *)  ); //里面装的是指针
	if (p3 == NULL) 
	{
		return -1;
	}
	//根据

	for (i=0; i<num1; i++)
	{
		tmplen= strlen(myp1[i]) + 1;
		p3[i] = (char *)malloc( tmplen * sizeof(char)) ;
		if (p3[i] == NULL)
		{
			return -2;
		}
		strcpy(p3[i], myp1[i]);
	}

	for (j=0; j<num2; j++, i++)
	{
		tmplen = strlen(myp2[j]) + 1;
		p3[i] = (char *)malloc (tmplen * sizeof(char));
		if (p3[i] == NULL)
		{
			return -3;
		}
		strcpy(p3[i], myp2[j]);
	}

	tmplen = num1 + num2;
	//*num3 = num1 + num2;

	//排序
	for (i=0; i<tmplen; i++)
	{
		for (j=i+1; j<tmplen; j++)
		{
			if ( strcmp(p3[i], p3[j]) > 0 )
			{
				tmpP = p3[i];
				p3[i] = p3[j];
				p3[j] = tmpP;
			}
		}
	}

	//间接赋值
	*num3 = tmplen;
	*myp3 = p3;
	return 0;
}

void sortFree01(char **p, int len)
{
	int i = 0;
	if (p == NULL)
	{
		return ;
	}

	for (i=0; i<len ; i++)
	{
		free(p[i]);
	}
	free(p);
}

void sortFree02(char ***myp, int len) //把二级指针指向二维内存释放掉,,同时间接的修改了实参的值
{
	int i = 0;
	char **p = NULL;
	if (myp == NULL)
	{
		return ;
	}

	p  = *myp; //还原成二级指针
	if (p == NULL)
	{
		return ;
	}

	for (i=0; i<len ; i++)
	{
		free(p[i]);
	}
	free(p);
	//myp 是实参的地址
	*myp = NULL; //间接赋值是指针存在的最大意义
}

int  main()
{
	int ret = 0;
	char *p1[] = {"aa", "ccccccc", "bbbbbb"};
	char buf2[10][30] = {"111111", "3333333", "222222"};
	char **p3 = NULL;
	int len1, len2, len3, i = 0;

	len1 = sizeof(p1)/sizeof(*p1);
	len2 = 3;

	ret = sort(p1, len1, buf2, len2, &p3, &len3);
	if (ret != 0)
	{
		printf("func sort() err:%d \n", ret);
		return ret;
	}

	for (i=0; i<len3; i++)
	{
		printf("%s\n", p3[i]);
	}

	printf("hello...\n");
	return ret;
}
[email protected]:~/high$ 
编译
[email protected]:~/high$ gcc teacher.c  && ./a.out 
111111
222222
3333333
aa
bbbbbb
ccccccc
hello...
[email protected]:~/high$

结构体浅拷贝

[email protected]:~/high$ cat main.c 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct teacher
{
	char name[60];
	int age;
	char *alias_name;
};

int main()
{
	struct teacher t1;
	struct teacher t2;

	strcpy(t1.name,"chunli");
	t1.age = 22;
	t1.alias_name = (char *)malloc(100);
	strcpy(t1.alias_name,"chunli_alias");
	printf("%s \n",t1.name);
	printf("%d \n",t1.age);
	printf("%s \n",t1.alias_name);

	//t2 = t1;		//这两个拷贝方式的效果一样
	//编译器的 = 操作只会把指针变量的值 拷贝过去
	//但不会把指针指向的内存空间拷贝过去
	memcpy(&t2,&t1,sizeof(struct teacher));

	printf("%s \n",t2.name);
	printf("%d \n",t2.age);
	printf("%s \n",t2.alias_name);

	if(t1.alias_name != NULL)
	{
		free(t1.alias_name);
		t1.alias_name =NULL;
	}

	if(t2.alias_name != NULL)
	{
		free(t2.alias_name);//程序会在这里宕掉因为别人已经释放了那片区域
		t2.alias_name =NULL;
	}

	return 0;
}

[email protected]:~/high$ 

[email protected]:~/high$ 
[email protected]:~/high$ gcc -g main.c  && ./a.out 
chunli 
22 
chunli_alias 
chunli 
22 
chunli_alias 
*** Error in `./a.out‘: double free or corruption (fasttop): 0x00000000025a8010 ***
Aborted (core dumped)
[email protected]:~/high$

结构体深度拷贝

[email protected]:~/high$ cat main.c 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct teacher
{
	char name[60];
	int age;
	char *alias_name;
};

int main()
{
	struct teacher t1;
	struct teacher t2;

	strcpy(t1.name,"chunli");
	t1.age = 22;
	t1.alias_name = (char *)malloc(100);
	strcpy(t1.alias_name,"chunli_alias");
	printf("%s \n",t1.name);
	printf("%d \n",t1.age);
	printf("%s \n",t1.alias_name);

	//编译器的 = 操作只会把指针变量的值 拷贝过去
	//但不会把指针指向的内存空间拷贝过去
	//t2 = t1;		//这两个拷贝方式的效果一样
	memcpy(&t2,&t1,sizeof(struct teacher));
	t2.alias_name = (char*)malloc(100);	//为t2 打造内存空间
	strcpy(t2.alias_name,t1.alias_name);	//深度拷贝

	printf("%s \n",t2.name);
	printf("%d \n",t2.age);
	printf("%s \n",t2.alias_name);

	if(t1.alias_name != NULL)
	{
		free(t1.alias_name);
		t1.alias_name =NULL;
	}

	if(t2.alias_name != NULL)
	{
		free(t2.alias_name);//程序会在这里不会宕掉因为t2有自己的内存空间
		t2.alias_name =NULL;
	}

	return 0;
}

[email protected]:~/high$ gcc -g main.c  && ./a.out 
chunli 
22 
chunli_alias 
chunli 
22 
chunli_alias 
[email protected]:~/high$ 
[email protected]:~/high$ 
[email protected]:~/high$

结构体高级话题偏移量1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct teacher
{
        char name[60];
        int age;
        char *alias_name;
};

int main()
{
        struct teacher t1;
        struct teacher *p1;
        p1 -1;
        p1 -2;
        p1 -3;
        p1 - p1;
        int offsize = (int)&(p1->age);
        printf("%d\n",offsize);

        return 0;
}
编译
[email protected]:~/high$ gcc -g main.c  && ./a.out 
main.c: In function ‘main’:
main.c:20:16: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
  int offsize = (int)&(p1->age);
                ^
1327912356

结构体高级话题偏移量2

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct teacher
{
        char name[60];
        int age;
        char *alias_name;
};

int main()
{
        struct teacher t1;
        struct teacher *p1;
        p1 -1;
        p1 -2;
        p1 -3;
        p1 - p1;
        //告诉编译器struct teacher *从0到age有多大
        int offsize = (int)&(((struct teacher *)0)->age);
        printf("%d\n",offsize);

        return 0;
}
编译
[email protected]:~/high$ gcc -g main.c  && ./a.out 
main.c: In function ‘main’:
main.c:21:16: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
  int offsize = (int)&(((struct teacher *)0)->age);
                ^
60

【文件操作】

// 把字符写入文件

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
        FILE *p = fopen("./hello","w"); 
        if(p == NULL)
        {
                printf("error in fopen\n");
        }

        char *str = "Hello World!\n";
        int i = 0;
        for(i = 0;i<strlen(str);i++)
        {
                fputc(str[i],p);
        }
        fclose(p);

        return 0;
}
编译
[email protected]:~/high$ gcc -g main.c  && ./a.out 
[email protected]:~/high$ cat hello 
Hello World!

// 读文件

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
        FILE *p = fopen("./hello","r+");
        if(p == NULL)
        {
                printf("error in fopen\n");
        }
        while(!feof(p))
        {
                char c = fgetc(p);
                printf("%c",c);
        }
        if(p != NULL)
        {
                fclose(p);
        }

        return 0;
}
[email protected]:~/high$ gcc -g main.c  && ./a.out 
Hello World!

// fputs写文件

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
        FILE *p = fopen("./hello","r+");
        if(p == NULL)
        {
                printf("error in fopen\n");
        }
        char *str = "Hello ...\n";
        fputs(str,p);
        if(p != NULL)
        {
                fclose(p);
        }

        return 0;
}
编译运行
[email protected]:~/high$ cat hello 
Hello ...
d!
可以看出残缺覆盖

fgets读文件

// fgets读文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
        FILE *p = fopen("./hello","r+");
        if(p == NULL)
        {
                printf("error in fopen\n");
        }
        char buf[1024];
        while(!feof(p))
        {
                fgets(buf,1024,p);
                printf("%s",buf);
        }
        if(p != NULL)
        {
                fclose(p);
        }

        return 0;
}
Linux下运行
[email protected]:~/high$ cat hello 
2222222222222222222222
ffffffffffffffffff
3333
[email protected]:~/high$ gcc -g main.c  && ./a.out 
2222222222222222222222
ffffffffffffffffff
3333
3333
不明白为什么会多一行
在win下面就是正常的
网上查了一下linux的feof函数有问题

把结构体写入文件

[email protected]:~/high$ cat main.c 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct teacher
{
	char name[64];
	int age;
}teacher;

int main()
{
	FILE *fp = NULL;
	char *filename = "./hello";
	teacher teacher_arr[3];
	int i = 0;
	for(i = 0;i<3;i++)		//初始化结构体
	{
		sprintf(teacher_arr[i].name,"%d,%d,%d",i,i+i,i*i);
		teacher_arr[i].age = i + 30;
	}

	fp = fopen(filename,"wb");	//打开文件
	if(fp == NULL)
	{
		return -1;
	}

	for(i = 0;i<3;i++)		//写入数据到文件
	{
		size_t write_num = fwrite(&teacher_arr[i],sizeof(teacher),1,fp);
		if(!write_num)
		{
			printf("磁盘满\n");
		}
	}

	if(fp != NULL)
	{
		fclose(fp);
	}

	return 0;
}

[email protected]:~/high$ gcc -g main.c  && ./a.out 
[email protected]:~/high$ cat hello 
0,0,0ɡ .1,2,1-..N=栀戀-..h愀嘂2,4,[email protected]僻戀-. [email protected]:~/high$ Xshell^C
[email protected]:~/high$ hexdump hello 
0000000 2c30 2c30 0030 0000 e1c8 569c 7ff4 0000
0000010 0000 0000 0000 0000 0000 0000 0000 0000
*
0000030 0000 0000 0000 0000 e520 569c 7ff4 0000
0000040 001e 0000 2c31 2c32 0031 0e2d 7ffe 0000
0000050 4e2e f63d 0000 0000 03a4 0040 0000 0000
0000060 ffff ffff 0000 0000 6268 0e2d 7ffe 0000
0000070 51f8 563f 7ff4 0000 b568 569c 7ff4 0000
0000080 e1c8 569c 001f 0000 2c32 2c34 0034 0000
0000090 0001 0000 0000 0000 083d 0040 0000 0000
00000a0 6170 0e2d 7ffe 0000 0000 0000 0000 0000
00000b0 07f0 0040 0000 0000 0570 0040 0000 0000
00000c0 6250 0e2d 7ffe 0000 0020 0000          
00000cc
[email protected]:~/high$

从二进制文件中读取结构体数据

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct teacher
{
        char name[64];
        int age;
}teacher;

int main()
{
        FILE *fp = NULL;
        char *filename = "./hello";
        teacher teacher_arr[3];
        int i = 0;

        fp = fopen(filename,"rb");      //打开文件
        if(fp == NULL)  return -1;

        for(i = 0;i<3;i++)              //写入数据到文件
        {
                size_t write_num = fread(&teacher_arr[i],sizeof(teacher),1,fp);
        }
        if(fp != NULL)  fclose(fp);
        for(i = 0;i<3;i++)              //初始化结构体
        {
                printf("%s ->",teacher_arr[i].name);
                printf("%d \n",teacher_arr[i].age);
        }
        
        return 0;
}
编译
[email protected]:~/high$ gcc -g main.c  && ./a.out 
0,0,0 ->30 
1,2,1 ->31 
2,4,4 ->32 
[email protected]:~/high$

【C语言 文件项目】

1程序的配置文件

2配置文件信息以key value存放

3应用层 与 底层文件操作分开

4应用层查的时候输入key返回value

5应用层改的时候输入keyvalue。如果key存在就修改。如果key不存在则追加一条记录

我的代码文件

[email protected]:~/high$ ll
total 36K
-rw-rw-r-- 1 chunli chunli 2.6K Jun 21 15:50 cfg_op.c
-rw-rw-r-- 1 chunli chunli  340 Jun 21 12:35 cfg_op.h
-rw-rw-r-- 1 chunli chunli 1.4K Jun 21 15:49 main.c
-rw-r--r-- 1 chunli chunli   34 Jun 21 15:51 mycfg.ini

文件1

[email protected]:~/high$ cat cfg_op.h 
#ifndef __CFG_OP_H__
#define __CFG_OP_H__

	#ifdef __cplusplus
	extern "C"{
	#endif
		int GetCfgItem(char *pFileNmae/*in*/,char *pKey/*in*/,char*pValue/*in out*/,int *pValueLen/*out*/);
		int WriteCfgItem(char *pFilename/*in*/,char *pItemName /*in*/,char *pItemValue/*in*/,int itemCalueLen/*in*/ );
	#ifdef __cplusplus
	}
	#endif

#endif
[email protected]:~/high$

文件2

[email protected]:~/high$ cat cfg_op.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXline  1024

int GetCfgItem(char *pFileNmae/*in*/,char *pKey/*in*/,char*pValue/*in out*/,int *pValueLen/*out*/)
{
	int ret = 0;
	FILE *fp = NULL;
	fp = fopen(pFileNmae,"r+");
	if(fp == NULL) 
	{
		return -1;
		printf("open file %s error\n",pFileNmae);
	}
	char linebuf[MAXline];
	while(!feof(fp))
	{
		memset(linebuf,0,1024);
		char *find = NULL;
		fgets(linebuf,MAXline,fp);
		find = strstr(linebuf,pKey);	if(find == NULL){continue;}	//没找到key
		find = strstr(linebuf,"=");	if(find == NULL){continue;}	//也没有"="
		find = find + strlen("=");
		char *p_head = NULL;
		char *p_tail = NULL;
		while(1)
		{
			if(*find == ‘ ‘)	{find++;}
			else
			{
				p_head = find;
				if(*find == ‘\n‘)
				{
					ret = -1;
					goto End;
					printf("没有找到 %s 对应的value\n",pKey);
				}
				break;
			}
		}
		while(1)
		{
			if( (*find == ‘ ‘) || (*find == ‘\n‘) )
			{
				break;
			}
			else
			{
				*find++;
			}
		}
		p_tail = find;
		*pValueLen  = p_tail - p_head;
		memcpy(pValue,p_head,p_tail - p_head);
	}

End:
	fclose(fp);
	return ret;
}
int WriteCfgItem(char *pFilename/*in*/,char *pKey /*in*/,char *pValue/*in*/,int ValueLen/*in*/ )
{
	int ret = 0;
	int iTag = 0;
	int leng = 0;
	char linebuf[MAXline];
	FILE *fp = NULL;
	char *pTmp = NULL;
	char *pBegin = NULL;
	char *pEnd = NULL;
	char filebuf[1024 *8] = {0};
	if(pFilename == NULL) {return -1;}
	if(pKey == NULL) {return -2;}
	if(pValue == NULL) {return -3;}
	fp = fopen(pFilename,"r+");
	if(fp == NULL)
	{
		printf("文件打开失败,正在创建\n");
		fp = fopen(pFilename,"w+t");
		if(fp == NULL)
		{
			ret = -4;
			printf("文件创建也失败了\n");
			goto End;
		}
	}
	fseek(fp,0L,SEEK_END);
	leng = ftell(fp);
	fseek(fp,0L,SEEK_SET);
	if(leng > 1024 * 8)
	{
		ret = -5;
		printf("文件太大了\n");
		goto End;

	}
	while(!feof(fp))
	{
		memset(linebuf,MAXline,sizeof(linebuf));
		pTmp = fgets(linebuf,MAXline,fp);
		if(pTmp == NULL)
		{
			break;
		}
		pTmp = strstr(linebuf,pKey);
		if(pTmp == NULL)
		{
			strcat(filebuf,linebuf);
			continue;
		}
		else
		{
			sprintf(linebuf,"%s = %s\n",pKey,pValue);
			strcat(filebuf,linebuf);
			iTag = 1;
		}
	}

		if(iTag == 0)
		{
			fprintf(fp,"%s = %s\n",pKey,pValue);
		}
		else
		{
			if(fp == NULL)
			{
				fclose(fp);
				fp = NULL;
			}
			fp = fopen(pFilename,"w+t");
			if(fp == NULL)
			{
				ret = -5;
				printf("ERROR Create file!\n");
				goto End;
			}
			fputs(filebuf,fp);
			//fwrtite(filebuf,sizeof(char),strlen(filebuf),fp);
		}

End:
	if(fp != NULL)
	{
		fclose(fp);
		fp = NULL;
	}
	return ret;
}

[email protected]:~/high$

文件3

[email protected]:~/high$ cat main.c 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cfg_op.h"

char *filename = "mycfg.ini";

void printf_menu()
{
	printf("\t\t*********************************\n");
	printf("\t\t[1]读配置文件\n");
	printf("\t\t[2]写配置文件\n");
	printf("\t\t[0]退出\n");
	printf("\t\t*********************************\n");
}

int TGetCfg()
{
	char name[1024] = {0};
	char valude[1024] = {0};
	int vlen = 0;
	printf("进入读文件模式\n");
	printf("请输入key ");
	scanf("%s",name);
	int ret =  GetCfgItem(filename,name,valude,&vlen);
	if(ret != 0)
	{
		printf("ERROR in GetCfgItem \n");
		return ret;
	}
	printf("读取结果%s -> %s \n",name,valude);
	return ret;
}
int TWriteCfg()
{
	char name[1024] = {0};
	char valude[1024] = {0};
	printf("进入配置文件的修改或添加模式\n");
	printf("请输入key valude: ");
	scanf("%s %s",name,valude);
	int ret =  WriteCfgItem(filename,name,valude,strlen(valude));
	if(ret != 0)
	{
		printf("ERROR in WriteCfgItem \n");
		return ret;
	}
	printf("您的输入是:%s -> %s \n",name,valude);
	return ret;
}

int main()
{
	int choice_num;
	while(1)
	{
		printf_menu();
		scanf("%d",&choice_num);
		switch(choice_num)
		{
			case 0:
				exit(0);
			case 1:
				TGetCfg();
				break;
			case 2:
				TWriteCfg();
				break;
			default:
				exit(0);
		}
	}
	return 0;
}

[email protected]:~/high$

编译运行

[email protected]:~/high$ gcc -g -o run main.c  cfg_op.c  && ./run
		*********************************
		[1]读配置文件
		[2]写配置文件
		[0]退出
		*********************************
1
进入读文件模式
请输入key 1
读取结果1 -> 2 
		*********************************
		[1]读配置文件
		[2]写配置文件
		[0]退出
		*********************************
2
进入配置文件的修改或添加模式
请输入key valude: 1 haha   
您的输入是:1 -> haha 
		*********************************
		[1]读配置文件
		[2]写配置文件
		[0]退出
		*********************************
1
进入读文件模式
请输入key 1
读取结果1 -> haha 
		*********************************
		[1]读配置文件
		[2]写配置文件
		[0]退出
		*********************************
0
[email protected]:~/high$

上面这道题老师的代码VS环境编译

文件1cfg_op.h

#ifndef __CFG_OP_H__
#define __CFG_OP_H__

#ifdef  __cplusplus
extern "C" {
#endif

//获取配置项
int GetCfgItem(char *pFileName /*in*/, char *pKey /*in*/, char * pValue/*in out*/, int * pValueLen /*out*/);

//写配置项 
int WriteCfgItem(char *pFileName /*in*/, char *pItemName /*in*/, char *pItemValue/*in*/, int itemValueLen /*in*/);

#ifdef  __cplusplus
}
#endif

#endif

文件2

cfg_op.c

#define  _CRT_SECURE_NO_WARNINGS 
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define MaxLine 2048 

//获取配置项
int GetCfgItem(char *pFileName /*in*/, char *pKey /*in*/, char * pValue/*in out*/, int * pValueLen /*out*/)
{

	int		ret = 0;
	FILE	*fp = NULL;
	char	*pTmp = NULL, *pEnd = NULL, *pBegin = NULL;

	char lineBuf[MaxLine];

	fp = fopen(pFileName, "r");
	if (fp == NULL)
	{
		ret = -1;
		return ret;
	}

	while (!feof(fp))
	{
		memset(lineBuf, 0, sizeof(lineBuf));
		 //fgets(_Out_z_cap_(_MaxCount) char * _Buf, _In_ int _MaxCount, _Inout_ FILE * _File);
		fgets(lineBuf, MaxLine, fp);
		//printf("lineBuf:%s ",lineBuf );

		pTmp = strchr(lineBuf, ‘=‘); //
		if (pTmp == NULL) //没有=号
		{
			continue;
		}

		pTmp = strstr(lineBuf, pKey);
		if (pTmp == NULL) //判断key是不是在 //所在行 是不是有key
		{
			continue;
		}
		pTmp = pTmp + strlen(pKey); //mykey1 = myvalude11111111 ==> "= myvalude1111111"

		pTmp = strchr(pTmp, ‘=‘);
		if (pTmp == NULL) //判断key是不是在 //所在行 是不是有key
		{
			continue;
		}
		pTmp = pTmp + 1;
		//
		//printf("pTmp:%s ", pTmp);

		//获取value 起点
		while (1) 
		{
			if (*pTmp == ‘ ‘)
			{
				pTmp ++ ;
			} 
			else
			{
				pBegin = pTmp;
				if (*pBegin == ‘\n‘)
				{
					//没有配置value
					//printf("配置项:%s 没有配置value \n", pKey);
					goto End;
				}
				break;
			}
		}

		//获取valude结束点
		while (1) 
		{
			if ((*pTmp == ‘ ‘ || *pTmp == ‘\n‘))
			{
				break;
			}
			else 
			{
				pTmp ++;
			}
		}
		pEnd = pTmp;

		//赋值
		*pValueLen = pEnd-pBegin;
		memcpy(pValue, pBegin, pEnd-pBegin);
	}

End:
	if (fp == NULL)
	{
		fclose(fp);
	}
	return 0;

}

//写配置项 
//实现流程
//循环读每一行检查key配置项是否存在 若存在修改对应value值
//若不存在在文件末尾 添加 "key = value"
//难点如何修改文件流中的值
int WriteCfgItem(char *pFileName /*in*/, char *pKey /*in*/, char * pValue/*in*/, int ValueLen /*in*/)
{
	int		rv = 0, iTag = 0, length = 0;
	FILE	*fp = NULL;
	char	lineBuf[MaxLine];
	char	*pTmp = NULL, *pBegin = NULL, *pEnd = NULL;
	char	filebuf[1024*8] = {0};

	if (pFileName==NULL || pKey==NULL || pValue==NULL) 
	{
		rv = -1;
		printf("SetCfgItem() err. param err \n");
		goto End;
	}

	fp = fopen(pFileName, "r+");
	if (fp == NULL)
	{
		rv = -2;
		printf("fopen() err. \n");
		//goto End;
	}

	if (fp == NULL)
	{
		fp = fopen(pFileName, "w+t");
		if (fp == NULL)
		{
			rv = -3;
			printf("fopen() err. \n");
			goto End;
		}
	}

	fseek(fp, 0L, SEEK_END); //把文件指针从0位置开始移动到文件末尾
	//获取文件长度;
	length = ftell(fp);

	fseek(fp, 0L, SEEK_SET);

	if (length > 1024*8) 
	{
		rv = -3;
		printf("文件超过1024*8, nunsupport");
		goto End;
	}

	while (!feof(fp))
	{
		//读每一行
		memset(lineBuf, 0, sizeof(lineBuf));
		pTmp = fgets(lineBuf, MaxLine, fp);
		if (pTmp == NULL) 
		{
			break;
		}

		//key关键字是否在本行
		pTmp = strstr(lineBuf, pKey);
		if (pTmp == NULL) //key关键字不在本行 copy到filebuf中
		{
			strcat(filebuf, lineBuf);
			continue;
		}
		else  //key关键在在本行中替换旧的行再copy到filebuf中 
		{
			sprintf(lineBuf, "%s = %s\n", pKey, pValue);  
			strcat(filebuf, lineBuf);
			//若存在key
			iTag = 1; 
		}
	}

	//若key关键字不存在 追加
	if (iTag == 0) 
	{
		fprintf(fp, "%s = %s\n", pKey, pValue);
	}
	else //若key关键字存在则重新创建文件
	{
		if (fp != NULL) 
		{ 
			fclose(fp); 
			fp = NULL; //避免野指针
		}

		fp = fopen(pFileName, "w+t"); 
		if (fp == NULL)
		{
			rv = -4;
			printf("fopen() err. \n");
			goto End;
		}
		fputs(filebuf, fp);
		//fwrite(filebuf, sizeof(char), strlen(filebuf), fp);
	}

End:
	if (fp != NULL)
	{
		fclose(fp); 
	}
	return rv;
}

文件3

#define  _CRT_SECURE_NO_WARNINGS 
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "cfg_op.h"

#define CFGNAME "c:/mycfg.ini"
void mymenu()
{
	printf("=============================\n");
	printf("1 测试写配置文件\n");
	printf("2 测试读配置文件\n");
	printf("0 退出\n");
	printf("=============================\n");
}

//获取配置项
int TGetCfg()
{
	int		ret = 0;
	//读配置项 
	char	name[1024] = {0};
	char	valude[1024] = {0};
	int		vlen = 0;

	printf("\n请键入key:");
	scanf("%s", name);

	ret = GetCfgItem(CFGNAME /*in*/, name /*in*/, valude/*in*/, &vlen);
	if (ret != 0)
	{
		printf("func WriteCfgItem err:%d \n", ret);
		return ret;
	}
	printf("valude:%s \n", valude);

}

//写配置项 
int TWriteCfg()
{
	int		ret = 0;
	//写配置项 
	char name[1024] = {0};
	char valude[1024] = {0};

	printf("\n请键入key:");
	scanf("%s", name);

	printf("\n请键入valude:");
	scanf("%s", valude);

	ret = WriteCfgItem(CFGNAME /*in*/, name /*in*/, valude/*in*/,strlen(valude) /*in*/);
	if (ret != 0)
	{
		printf("func WriteCfgItem err:%d \n", ret);
		return ret;
	}
	printf("你的输入是%s = %s \n", name , valude);
	return ret;
}

void main()
{

	int choice;

	for (;;)
	{
		//显示一个菜单
		mymenu();
		scanf("%d", &choice);
		switch (choice)
		{

		case 1:   //写配置项
			TWriteCfg();
			break;
		case 2: 
			TGetCfg(); //读配置项
			break;
		case 0: 
			exit(0);
		default:;
			exit(0);
		}

	}
	printf("hello...\n");
	system("pause");
	return ;
}

文件专业加密:

VS编译OK

GCC编译不正常。

4个文件:

文件1:des.h

/*********************************************************
 *  des.h
 *  用户使用des算法头文件
 *
 *********************************************************/
#ifndef _OPENDESS_H_
#define _OPENDESS_H_

#ifdef __cplusplus
extern "C" {
#endif

//ab\0defg

//用户使用的函数
int DesEnc(
		unsigned char *pInData,
		int            nInDataLen,
		unsigned char *pOutData,
		int           *pOutDataLen);

//用户使用函数des解密
int DesDec(
	   unsigned char *pInData,
	   int            nInDataLen,
	   unsigned char *pOutData,
	   int           *pOutDataLen);

#ifdef __cplusplus
}
#endif

#endif

文件2,des.c

/******************************************************
 *
 *  des.c
 *  common des......
 *
 ******************************************************/

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "des.h"

/*********************************************************
  data type definition for Des;
**********************************************************/
#define EN0	0
#define DE1	1

#define DES_KEYBYTES	128
#define DES_KEYLONGS	32
#define DES_BLOCKLEN	8

typedef struct {
	unsigned char ek[DES_KEYBYTES];
	int	ekLen;
	unsigned char dk[DES_KEYBYTES];
	int	dkLen;
	unsigned char CbcCtx[DES_BLOCKLEN];
} DES_CTX;

typedef struct {
	unsigned char ek1[DES_KEYBYTES];
	int	ek1Len;
	unsigned char dk1[DES_KEYBYTES];
	int	dk1Len;
	unsigned char ek2[DES_KEYBYTES];
	int	ek2Len;
	unsigned char dk2[DES_KEYBYTES];
	int	dk2Len;
	unsigned char CbcCtx[DES_BLOCKLEN];
	//int	IsFirstBlock;
} DES3_CTX;

static unsigned char pc1[56] = {
	56, 48, 40, 32, 24, 16,  8,  0, 57, 49, 41, 33, 25, 17,
	 9,  1, 58, 50, 42, 34, 26, 18, 10,  2, 59, 51, 43, 35,
	62, 54, 46, 38, 30, 22, 14,  6, 61, 53, 45, 37, 29, 21,
	13,  5, 60, 52, 44, 36, 28, 20, 12,  4, 27, 19, 11,  3 };

static unsigned char pc2[48] = {
	13, 16, 10, 23,  0,  4,		 2, 27, 14,  5, 20,  9,
	22, 18, 11,  3, 25,  7, 	15,  6, 26, 19, 12,  1,
	40, 51, 30, 36, 46, 54,		29, 39, 50, 44, 32, 47,
	43, 48, 38, 55, 33, 52, 	45, 41, 49, 35, 28, 31 };

static unsigned short bytebit[8] = {0200,0100,040,020,010,04,02,01 };
static unsigned char totrot[16] = {1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28};
static unsigned long bigbyte[24] = {
	0x800000L,	0x400000L,	0x200000L,	0x100000L,
	0x80000L,	0x40000L,	0x20000L,	0x10000L,
	0x8000L,	0x4000L,	0x2000L,	0x1000L,
	0x800L,		0x400L,		0x200L,		0x100L,
	0x80L,		0x40L,		0x20L,		0x10L,
	0x8L,		0x4L,		0x2L,		0x1L	};

//insert digits
static unsigned long SP1[64] ={
       0x01010400l,0x00000000l,0x00010000l,0x01010404l,
       0x01010004l,0x00010404l,0x00000004l,0x00010000l,
       0x00000400l,0x01010400l,0x01010404l,0x00000400l,
       0x01000404l,0x01010004l,0x01000000l,0x00000004l,
       0x00000404l,0x01000400l,0x01000400l,0x00010400l,
       0x00010400l,0x01010000l,0x01010000l,0x01000404l,
       0x00010004l,0x01000004l,0x01000004l,0x00010004l,
       0x00000000l,0x00000404l,0x00010404l,0x01000000l,
       0x00010000l,0x01010404l,0x00000004l,0x01010000l,
       0x01010400l,0x01000000l,0x01000000l,0x00000400l,
       0x01010004l,0x00010000l,0x00010400l,0x01000004l,
       0x00000400l,0x00000004l,0x01000404l,0x00010404l,
       0x01010404l,0x00010004l,0x01010000l,0x01000404l,
       0x01000004l,0x00000404l,0x00010404l,0x01010400l,
       0x00000404l,0x01000400l,0x01000400l,0x00000000l,
       0x00010004l,0x00010400l,0x00000000l,0x01010004l };
       
       
static unsigned long SP2[64]={
       0x80108020l,0x80008000l,0x00008000l,0x00108020l,
       0x00100000l,0x00000020l,0x80100020l,0x80008020l,
       0x80000020l,0x80108020l,0x80108000l,0x80000000l,
       0x80008000l,0x00100000l,0x00000020l,0x80100020l,
       0x00108000l,0x00100020l,0x80008020l,0x00000000l,
       0x80000000l,0x00008000l,0x00108020l,0x80100000l,
       0x00100020l,0x80000020l,0x00000000l,0x00108000l,
       0x00008020l,0x80108000l,0x80100000l,0x00008020l,
       0x00000000l,0x00108020l,0x80100020l,0x00100000l,
       0x80008020l,0x80100000l,0x80108000l,0x00008000l,
       0x80100000l,0x80008000l,0x00000020l,0x80108020l,
       0x00108020l,0x00000020l,0x00008000l,0x80000000l,
       0x00008020l,0x80108000l,0x00100000l,0x80000020l,
       0x00100020l,0x80008020l,0x80000020l,0x00100020l,
       0x00108000l,0x00000000l,0x80008000l,0x00008020l,
       0x80000000l,0x80100020l,0x80108020l,0x00108000l };
       
       
static unsigned long SP3[64]={ 
       0x00000208l,0x08020200l,0x00000000l,0x08020008l,
       0x08000200l,0x00000000l,0x00020208l,0x08000200l,
       0x00020008l,0x08000008l,0x08000008l,0x00020000l,
       0x08020208l,0x00020008l,0x08020000l,0x00000208l,
       0x08000000l,0x00000008l,0x08020200l,0x00000200l,
       0x00020200l,0x08020000l,0x08020008l,0x00020208l,
       0x08000208l,0x00020200l,0x00020000l,0x08000208l,
       0x00000008l,0x08020208l,0x00000200l,0x08000000l,
       0x08020200l,0x08000000l,0x00020008l,0x00000208l,
       0x00020000l,0x08020200l,0x08000200l,0x00000000l,
       0x00000200l,0x00020008l,0x08020208l,0x08000200l,
       0x08000008l,0x00000200l,0x00000000l,0x08020008l,
       0x08000208l,0x00020000l,0x08000000l,0x08020208l,
       0x00000008l,0x00020208l,0x00020200l,0x08000008l,
       0x08020000l,0x08000208l,0x00000208l,0x08020000l,
       0x00020208l,0x00000008l,0x08020008l,0x00020200l };
       
       
static unsigned long SP4[64]={             
       0x00802001l,0x00002081l,0x00002081l,0x00000080l,
       0x00802080l,0x00800081l,0x00800001l,0x00002001l,
       0x00000000l,0x00802000l,0x00802000l,0x00802081l,
       0x00000081l,0x00000000l,0x00800080l,0x00800001l,
       0x00000001l,0x00002000l,0x00800000l,0x00802001l,
       0x00000080l,0x00800000l,0x00002001l,0x00002080l,
       0x00800081l,0x00000001l,0x00002080l,0x00800080l,
       0x00002000l,0x00802080l,0x00802081l,0x00000081l,
       0x00800080l,0x00800001l,0x00802000l,0x00802081l,
       0x00000081l,0x00000000l,0x00000000l,0x00802000l,
       0x00002080l,0x00800080l,0x00800081l,0x00000001l,
       0x00802001l,0x00002081l,0x00002081l,0x00000080l,
       0x00802081l,0x00000081l,0x00000001l,0x00002000l,
       0x00800001l,0x00002001l,0x00802080l,0x00800081l,
       0x00002001l,0x00002080l,0x00800000l,0x00802001l,
       0x00000080l,0x00800000l,0x00002000l,0x00802080l };
       
       
static unsigned long SP5[64]={   
       0x00000100l,0x02080100l,0x02080000l,0x42000100l,
       0x00080000l,0x00000100l,0x40000000l,0x02080000l,
       0x40080100l,0x00080000l,0x02000100l,0x40080100l,
       0x42000100l,0x42080000l,0x00080100l,0x40000000l,
       0x02000000l,0x40080000l,0x40080000l,0x00000000l,
       0x40000100l,0x42080100l,0x42080100l,0x02000100l,
       0x42080000l,0x40000100l,0x00000000l,0x42000000l,
       0x02080100l,0x02000000l,0x42000000l,0x00080100l,
       0x00080000l,0x42000100l,0x00000100l,0x02000000l,
       0x40000000l,0x02080000l,0x42000100l,0x40080100l,
       0x02000100l,0x40000000l,0x42080000l,0x02080100l,
       0x40080100l,0x00000100l,0x20000000l,0x42080000l,
       0x42080100l,0x00080100l,0x42000000l,0x42080100l,
       0x02080000l,0x02000100l,0x40000100l,0x00080000l,
       0x00080100l,0x02000100l,0x40000100l,0x00080000l,
       0x00000000l,0x40080000l,0x02080100l,0x40000100l };
       
       
static unsigned long SP6[64]={ 
       0x20000010l,0x20400000l,0x00004000l,0x20404010l,
       0x20400000l,0x00000010l,0x20404010l,0x00400000l,
       0x20004000l,0x00404010l,0x00400000l,0x20000010l,
       0x00400010l,0x20004000l,0x20000000l,0x00004010l,
       0x00000000l,0x00400010l,0x20004010l,0x00004000l,
       0x00404000l,0x20004010l,0x00000010l,0x20400010l,
       0x20400010l,0x00000000l,0x00404010l,0x20404000l,
       0x00004010l,0x00404000l,0x20404000l,0x20000000l,
       0x20004000l,0x00000010l,0x20400010l,0x00404000l,
       0x20404010l,0x00400000l,0x00004010l,0x20000010l,
       0x00400000l,0x20004000l,0x20000000l,0x00004010l,
       0x20000010l,0x20404010l,0x00404000l,0x20400000l,
       0x00404010l,0x20404000l,0x00000000l,0x20400010l,
       0x00000010l,0x00004000l,0x20400000l,0x00404010l,
       0x00004000l,0x00400010l,0x20004010l,0x00000000l,
       0x20404000l,0x20000000l,0x00400010l,0x20004010l };  
            
static unsigned long SP7[64] = {
	0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
	0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
	0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
	0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
	0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
	0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
	0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
	0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
	0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
	0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
	0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
	0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
	0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
	0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
	0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
	0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L };

static unsigned long SP8[64] = {
	0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
	0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
	0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
	0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
	0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
	0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
	0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
	0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
	0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
	0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
	0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
	0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
	0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
	0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
	0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
	0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L };

void deskey(unsigned char *key,short edf, unsigned long *kn);
void cookey(register unsigned long *raw1, unsigned long *dough);
//void cpkey(register unsigned long *into);
//void usekey(register unsigned long *from);
//void des(unsigned char *inblock,unsigned char *outblock);
void scrunch(register unsigned char *outof, register unsigned long *into);
void unscrun(register unsigned long *outof, register unsigned char *into);
void desfunc(register unsigned long *block,register unsigned long *keys);

/*****************  DES Function  *****************/
unsigned long OPENCOMM_DesExpandEncKey(
		unsigned char *pbDesKey,
		unsigned long  ulDesKeyLen,
		unsigned char *pbDesEncKey,
		unsigned long *ulDesEncKeyLen);

unsigned long OPENCOMM_DesExpandDecKey(
		unsigned char *pbDesKey,
		unsigned long  ulDesKeyLen,
		unsigned char *pbDesDecKey,
		unsigned long *ulDesDecKeyLen);

unsigned long OPENCOMM_DesEncRaw(
		unsigned char *pbDesEncKey,
		unsigned long  ulDesEncKeyLen,
		unsigned char *pbInData,
		unsigned long  ulInDataLen,
		unsigned char *pbOutData,
		unsigned long *ulOutDataLen);

unsigned long OPENCOMM_DesDecRaw(
		unsigned char *pbDesDecKey,
		unsigned long  ulDesDecKeyLen,
		unsigned char *pbInData,
		unsigned long  ulInDataLen,
		unsigned char *pbOutData,
		unsigned long *ulOutDataLen);

int myic_DESDecrypt(
		unsigned char *pDesKey,
		int            nDesKeyLen,
		unsigned char *pInData,
		int            nInDataLen,
		unsigned char *pOutData,
		int           *pOutDataLen);

int myic_DESEncrypt(
		unsigned char *pDesKey,
		int            nDesKeyLen,
		unsigned char *pInData,
		int            nInDataLen,
		unsigned char *pOutData,
		int           *pOutDataLen);

void deskey(unsigned char *key,short edf, unsigned long *kn)
{
	register int i, j, l, m, n;
	unsigned long pc1m[56],pcr[56];

	for ( j = 0; j < 56; j++ ) 
	{
		l = pc1[j];
		m = l & 07;
		pc1m[j] = (((unsigned long) key[l >> 3] & (unsigned long)bytebit[m] ) ? 1:0);
	}
	for ( i = 0;i < 16; i++)
	{
		if ( edf == DE1 )	m = (15 - i) << 1;
		else	m = i << 1;
		n = m + 1;
		kn[m] = kn[n] = 0L;
		for ( j = 0; j < 28; j++ )
		{
			l = j + totrot[i];
			if ( l < 28 )	pcr[j] = pc1m[l];
			else	pcr[j] = pc1m[l-28];
		}
		for (j = 28; j < 56; j++ ) 
		{
			l = j + totrot[i];
			if ( l < 56 )	pcr[j] = pc1m[l];
			else	pcr[j] = pc1m[l-28];
		} 
		for ( j = 0; j < 24; j++ ) 
		{
			if ( pcr[pc2[j]] )	kn[m] |= bigbyte[j];
			if ( pcr[pc2[j+24]] )	kn[n] |= bigbyte[j];
		}
	}
	return;
}

void cookey(register unsigned long *raw1, unsigned long *dough)
{
	register unsigned long *cook,*raw0;
	register int i;

	cook = dough;
	for ( i = 0; i < 16; i++, raw1++ ) {
		raw0 = raw1++;
		*cook	 = (*raw0 & 0x00fc0000L) << 6;
		*cook	|= (*raw0 & 0x00000fc0L) << 10;
		*cook	|= (*raw1 & 0x00fc0000L) >> 10;
		*cook++	|= (*raw1 & 0x00000fc0L) >> 6;
		*cook	 = (*raw0 & 0x0003f000L) << 12;
		*cook	|= (*raw0 & 0x0000003fL) << 16;
		*cook	|= (*raw1 & 0x0003f000L) >> 4;
		*cook++	|= (*raw1 & 0x0000003fL);
	}
	return;
}

void scrunch(register unsigned char *outof, register unsigned long *into)
{
	*into	 = (*outof++ & 0xffL) << 24;
	*into	|= (*outof++ & 0xffL) << 16;
	*into	|= (*outof++ & 0xffL) << 8;
	*into++	|= (*outof++ & 0xffL);
	*into	 = (*outof++ & 0xffL) << 24;
	*into	|= (*outof++ & 0xffL) << 16;
	*into	|= (*outof++ & 0xffL) << 8;
	*into++	|= (*outof   & 0xffL);
	return;
}

void unscrun(register unsigned long *outof, register unsigned char *into)
{
	*into++	 = (unsigned char)((*outof >> 24) & 0xffL);
	*into++	 = (unsigned char)((*outof >> 16) & 0xffL);
	*into++	 = (unsigned char)((*outof >>  8) & 0xffL);
	*into++	 = (unsigned char)( *outof++	  & 0xffL);
	*into++	 = (unsigned char)((*outof >> 24) & 0xffL);
	*into++	 = (unsigned char)((*outof >> 16) & 0xffL);
	*into++	 = (unsigned char)((*outof >>  8) & 0xffL);
	*into	 = (unsigned char)( *outof		  & 0xffL);
	return;
}

void desfunc(register unsigned long *block,register unsigned long *keys)
{
	register unsigned long fval, work, right, leftt;
	register int round;

	leftt = block[0];
	right = block[1];
	work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;

	right ^= work;
	leftt ^= (work << 4);
	work = ((leftt >> 16) ^ right) & 0x0000ffffL;

	right ^= work;
	leftt ^= (work << 16);
	work = ((right >> 2) ^ leftt) & 0x33333333L;

	leftt ^= work;
	right ^= (work << 2);
	work = ((right >> 8) ^ leftt) & 0x00ff00ffL;

	leftt ^= work;
	right ^= (work << 8);
	right = ((right << 1) | ((right >>31) & 1L)) & 0xffffffffL;
	work = (leftt ^ right) & 0xaaaaaaaaL;

	leftt ^= work;
	right ^= work;
	leftt = ((leftt << 1) | ((leftt >> 31)&1L)) & 0xffffffffL;

	for (round = 0; round < 8; round++) {
		work  = (right << 28) | (right >> 4);
		work ^= *keys++;
		fval  = SP7[ work	& 0x3fL];
		fval |= SP5[(work >>  8) & 0x3fL];
		fval |= SP3[(work >> 16) & 0x3fL];
		fval |= SP1[(work >> 24) & 0x3fL];
		work  = right ^ *keys++;
		fval |= SP8[ work 	& 0x3fL];
		fval |= SP6[(work >>  8) & 0x3fL];
		fval |= SP4[(work >> 16) & 0x3fL];
		fval |= SP2[(work >> 24) & 0x3fL];
		leftt ^= fval;
		work  = (leftt << 28) | (leftt >> 4);
		work ^= *keys++;
		fval  = SP7[ work 	& 0x3fL];
		fval |= SP5[(work >>  8) & 0x3fL];
		fval |= SP3[(work >> 16) & 0x3fL];
		fval |= SP1[(work >> 24) & 0x3fL];
		work  = leftt ^ *keys++;
		fval |= SP8[ work 	& 0x3fL];
		fval |= SP6[(work >>  8) & 0x3fL];
		fval |= SP4[(work >> 16) & 0x3fL];
		fval |= SP2[(work >> 24) & 0x3fL];
		right ^= fval;
	}

	right = (right << 31) | (right >> 1);
	work = (leftt ^ right) & 0xaaaaaaaaL;
	leftt ^= work;
	right ^= work;
	leftt = (leftt << 31) | (leftt >> 1);
	work = ((leftt >>  8) ^ right) & 0x00ff00ffL;
	right ^= work;
	leftt ^= (work << 8);
	work = ((leftt >>  2) ^ right) & 0x33333333L;
	right ^= work;
	leftt ^= (work << 2);
	work = ((right >> 16) ^ leftt) & 0x0000ffffL;
	leftt ^= work;
	right ^= (work << 16);
	work = ((right >>  4) ^ leftt) & 0x0f0f0f0fL;
	leftt ^= work;
	right ^= (work << 4);
	*block++ = right;
	*block = leftt;
	return;
}

/*****************************************************************
	OPENCOMM_DesExpandEncKey	: Expand Des Enc Key 扩展des加密密钥
	Return value:
		0         : Success
		other     : failed
	Parameters:
		pbDesKey        : 扩展前的DES密钥(8字节)       input
		ulDesKeyLen     : 扩展前的DES密钥长度          input
		pbDesEncKey     : 扩展后的DES加密密钥(128字节)  output
		*ulDesEncKeyLen : 扩展后的DES加密密钥长度       output
*****************************************************************/
unsigned long OPENCOMM_DesExpandEncKey(
		unsigned char *pbDesKey,
		unsigned long  ulDesKeyLen,
		unsigned char *pbDesEncKey,
		unsigned long *ulDesEncKeyLen)
{
	unsigned long kn[32], dough[32];

	if (ulDesKeyLen != 8)
		return 0xEE20;

	deskey(pbDesKey, EN0, kn);
	cookey(kn, dough);
	*ulDesEncKeyLen = DES_KEYBYTES;  //32 long = 128 bytes
	memcpy(pbDesEncKey, dough, *ulDesEncKeyLen);

	return 0;
}

/*****************************************************************
	OPENCOMM_DesExpandDecKey	: Expand Des Dec Key 扩展des解密密钥
	Return value:
		0       : Success
		other   : failed
	Parameters:
		pbDesKey        : 扩展前的DES密钥(8字节)      input
		ulDesKeyLen     : 扩展前的DES密钥长度         input
		pbDesDecKey     : 扩展后的DES解密密钥(128字节) output
		*ulDesDecKeyLen : 扩展后的DES解密密钥长度      output
*****************************************************************/
unsigned long OPENCOMM_DesExpandDecKey(
		unsigned char *pbDesKey,
		unsigned long  ulDesKeyLen,
		unsigned char *pbDesDecKey,
		unsigned long *ulDesDecKeyLen)
{
	unsigned long kn[32], dough[32];

	if (ulDesKeyLen != 8)
		return 0xEE20;

	deskey(pbDesKey, DE1, kn);
	cookey(kn, dough);
	*ulDesDecKeyLen = DES_KEYBYTES;  //32 long = 128 bytes
	memcpy(pbDesDecKey, dough, *ulDesDecKeyLen);

	return 0;
}

/****************************************************************
	OPENCOMM_DesEncRaw		: Des算法加密小整块明文8字节 
	Return value:
		0       : Success
		other   : failed
	Parameters:
		pbDesEncKey    : DES加密密钥    input
		ulDesEncKeyLen : DES加密密钥长度 input
		pbInData       : 待加密的明文    input
		ulInDataLen    : 待加密的明文长度 input
		pbOutData      : 加密后的密文    output
		*ulOutDataLen  : 加密后的密文长度 output
*****************************************************************/
unsigned long OPENCOMM_DesEncRaw(
		unsigned char *pbDesEncKey,
		unsigned long  ulDesEncKeyLen,
		unsigned char *pbInData,
		unsigned long  ulInDataLen,
		unsigned char *pbOutData,
		unsigned long *ulOutDataLen)
{
	unsigned long work[2], ek[DES_KEYLONGS];
	unsigned char cp[DES_BLOCKLEN];

	if (ulInDataLen != DES_BLOCKLEN)
		return 0xEE20;

	if (ulDesEncKeyLen != DES_KEYBYTES)
		return 0xEE20;

	memcpy(cp, pbInData, DES_BLOCKLEN);
	scrunch(cp,work);  // 8 bytes -> 2 long
	memcpy(ek, pbDesEncKey, ulDesEncKeyLen);
	desfunc(work,ek);
	unscrun(work,cp); // 2 long -> 8 bytes
	memcpy(pbOutData, cp, DES_BLOCKLEN);
	*ulOutDataLen = DES_BLOCKLEN;

	return 0;
}

/*****************************************************************
	OPENCOMM_DesDecRaw : Des算法解密小整块密文8字节 
	Return value:
		0     : Success
		other : failed
	Parameters:
		pbDesDecKey    : DES解密密钥     input
		ulDesDecKeyLen : DES解密密钥长度  input
		pbInData       : 待解密的密文     input
		ulInDataLen    : 待解密的密文长度  input
		pbOutData      : 解密后的明文     output
		*ulOutDataLen  : 解密后的明文长度  output
*****************************************************************/
unsigned long OPENCOMM_DesDecRaw(
		unsigned char *pbDesDecKey,
		unsigned long  ulDesDecKeyLen,
		unsigned char *pbInData,
		unsigned long  ulInDataLen,
		unsigned char *pbOutData,
		unsigned long *ulOutDataLen)
{
	unsigned long work[2], dk[DES_KEYLONGS];
	unsigned char cp[DES_BLOCKLEN];

	if (ulInDataLen != DES_BLOCKLEN)
		return 0xEE20;

	if (ulDesDecKeyLen != DES_KEYBYTES)
		return 0xEE20;

	memcpy(cp, pbInData, DES_BLOCKLEN);
	scrunch(cp,work);  // 8 bytes -> 2 long
	memcpy(dk, pbDesDecKey, ulDesDecKeyLen);
	desfunc(work,dk);
	unscrun(work,cp); // 2 long -> 8 bytes
	memcpy(pbOutData, cp, DES_BLOCKLEN);
//	des_enc(pbDesEncKey, pbInData, pbOutData);
	*ulOutDataLen = DES_BLOCKLEN;

	return 0;
}

/*********************   DES    *********************/

int myic_DESEncrypt(
		unsigned char *pDesKey,
		int            nDesKeyLen,
		unsigned char *pInData,
		int            nInDataLen,
		unsigned char *pOutData,
		int           *pOutDataLen)
{
	unsigned char DesKeyBuf[32];
	unsigned char DesEncKeyBuf[128];
	int EncKeyLen, KeyLen = 0;
	int retval = 0, loops, i;

	if(nInDataLen%8 != 0)
		return 0xEE20;

	if(nDesKeyLen != 8)
		return 0xEE20;
	KeyLen = nDesKeyLen;
	memcpy(DesKeyBuf, pDesKey, nDesKeyLen);

	retval = OPENCOMM_DesExpandEncKey(DesKeyBuf, KeyLen,
		DesEncKeyBuf, (unsigned long *)&EncKeyLen);
	if(retval != 0)
		return retval;

	loops = nInDataLen/8;
	for(i = 0; i < loops; i++)
	{
		retval = OPENCOMM_DesEncRaw(DesEncKeyBuf, EncKeyLen, pInData + i*8,
			8, pOutData + i*8, (unsigned long *)pOutDataLen);
		if(retval != 0)
			return retval;
	}
	*pOutDataLen = nInDataLen;
	return retval;
}

int myic_DESDecrypt(
		unsigned char *pDesKey,
		int            nDesKeyLen,
		unsigned char *pInData,
		int            nInDataLen,
		unsigned char *pOutData,
		int           *pOutDataLen)
{
	unsigned char DesKeyBuf[32];
	unsigned char DesDecKeyBuf[128];
	int DecKeyLen, KeyLen = 0;
	int retval = 0, loops, i;

	if(nInDataLen%8 != 0)
		return 0xEE20;

	if(nDesKeyLen != 8)
		return 0xEE20;
	KeyLen = nDesKeyLen;
	memcpy(DesKeyBuf, pDesKey, nDesKeyLen);

	retval = OPENCOMM_DesExpandDecKey(DesKeyBuf, KeyLen,
		DesDecKeyBuf, (unsigned long *)&DecKeyLen);
	if(retval != 0)
		return retval;

	loops = nInDataLen/8;
	for(i = 0; i < loops; i++)
	{
		retval = OPENCOMM_DesDecRaw(DesDecKeyBuf, DecKeyLen, pInData + i*8,
			8, pOutData + i*8, (unsigned long *)pOutDataLen);
		if(retval != 0)
			return retval;
	}
	*pOutDataLen = nInDataLen;
	return retval;
}

//对称明文数据打pading
void  CW_dataPadAdd(int tag, unsigned char *date, unsigned int dateLen, 
					unsigned char **padDate, unsigned int *padDateLen)
{
	int           i, padLen;
	unsigned char *pTmp   = NULL;

	pTmp = (unsigned char *)malloc(dateLen+24);
	if (pTmp == NULL)
	{
		*padDate = NULL;
		return ;
	}
	memset(pTmp, 0, dateLen+24);
	memcpy(pTmp, date, dateLen);

	if (tag == 0)
	{
		padLen = 8 - dateLen % 8;
		for (i=0; i<padLen; i++)
		{
			pTmp[dateLen+i] = (char)padLen;
		}
		*padDateLen = dateLen + padLen;
	}
	else
	{
		padLen = 16 - dateLen % 16;
		for (i=0; i<padLen; i++)
		{
			pTmp[dateLen+i] = (char)padLen;
		}
	}

	*padDateLen = dateLen + padLen;
	*padDate = pTmp;
}

#define  USER_PASSWORD_KEY "abcd1234"

//数据加密
int DesEnc(
		 unsigned char *pInData,
		 int            nInDataLen,
		 unsigned char *pOutData,
		 int           *pOutDataLen)
{
	int				rv;
	unsigned char	*padDate = NULL;
	unsigned int	padDateLen = 0;

	CW_dataPadAdd(0, pInData, (unsigned int )nInDataLen, &padDate, &padDateLen);

	rv = myic_DESEncrypt((unsigned char *)USER_PASSWORD_KEY, strlen(USER_PASSWORD_KEY),
		padDate, (int)padDateLen, pOutData, pOutDataLen);
	if (rv != 0)
	{
		if (padDate != NULL)
		{
			free(padDate);
		}
		return rv;
	}

	if (padDate != NULL)
	{
		free(padDate);
	}
	return 0;
}

//数据加密
int DesEnc_raw(
	unsigned char *pInData,
	int            nInDataLen,
	unsigned char *pOutData,
	int           *pOutDataLen)
{
	int				rv;
	unsigned char	*padDate = NULL;
	unsigned int	padDateLen = 0;

	rv = myic_DESEncrypt((unsigned char *)USER_PASSWORD_KEY, strlen(USER_PASSWORD_KEY),
		pInData, (int)nInDataLen, pOutData, pOutDataLen);
	if (rv != 0)
	{
		return rv;
	}
	return 0;
}

//解密分配内存错误
#define  ERR_MALLOC 20
//密码长度不是8的整数倍, 不合法
#define  ERR_FILECONT 20

//用户使用函数des解密
int DesDec(
		   unsigned char *pInData,
		   int            nInDataLen,
		   unsigned char *pOutData,
		   int           *pOutDataLen)
{
	int				rv;
	char			padChar;
	unsigned char 	*tmpPlain = NULL;

	tmpPlain =		(unsigned char *)malloc(nInDataLen+24);
	if (tmpPlain == NULL)
	{
		return ERR_MALLOC;
	}
	memset(tmpPlain, 0, nInDataLen+24);

	//解密
	rv = myic_DESDecrypt((unsigned char *)USER_PASSWORD_KEY, strlen(USER_PASSWORD_KEY),
		pInData, nInDataLen, tmpPlain, pOutDataLen);
	if (rv != 0)
	{
		if (tmpPlain != NULL) free(tmpPlain);
		return rv;
	}

	//去pading
	padChar = tmpPlain[*pOutDataLen - 1];
	if ( (int)padChar<=0 || (int)padChar>8) //异常处理
	{
		if (tmpPlain) free(tmpPlain);
		return ERR_FILECONT;
	}

	*pOutDataLen = *pOutDataLen - (int)padChar;
	//memset(tmpPlain + *pOutDataLen, 0, (int)padChar);
	memcpy(pOutData, tmpPlain, *pOutDataLen);
	if (tmpPlain) free(tmpPlain);
	return 0;
}

//用户使用函数des解密
int DesDec_raw(
	unsigned char *pInData,
	int            nInDataLen,
	unsigned char *pOutData,
	int           *pOutDataLen)
{
	int				rv;
	//char			padChar;
	//unsigned char 	*tmpPlain = NULL;

	/*
	tmpPlain =		(unsigned char *)malloc(nInDataLen+24);
	if (tmpPlain == NULL)
	{
		return ERR_MALLOC;
	}
	memset(tmpPlain, 0, nInDataLen+24);
	*/

	//解密
	rv = myic_DESDecrypt((unsigned char *)USER_PASSWORD_KEY, strlen(USER_PASSWORD_KEY),
		pInData, nInDataLen, pOutData, pOutDataLen);
	if (rv != 0)
	{
		//if (tmpPlain != NULL) free(tmpPlain);
		return rv;
	}
	/*
	//去pading
	padChar = tmpPlain[*pOutDataLen - 1];
	if ( (int)padChar<=0 || (int)padChar>8) //异常处理
	{
		if (tmpPlain) free(tmpPlain);
		return ERR_FILECONT;
	}

	*pOutDataLen = *pOutDataLen - (int)padChar;
	//memset(tmpPlain + *pOutDataLen, 0, (int)padChar);
	memcpy(pOutData, tmpPlain, *pOutDataLen);
	if (tmpPlain) free(tmpPlain);
	*/
	return 0;
}

加解密测试.c

#define  _CRT_SECURE_NO_WARNINGS 
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "des.h"

int main()
{
	int		ret = 0;
	char *plain = "1232343444";
	int plainlen = strlen(plain);

	char plain2[4096] = {0};
	int plainlen2 = 0;

	unsigned char cryptbuf[4096] = {0};
	int cryptlen = 0;
	//用户使用的函数
	ret =  DesEnc(plain, plainlen, cryptbuf, &cryptlen);
	if (ret != 0)
	{
		printf("func DesEnc() err:%d \n");
		return ret;
	}

	//用户使用函数des解密
	ret =   DesDec(cryptbuf, cryptlen,  plain2, &plainlen2);
	if (ret != 0)
	{
		printf("func DesDec() err:%d \n");
		return ret;
	}

	if (plainlen != plainlen2)
	{
		ret = -2;
		printf("明文长度和解密后的明文长度 不一样 \n");
		return ret;
	}

	if (memcmp(plain2, plain, plainlen) == 0 )
	{
		printf("明文长度和解密后的明文长度 一样 ok \n");
	}
	else
	{
		printf("明文长度和解密后的明文长度 不一样 err \n");
	}

	system("pause");
	return ret ;
}

文件加密框架:

#define  _CRT_SECURE_NO_WARNINGS 
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "des.h"

int FileSymEnc(const char *pfile1, const char *pfile2)
{
	int		ret = 0;
	FILE *fp1= NULL, *fp2 = NULL;
	unsigned char plain[4096];
	int plainlen = 0;

	unsigned char cryptbuf[4096] = {0};
	int cryptlen = 0;

	int tmplen;

	fp1 = fopen(pfile1, "rb");
	if (fp1 == NULL)
	{
		goto END;
	}

	fp2 = fopen(pfile2, "wb");
	if (fp2 == NULL)
	{
		goto END;
	}

	while (!feof(fp1))
	{
		plainlen = fread(plain, 1, 4096, fp1);
		if (feof(fp1))  //读完数据以后,判断是否文件结束
		{
			break;
		}

		//加密==4k的数据
		ret =  DesDec_raw(plain, plainlen, cryptbuf, &cryptlen);
		if (ret != 0)
		{
			printf("func DesEnc() err:%d \n", ret);
			goto END;
		}

		tmplen = fwrite(cryptbuf, 1, cryptlen, fp2);
		if (tmplen != cryptlen)
		{
			ret  = -3;
			printf("写密文文件失败,请检查是否磁盘已满\n");
			goto END;
		}

		//if (plainlen == 4096)
	}

	//加密小于4k的数据
	ret =  DesEnc(plain, plainlen, cryptbuf, &cryptlen);
	if (ret != 0)
	{
		printf("func DesEnc() err:%d \n", ret);
		goto END;
	}

	tmplen = fwrite(cryptbuf, 1, cryptlen, fp2);
	if (cryptlen != tmplen)
	{
		ret  = -3;
		printf("写小于4k文件密文失败,请检查是否磁盘已满\n");
		goto END;
	}

END:
	if (fp1 != NULL)
	{
		fclose(fp1);
	}
	if (fp2 != NULL)
	{
		fclose(fp2);
	}
	return 0;
}

void main()
{
	int		ret = 0;
	const char *file1 = "c:/socketclient.dll";
	const char *file2 = "c:/socketclientend.dll";

	//const char *file1 = "c:/22.txt";
	//const char *file2 = "c:/22enc.txt";

	ret =  FileSymEnc(file1, file2);
	if (ret != 0)
	{
		printf("func FileSymEnc() err\n " );
		return ;
	}

	system("pause");
	return ;
}
时间: 2024-08-02 06:59:04

C提高5 高级结构体 文件操作的相关文章

Gradle提高篇之一——文件操作

Gradle提高篇之一——文件操作 Gradle提高篇之二——依赖管理 Gradle提高篇之二——理解SourceSet Gradle提高篇之四——构建大型Java项目 Gradle提高篇之五——发布与部署

几年前做家教写的C教程(之五专讲结构体与文件操作)

C语言学习宝典(5) 结构体: 将不同类型的数据组合成为一个有机的整体,这个整体就是一个结构体. 例如: Struct student { Int name; Char sex; Float score; }: 使用方法: 类型名 成员名: 一般形式: Struct { 成员列表: }变量名表列: 结构体变量的引用: 结构体变量名.成员名 文件: FILE  *fp; Fp=fopen(文件名,文件打开方式): Fclose(文件指针) 例1  对候选人得票的统计程序,设有3个后选人,每次输入一

c语言_文件操作_FILE结构体小解释

参考文档来自:https://www.cnblogs.com/haore147/p/3648395.html 我们通过fopen返回一个文件指针(指向FILE结构体的指针)来进行文件操作. 在vs2013下的代码如下: #include <stdio.h> #pragma warning(disable:4996) int main() { FILE *p = fopen("C:\\test\\win\\a.txt", "r"); char buf[10

Windows DIB文件操作详解-4.使用DIB Section

前面讲了为了提高DIB的显示性能和效率,我们将DIB转换成DDB,但是这又遇到一个问题,如果我想操作DIB的数据的话,显然是不能使用DDB:一是因为DIB转DDB时发生了颜色转换,再就是DDB无法直接提取指定像素点的数据.那么我们怎么办呢,Windows使用一种折中的方式来达到这一目标(既提高了显示效率和性能,又可以直接操作像素点). 1.DIB Section存储和显示 Windows使用DIB块(DIB Section)来存储DIB数据,其内存结构示意图如下 其实,和我们自己读入DIB数据到

linux_api之文件操作

本篇索引: 1.引言 2.文件描述符 3.open函数 4.close函数 5.read函数 6.write函数 7.lseek函数 8.i/o效率问题 9.内核用以维护打开文件的相关数据结构 10.O_APPEND标志 11.dup函数(文件描述符重定位函数) 12.有关文件共享的问题 13.fcntl函数 14.ioctl函数         1.引言 1.1.文件io这个词的含义 实现对文件的数据输入(input)和输出(output),所以简称为文件io. 1.2.什么需要文件io 程序

Nginx基础入门之文件操作优化及请求特殊处理介绍

本节的内容主要讲到关于nginx文件操作优化以及对客户端请求特殊处理(比如限速,不合法请求处理,是否注明nginx版本号) 一.通过nginx对客户端相关请求做特殊处理 1.1 按HTTP方法名限制用户请求 语法:limit_except method ... {...} 配置块:location Nginx通过limit_except后面指定的方法名来限制用户请求.方法名可取值包括:GET.HEAD.POST.PUT.DELETE.MKCOL.COPY.MOVE.OPTIONS.PROPFIN

【Go语言】集合与文件操作

本文目录 1.数据集合的主要操作 1_1.字典的声明 1_2.字典的初始化和创建 1_3.字典的访问和操作 1_4.其他类型的数据集 2.文件操作 2_1.文件操作概述os包和path包 2_2.文件操作示例 目录操作: 打开与建立文件: 写文件 : 读文件: 删除文件: 回到顶部 1.集合以及主要操作 首先要提到的是Go语言的内置数据类型map(字典类型 类似于Java中的HashMap和Swift中的Directory),这样你无需导入任何包便可 使用map类型了.map是一种特殊的数据结构

Linux操作系统 内存管理、用户操作和文件操作

内存管理.用户操作和文件操作 预备知识: 1.Linux系统的内存分为物理内存和虚拟内存.物理内存是指安装在计算机当中的主存储器:虚拟内存是一段虚拟的逻辑上连续的储存空间,虚拟内存是由多个内存碎片组成,只有正在使用的虚拟内存被存放在内存上,对于暂时不使用的虚拟内存空间其实是储存在外存中.虚拟内存空间地址和实际的物理内存空间地址存在某种逻辑上的关系,如果虚拟内存空间地址的内容将被使用,通过逻辑关系可以计算出此部分内容对应的实际物理内存空间,然后将内容加载到内存中.虚拟内存在一定程度上独立于物理内存

小何讲Linux: 基本文件操作和实例

文件操作的基本概念参见博客: 小何讲Linux: 底层文件I/O操作 1.  函数说明 open()函数:是用于打开或创建文件,在打开或创建文件时可以指定文件的属性及用户的权限等各种参数. 所谓打开文件实质上是在进程与文件之间建立起一种连接,而"文件描述符"唯一地标识着这样一个连接 close()函数:是用于关闭一个被打开的文件.当一个进程终止时,所有被它打开的文件都由内核自动关闭,很多程序都使用这一功能而不显示地关闭一个文件. read()函数:是用于将从指定的文件描述符中读出的数据