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

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

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

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

4把数组排序

5打印堆区的二维数组

6释放堆空间

chunli@Linux:~/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;
}


chunli@Linux:~/high$ 
编译运行
chunli@Linux:~/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 
chunli@Linux:~/high$


这是老师的答案

chunli@Linux:~/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;
}
chunli@Linux:~/high$ 
编译
chunli@Linux:~/high$ gcc teacher.c  && ./a.out 
111111
222222
3333333
aa
bbbbbb
ccccccc
hello...
chunli@Linux:~/high$




结构体浅拷贝

chunli@Linux:~/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;
}


chunli@Linux:~/high$ 

chunli@Linux:~/high$ 
chunli@Linux:~/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)
chunli@Linux:~/high$




结构体深度拷贝

chunli@Linux:~/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;
}


chunli@Linux:~/high$ gcc -g main.c  && ./a.out 
chunli 
22 
chunli_alias 
chunli 
22 
chunli_alias 
chunli@Linux:~/high$ 
chunli@Linux:~/high$ 
chunli@Linux:~/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;
}
编译
chunli@Linux:~/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;
}
编译
chunli@Linux:~/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;
}
编译
chunli@Linux:~/high$ gcc -g main.c  && ./a.out 
chunli@Linux:~/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;
}
chunli@Linux:~/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;
}
编译运行
chunli@Linux:~/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下运行
chunli@Linux:~/high$ cat hello 
2222222222222222222222
ffffffffffffffffff
3333
chunli@Linux:~/high$ gcc -g main.c  && ./a.out 
2222222222222222222222
ffffffffffffffffff
3333
3333
不明白为什么会多一行
在win下面就是正常的
网上查了一下linux的feof函数有问题




把结构体写入文件

chunli@Linux:~/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;
}


chunli@Linux:~/high$ gcc -g main.c  && ./a.out 
chunli@Linux:~/high$ cat hello 
0,0,0ɡ .1,2,1-..N=栀戀-..h愀嘂2,4,4@pa-.僻戀-. chunli@Linux:~/high$ Xshell^C
chunli@Linux:~/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
chunli@Linux:~/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;
}
编译
chunli@Linux:~/high$ gcc -g main.c  && ./a.out 
0,0,0 ->30 
1,2,1 ->31 
2,4,4 ->32 
chunli@Linux:~/high$


【C语言 文件项目】

1程序的配置文件

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

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

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

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


我的代码文件

chunli@Linux:~/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

chunli@Linux:~/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
chunli@Linux:~/high$



文件2

chunli@Linux:~/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;
}

chunli@Linux:~/high$



文件3

chunli@Linux:~/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;
}


chunli@Linux:~/high$



编译运行

chunli@Linux:~/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
chunli@Linux:~/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编译不正常。

wKioL1dpBk3ASNo_AABJ0OvMnIU174.png


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 ;
}