问题关于我的链表代码,奇怪的错误

huangapple go评论73阅读模式
英文:

Question for my linked list code, odd bug

问题

这段代码有一个问题,造成了在第三次循环case 2之后返回了值3221226356。这个问题可能与内存分配和指针操作有关。如果要持续循环输入数据,您需要在每次循环之后重新初始化一些变量,以确保它们不会影响下一个循环。

以下是一些可能的修复:

  1. case 2的循环内,将totalitemcode和其他可能影响下一个循环的变量重置为初始状态。
  2. 确保循环中使用的缓冲区或指针不会超出其范围,以防止内存访问错误。

请注意,修复代码可能需要更多的调试和测试以确保它按预期工作。如果您需要详细的代码更改建议,请告诉我。

英文:

I have a problem with this code, I don't know why it stops looping the second switch(input) after inputing the datas 3 times.

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

struct Node{
	char Name[50];
    int value; 
    Node *next, *prev; 
}*head, *tail;


Node* createNode(int value, char name[]){
    Node* newNode = (Node*)malloc(sizeof(Node*));
    strcpy(newNode->Name, name);
	newNode->value = value; 
    return newNode; 
}


void pushTail(int value, char name[]){
	Node *newNode = createNode(value, name);
	if(head == NULL){
        head = tail = newNode; 
        return; 
    }
	else{
	   tail->next = newNode;
    	newNode->prev = tail; 
    	tail = newNode; 	
	}
}

void makelongList(){
	for(int i = 0; i < 25; i++){
		printf("\n"); 
	}
}

void orderHistory(int val){
	Node* curr = head; 
	makelongList();
	printf("=== Order History ===\n");
	int i = 0;
	while(curr != NULL){
		printf("Order %d : %s, %d pcs\n", i+1, curr->Name, curr->value);	
		i++;
		curr = curr->next; 
	}
	printf("Total Spent = Rp. %d \n", val);
	printf("=====================\n"); getchar();

}

void itemDatabase(){
	makelongList();
	printf("=========================================\n");
	printf("| Item Code |    Item Name   |  Price   |\n");
	printf("=========================================\n"); 
	printf("|    A0     | Milk Tea       | Rp. 3000 |\n");
	printf("|    A1     | Mineral Water  | Rp. 2000 |\n");
	printf("|    A2     | Hot Dog        | Rp. 7000 |\n");
	printf("|    A3     | Cheeseburger   | Rp. 9000 |\n");
	printf("|    A4     | Cold/Hot Tea   | Rp. 4000 |\n");
	printf("=========================================\n");
	
	printf("\n Press enter to continue\n");  getchar(); 
}

void printMenu(){
	printf("=== suniB Supermarket ===\n");
	printf("1. View Available Items\n"); 
	printf("2. Buy Items\n");
	printf("3. Order History\n"); 
	printf("4. Exit\n");
	printf("=========================\n");
	printf(">> "); 
}

void printReciept(int val){
	printf("=== suniB Supermarket ===\n"); 
	printf("=  -  R E C I E P T - ===\n  ");
	printf("      [Name]-[QTY] \n");
	Node *curr = head;
    while(curr != NULL){
    printf("        %s     %d \n", curr->Name, curr->value);
        curr = curr->next; 
    }
    printf("Total Spent = Rp. %d \n", val);
	printf("-Thank You For Shopping!-\n"); 
	printf("=========================\n");
}
void classicprintList(){
    Node *curr = head; 
    printf("NULL");
    while(curr != NULL){
        printf("<-[ %d ]->", curr->value);
        curr = curr->next; 
    }
    printf("NULL\n");
}

int main(){
	
	int input, qty, pricelist[10] = {3000, 2000, 7000, 9000, 4000}, mult = 0, total = 0, temps = 0;
	char itemcode[2], temp[2] = {0}, optionstring[2]; 
	
	do{
		makelongList(); 
		printMenu();
		scanf("%d", &input); getchar();
		switch(input){
			case 1: 
				itemDatabase(); 
				break; 
			case 2: 
				do{
					do{
						printf("Insert the item code you want to buy : "); scanf("%s", itemcode); getchar(); 
					}while((itemcode[0] != 'A') && (itemcode[1] != '0') && (itemcode[1] != '1') && (itemcode[1] != '2') && (itemcode[1] != '3') && (itemcode[1] != '4'));
					do{
						printf("Insert the amount : "); scanf("%d", &qty); getchar(); 
					}while(qty < 0);
					temp[0] = itemcode[1];
					temps = atoi(temp); 
					switch(temps){
						case 0:
						 	mult = qty*pricelist[0];
						 	total += mult; 
							printf("\nItem name : Milk Tea\n");
						 	break;
						case 1: 
							mult = qty*pricelist[1]; 
							total += mult;
							printf("\nItem name : Mineral Water\n"); 
							break; 
						case 2: 
							mult = qty*pricelist[2]; 
							total += mult; 
							printf("\nItem name : Hot Dog\n"); 
							break; 
						case 3:
							mult = qty*pricelist[3]; 
							total += mult; 
							printf("\nItem name : Cheeseburger\n");
							break; 
						case 4:
							mult = qty*pricelist[4];
							total += mult; 
							printf("\nItem name : Cold | Hot Tea\n"); 
							break; 
					}
					printf("Your total amount will be : %d\n", total);
					printf("Do you want to continue? [Y | N]? : "); scanf("%c", optionstring); getchar(); 
					pushTail(qty, itemcode); 
				}while(strcmp(optionstring, "Y") == 0);
				break;
			case 3:
				orderHistory(total); 
				break; 
			case 4:
				break; 
		}
		
	}while(input >= 1 && input <= 4);
	
	return 0; 
}

the program returns value 3221226356 after the third loop of case 2. If anyone could help it would be amazing.

I expect the loop to keep going and input as many datas possible. Would say at least it could loop 10 times, but the more the better.

答案1

得分: 1

你的链表实现存在未定义行为,因为在添加到链表中的节点中,数据成员 nextprev 没有被初始化。

Node* createNode(int value, char name[]){
    Node* newNode = (Node*)malloc(sizeof(Node*));
    strcpy(newNode->Name, name);
    newNode->value = value; 
    return newNode; 
}


void pushTail(int value, char name[]){
    Node *newNode = createNode(value, name);
    if(head == NULL){
        head = tail = newNode; 
        return; 
    }
    else{
       tail->next = newNode;
        newNode->prev = tail; 
        tail = newNode;     
    }
}

此外,还存在其他问题。例如,在这个带有非常冗长条件的 do while 语句中:

do{
    printf("插入你想购买的物品代码:"); scanf("%s", itemcode); getchar(); 
}while((itemcode[0] != 'A') && (itemcode[1] != '0') && (itemcode[1] != '1') && (itemcode[1] != '2') && (itemcode[1] != '3') && (itemcode[1] != '4'));

由于数组 itemcode 声明为 2 个元素,除了终止的零字符 '\0' 外,只能存储一个字符,因此在调用 scanf 时尝试访问超出数组的内存。因此,诸如

(itemcode[1] != '1')

这样的表达式是没有意义的。

英文:

Your implementation of the list has undefined behavior because data members next and prev are not initialized in nodes added to the list

Node* createNode(int value, char name[]){
    Node* newNode = (Node*)malloc(sizeof(Node*));
    strcpy(newNode->Name, name);
    newNode->value = value; 
    return newNode; 
}


void pushTail(int value, char name[]){
    Node *newNode = createNode(value, name);
    if(head == NULL){
        head = tail = newNode; 
        return; 
    }
    else{
       tail->next = newNode;
        newNode->prev = tail; 
        tail = newNode;     
    }
}

Also there are other problems.

For example in this do while statement with an awful long condition

do{
    printf("Insert the item code you want to buy : "); scanf("%s", itemcode); getchar(); 
}while((itemcode[0] != 'A') && (itemcode[1] != '0') && (itemcode[1] != '1') && (itemcode[1] != '2') && (itemcode[1] != '3') && (itemcode[1] != '4'));

there is an attempt to access memory beyond the array itemcode in call of scanf because the array declared with 2 elements can store only one character apart from the terminating zero character '\0'. So such expressions like for example that

(itemcode[1] != '1')

do not make sense.

huangapple
  • 本文由 发表于 2023年4月1日 00:21:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/75900724.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定