停车场的一段代码,感觉是队列的插入问题,们来看看呀

C语言 码拜 8年前 (2017-04-18) 1091次浏览
下面是本人做的停车场管理的代码,感觉是队列的插入问题出问题,可是看不出来是什么,请高手们看看~

#include<stdio.h>
#include<Windows.h>
#include<stdlib.h>
#include<conio.h>
#include<time.h>
enum operation{
	enter = 1,
	inspot,
	leave
};//车的状态,1为进入,2为在停车位中,3为离开
#define OK 0
#define ERROR 1
#define OVERFLOW -2
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef int ElemType;
typedef struct Car{
	ElemType number = 0;
	clock_t entertime;
	clock_t leavetime;
	ElemType spotnum;
	Car * next;
} *Queueptr;
typedef struct LinkedQueue{
	Queueptr rear;
	Queueptr front;
	int length = 0;
}LinkedQueue;
//外部变量
ElemType inspotcar;
ElemType waitingcar;
char output[12][2] = { 0 };
char empty[12] = { 0 };
int pos_i = 13;
Status EnQueue(LinkedQueue &queue);
Status DeQueue(LinkedQueue &queue);
Status Enter(LinkedQueue &queue,LinkedQueue &linkedqueue_leave);
Status EnterQueue(LinkedQueue &queue);
ElemType Findusefulspot(void);
Status Leave(LinkedQueue &queue);
Status Checkempty(ElemType number);
Status Check(ElemType number);
Status InitQueue(LinkedQueue &queue);
Status InputInformation(LinkedQueue &linkedqueue, LinkedQueue &linkedqueue_leave);
Status Screen(LinkedQueue &linkedqueue, LinkedQueue &linkedqueue_leave);
Status Print(LinkedQueue &linkedqueue_leave);
Status EnterOrLeave(LinkedQueue &linkedqueue, LinkedQueue &linkedqueue_leave);
Status Information(LinkedQueue &linkedqueue);
Status Enterlie(LinkedQueue &queue);
ElemType FindStack(ElemType spotnum);
Status Operter(ElemType num, LinkedQueue &linkedqueue, LinkedQueue &linkedqueue_leave);
int main(void)
{
	LinkedQueue linkedqueue;
	LinkedQueue linkedqueue_leave;
	srand((unsigned)time(NULL));
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD pos = { 32, 11 };
	SetConsoleTitle(TEXT("停车场管理"));
	SetConsoleCursorPosition(hOut, pos);
	printf("停车场管理\n");
	Sleep(1000);
	InitQueue(linkedqueue);
	InitQueue(linkedqueue_leave);
	InputInformation(linkedqueue, linkedqueue_leave);
	system("pause");
	return 0;
}
Status InitQueue(LinkedQueue &queue)
{
	queue.front = queue.rear = (Queueptr)malloc(sizeof(Car));
	if (!queue.front){
		exit(OVERFLOW);
	}
	queue.front->next = NULL;
	return OK;
}
Status InputInformation(LinkedQueue &linkedqueue, LinkedQueue &linkedqueue_leave)
{
	system("cls");
	printf("共有多少车辆在排队中:");
	scanf_s("%d", &waitingcar);
	EnterQueue(linkedqueue);
	Screen(linkedqueue, linkedqueue_leave);
	return OK;
}
Status Screen(LinkedQueue &linkedqueue, LinkedQueue &linkedqueue_leave)
{
	system("cls");
	srand((unsigned)time(NULL));
	inspotcar = (rand() % 12) + 1;
	printf("停车场中已有%d辆车\n", inspotcar);
	Information(linkedqueue_leave);
	ElemType num = waitingcar + inspotcar;
	for (int i = 0; i < num; i++){
		system("cls");
		printf("          *************************          \n");
		printf("          *   1       2       3   *          \n");
		printf("          *                       *          \n");
		printf("          *   4       5       6   *          \n");
		printf("***********                       ***********\n");
		printf("                                             \n");
		printf("                                             \n");
		printf("***********                       ***********\n");
		printf("          *   7       8       9   *          \n");
		printf("          *                       *          \n");
		printf("          *   10      11      12  *          \n");
		printf("          *************************          \n");
		Print(linkedqueue_leave);
		Sleep(2000);
		EnterOrLeave(linkedqueue, linkedqueue_leave);

	}
	system("pause");
	return OK;
}
Status Print(LinkedQueue &linkedqueue_leave)
{
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD pos;
	pos = { 0, 13 };
	SetConsoleCursorPosition(hOut, pos);
	fflush(stdout);
	printf("正有%d辆车在排队", waitingcar);
	pos = { 0, 14 };
	SetConsoleCursorPosition(hOut, pos);
	printf("正有%d辆车在车场中", inspotcar);
	fflush(stdout);
	pos = { 0, 15 };
	SetConsoleCursorPosition(hOut, pos);
	for (int i = 0; i < 12; i++){
		printf("%d号车位有:", i + 1);
		fflush(stdout);
		if (output[i][1] == 0){
			printf(" \n");
		}
		else{
			printf("粤A%d\n", linkedqueue_leave.front->next->number);
			linkedqueue_leave.front = linkedqueue_leave.front->next;
		}
	}
	return OK;
}
Status Information(LinkedQueue &linkedqueue_leave)
{
	for (int i = 0; i < inspotcar; i++){
		Enterlie(linkedqueue_leave);
	}
	return OK;
}
Status Enterlie(LinkedQueue &linkedqueue_leave)
{
	Queueptr point = (Queueptr)malloc(sizeof(Car));
	if (!point){
		exit(OVERFLOW);
	}
	point->entertime = clock();
	point->number = (rand() % 9999) + 1;
	//分配车位
	ElemType num;
	while (1){
		num = rand() % 12;
		if (Check(num) == OK){
			output[num][0] = num + 1;
			output[num][1] = 1;
			point->spotnum = num;
			break;
		}
	}
	linkedqueue_leave.rear->next = point;
	linkedqueue_leave.rear = point;
	printf("hhhhh\n");
	Sleep(100);
	return OK;
}
Status Check(ElemType number)
{
	if (output[number][1] == 0){
		return OK;
	}
	else{
		return ERROR;
	}
}
Status EnterOrLeave(LinkedQueue &linkedqueue, LinkedQueue &linkedqueue_leave)
{
	ElemType num;
	if (waitingcar == 0){
		num = leave;
	}
	else{
		if ((rand() % 2) == 0){
			num = leave;
		}
		else{
			num = enter;
		}
	}
	Operter(num, linkedqueue, linkedqueue_leave);
	return OK;
}
Status Operter(ElemType num, LinkedQueue &linkedqueue, LinkedQueue &linkedqueue_leave)
{
	if (num == enter){
		Enter(linkedqueue,linkedqueue_leave);
	}
	else{
		Leave(linkedqueue_leave);
	}
	return OK;
}
Status Enter(LinkedQueue &queue,LinkedQueue &linkedqueue_leave)
{
	ElemType num = Findusefulspot();
	if (num == 0){
		return OK;
	}
	ElemType spot = (rand() % (num + 1));
	queue.front->entertime = clock();
	queue.front->spotnum = empty[spot] + 1;
	output[empty[spot]][1] = 1;
	DeQueue(queue);
	EnQueue(linkedqueue_leave);
	inspotcar += 1;
	waitingcar -= 1;
	return OK;
}
Status DeQueue(LinkedQueue &queue)
{
	Queueptr point = queue.front;
	queue.front = queue.front->next;
	free(point);
	return OK;
}
Status EnQueue(LinkedQueue &queue)
{
	Queueptr point = (Queueptr)malloc(sizeof(Car));
	queue.rear->next = point;
	queue.rear = point;
	return OK;
}
Status EnterQueue(LinkedQueue &linkedqueue)
{
	for (int i = 0; i < waitingcar; i++){
		EnQueue(linkedqueue);
	}
	return OK;
}
ElemType Findusefulspot(void)
{
	if (inspotcar == 12){
		return 0;
	}
	int j = 0;
	for (int i = 0; i < 12; i++){
		if (output[i][1] == 0){
			empty[j] = i;
			j += 1;
		}
	}
	Checkempty(j);
	ElemType em[12];
	ElemType k = 0;
	for (int i = 0; i <= j; i++){
		if (empty[i] == -1){
			;
		}
		else{
			em[k] = empty[i];
			k += 1;
		}
	}
	for (int i = 0; i <= k; i++){
		empty[i] = em[i];
	}
	return k;
}
Status Checkempty(ElemType number)
{
	for (int i = 0; i <= number; i++){
		if (empty[i] == 0){
			if ((output[1][1] == 1) && (output[3][1] == 1)){
				empty[i] = -1;
			}
			if ((output[3][1] == 1) && (output[4][1] == 1) && (output[5][1] == 1)){
				empty[i] = -1;
			}
			if ((output[4][1] == 1) && (output[3][1] == 1) && (output[2][1] == 1)){
				empty[i] = -1;
			}
			if ((output[1][1] == 1) && (output[3][1] == 1) && (output[4][1] == 1)){
				empty[i] = -1;
			}
		}
		if (empty[i] == 1){
			if ((output[3][1] == 1) && (output[4][1] == 1) && (output[5][1] == 1)){
				empty[i] = -1;
			}
			if ((output[4][1] == 1) && (output[3][1] == 1) && (output[2][1] == 1)){
				empty[i] = -1;
			}
			if ((output[0][1] == 1) && (output[4][1] == 1) && (output[5][1] == 1)){
				empty[i] = -1;
			}
			if ((output[0][1] == 1) && (output[2][1] == 1) && (output[4][1] == 1)){
				empty[i] = -1;
			}
		}
		if (empty[i] == 2){
			if ((output[3][1] == 1) && (output[4][1] == 1) && (output[5][1] == 1)){
				empty[i] = -1;
			}
			if ((output[1][1] == 1) && (output[5][1] == 1)){
				empty[i] = -1;
			}
			if ((output[0][1] == 1) && (output[4][1] == 1) && (output[5][1] == 1)){
				empty[i] = -1;
			}
			if ((output[1][1] == 1) && (output[4][1] == 1) && (output[5][1] == 1)){
				empty[i] = -1;
			}
		}
		if (empty[i] == 9){
			if ((output[6][1] == 1) && (output[10][1] == 1)){
				empty[i] = -1;
			}
			if ((output[6][1] == 1) && (output[7][1] == 1) && (output[8][1] == 1)){
				empty[i] = -1;
			}
			if ((output[6][1] == 1) && (output[7][1] == 1) && (output[11][1] == 1)){
				empty[i] = -1;
			}
			if ((output[6][1] == 1) && (output[7][1] == 1) && (output[10][1] == 1)){
				empty[i] = -1;
			}
		}
		if (empty[i] == 10){
			if ((output[6][1] == 1) && (output[7][1] == 1) && (output[8][1] == 1)){
				empty[i] = -1;
			}
			if ((output[6][1] == 1) && (output[7][1] == 1) && (output[11][1] == 1)){
				empty[i] = -1;
			}
			if ((output[7][1] == 1) && (output[8][1] == 1) && (output[9][1] == 1)){
				empty[i] = -1;
			}
			if ((output[7][1] == 1) && (output[9][1] == 1) && (output[11][1] == 1)){
				empty[i] = -1;
			}
		}
		if (empty[i] == 11){
			if ((output[6][1] == 1) && (output[7][1] == 1) && (output[8][1] == 1)){
				empty[i] = -1;
			}
			if ((output[7][1] == 1) && (output[8][1] == 1) && (output[10][1] == 1)){
				empty[i] = -1;
			}
			if ((output[7][1] == 1) && (output[8][1] == 1) && (output[9][1] == 1)){
				empty[i] = -1;
			}
			if ((output[8][1] == 1) && (output[10][1] == 1)){
				empty[i] = -1;
			}
		}
	}
	return OK;
}
Status Leave(LinkedQueue &queue)
{
	ElemType em[12];
	ElemType j = 0;
	for (int i = 0; i < 12; i++){
		if (output[i][1] == 1){
			em[j] = i;
			j += 1;
		}
	}
	ElemType num = rand() % j;
	output[em[num]][1] = 0;
	inspotcar -= 1;
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD pos = { 0, 27 };
	SetConsoleCursorPosition(hOut, pos);
	printf("车牌为粤A%d的车出停车场,总停时间为:%.3lf秒", queue.front->number, ((double)(((queue.front->leavetime) - (queue.front->leavetime)) / CLOCKS_PER_SEC)));
	DeQueue(queue);
	Sleep(1000);
	pos_i += 1;
	return OK;
}
解决方案

30

仅供参考:

#include <windows.h>
#include <stdio.h>
void ConPrint(char *CharBuffer, int len);
void ConPrintAt(int x, int y, char *CharBuffer, int len);
void gotoXY(int x, int y);
void ClearConsole(void);
void ClearConsoleToColors(int ForgC, int BackC);
void SetColorAndBackground(int ForgC, int BackC);
void SetColor(int ForgC);
void HideTheCursor(void);
void ShowTheCursor(void);
int main(int argc, char* argv[])
{
   HideTheCursor();
   ClearConsoleToColors(15, 1);
   ClearConsole();
   gotoXY(1, 1);
   SetColor(14);
   printf("This is a test...\n");
   Sleep(5000);
   ShowTheCursor();
   SetColorAndBackground(15, 12);
   ConPrint("This is also a test...\n", 23);
   SetColorAndBackground(1, 7);
   ConPrintAt(22, 15, "This is also a test...\n", 23);
   gotoXY(0, 24);
   SetColorAndBackground(7, 1);
   return 0;
}
//This will clear the console while setting the forground and
//background colors.
void ClearConsoleToColors(int ForgC, int BackC)
{
   WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);
   //Get the handle to the current output buffer...
   HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
   //This is used to reset the carat/cursor to the top left.
   COORD coord = {0, 0};
   //A return value... indicating how many chars were written
   //not used but we need to capture this since it will be
   //written anyway (passing NULL causes an access violation).
   DWORD count;
   //This is a structure containing all of the console info
   // it is used here to find the size of the console.
   CONSOLE_SCREEN_BUFFER_INFO csbi;
   //Here we will set the current color
   SetConsoleTextAttribute(hStdOut, wColor);
   if(GetConsoleScreenBufferInfo(hStdOut, &csbi))
   {
      //This fills the buffer with a given character (in this case 32=space).
      FillConsoleOutputCharacter(hStdOut, (TCHAR) 32, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);
      FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);
      //This will set our cursor position for the next print statement.
      SetConsoleCursorPosition(hStdOut, coord);
   }
}
//This will clear the console.
void ClearConsole()
{
   //Get the handle to the current output buffer...
   HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
   //This is used to reset the carat/cursor to the top left.
   COORD coord = {0, 0};
   //A return value... indicating how many chars were written
   //   not used but we need to capture this since it will be
   //   written anyway (passing NULL causes an access violation).
   DWORD count;
   //This is a structure containing all of the console info
   // it is used here to find the size of the console.
   CONSOLE_SCREEN_BUFFER_INFO csbi;
   //Here we will set the current color
   if(GetConsoleScreenBufferInfo(hStdOut, &csbi))
   {
      //This fills the buffer with a given character (in this case 32=space).
      FillConsoleOutputCharacter(hStdOut, (TCHAR) 32, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);
      FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);
      //This will set our cursor position for the next print statement.
      SetConsoleCursorPosition(hStdOut, coord);
   }
}
//This will set the position of the cursor
void gotoXY(int x, int y)
{
   //Initialize the coordinates
   COORD coord = {x, y};
   //Set the position
   SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
//This will set the forground color for printing in a console window.
void SetColor(int ForgC)
{
   WORD wColor;
   //We will need this handle to get the current background attribute
   HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
   CONSOLE_SCREEN_BUFFER_INFO csbi;
   //We use csbi for the wAttributes word.
   if(GetConsoleScreenBufferInfo(hStdOut, &csbi))
   {
      //Mask out all but the background attribute, and add in the forgournd color
      wColor = (csbi.wAttributes & 0xF0) + (ForgC & 0x0F);
      SetConsoleTextAttribute(hStdOut, wColor);
   }
}
//This will set the forground and background color for printing in a console window.
void SetColorAndBackground(int ForgC, int BackC)
{
   WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);;
   SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), wColor);
}
//Direct console output
void ConPrint(char *CharBuffer, int len)
{
   DWORD count;
   WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), CharBuffer, len, &count, NULL);
}
//Direct Console output at a particular coordinate.
void ConPrintAt(int x, int y, char *CharBuffer, int len)
{
   DWORD count;
   COORD coord = {x, y};
   HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
   SetConsoleCursorPosition(hStdOut, coord);
   WriteConsole(hStdOut, CharBuffer, len, &count, NULL);
}
//Hides the console cursor
void HideTheCursor()
{
   CONSOLE_CURSOR_INFO cciCursor;
   HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
   if(GetConsoleCursorInfo(hStdOut, &cciCursor))
   {
      cciCursor.bVisible = FALSE;
	  SetConsoleCursorInfo(hStdOut, &cciCursor);
   }
}
//Shows the console cursor
void ShowTheCursor()
{
   CONSOLE_CURSOR_INFO cciCursor;
   HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
   if(GetConsoleCursorInfo(hStdOut, &cciCursor))
   {
      cciCursor.bVisible = TRUE;
	  SetConsoleCursorInfo(hStdOut, &cciCursor);
   }
}

20

出现错误是:0xC0000005:  读取位置 0xCDCDCDDD 时发生访问冲突。
这是对未初始化过的堆上申请的变量进行了操作。
printf(“粤A%d\n”, linkedqueue_leave.front->next->number);你这句的linkedqueue_leave.front->next并没有对其赋过值

60

大佬不敢当,调过了就好。
未初始化变量调试起来确实比较头疼,所以Effective系列都推荐 使用前定义,定义伴随初始化

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明停车场的一段代码,感觉是队列的插入问题,们来看看呀
喜欢 (0)
[1034331897@qq.com]
分享 (0)