gpt4 book ai didi

c - 当用户给出输入时,在 C 中遍历和打印队列的行为有所不同

转载 作者:行者123 更新时间:2023-11-30 19:18:06 25 4
gpt4 key购买 nike

如果这个概念之前已经在 SOF 上解释过,我深表歉意!我相信我的情况略有不同,并且在网站上找不到类似的问题。

问题是这样的:

我正在尝试将字符数组(字符串)存储在我正在尝试实现的队列结构中。当我像这样对数据进行硬编码时,结构及其功能似乎工作正常:

#include "Time.h"
#include <unistd.h>

int main(void){

struct Queue* q = CreateQueue();
Enqueue(q, "element1");
Enqueue(q, "element2");
Enqueue(q, "element3");
Enqueue(q, "element4");

PrintAll(q->first); // this outputs all elements and the time they've been in the queue.

return 0;
}

输出符合预期,是所有 4 个元素的列表。然而,一旦我将一个简单的菜单放在一起,以捕获用户的数据而不是像上面那样进行硬编码,PrintAll() 函数就会输出最后一个排队元素的副本。您还注意到,我正在对每个节点进行计时,以跟踪它何时添加到队列中,这似乎工作正常。尽管输出显示输入的最后一个元素重复了 N 次(N 是队列的大小),但计时器似乎对每个节点都正确显示!

我怀疑这与未清理的标准输入流有关,但我认为我用 main() 函数中显示的代码块处理了这个问题。

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



int main(void){

char name[31];
char c;
int option;
int ch;
struct Queue* q = CreateQueue();

do
{

printf("\n 1. Add a an element to the queue");
printf("\n 2. Print all elements");
printf("\n 0. Exit");

printf("\n Please select an option");

while(scanf("%d", &option)!=1){
puts("Value non good");
ch=getchar();
while(ch!=EOF && ch!='\n'){
ch=getchar();
}
}

switch(option)
{
case 1:
{
ch=getchar();
while(ch!=EOF && ch!='\n')
{
ch=getchar();
}
printf("Please enter the name of the element.\n ");
fgets(name,30,stdin);

Enqueue(q, name);
PrintAll(q->first);
break;
}
case 2:
{
PrintAll(q->last);
break;
}
default:
return 0;
}

}while(option != 0);
return 0;
}

任何人都可以阐明这个问题吗?我将不胜感激。

这是其余的代码:

时间.c:

#include "Time.h"

struct Queue* CreateQueue()
{
struct Queue* q = malloc(sizeof(struct Queue));
q->first = NULL;
q->last = NULL;
q->size = 0;
return q;
}


void Enqueue(struct Queue* queue, char* string)
{
struct Node* newNode = malloc(sizeof(struct Node));
newNode->next = NULL;
newNode->student = string;
newNode->start_time = time(0);

if(queue->size == 0)
{
queue->first = newNode;

}
else
{
queue->last->next = newNode;
}
queue->last = newNode;
queue->size = queue->size + 1;
}

char* Dequeue(struct Queue* queue)
{
if (queue->size < 0)
{
exit(0);
}
char* toBeRemoved = queue->first->student;
struct Node* oldNode = queue->first;
queue->first = oldNode->next;
queue->size = queue->size - 1;
if(queue->size == 0)
{
queue->last = NULL;
}
free(oldNode);
return toBeRemoved;

}

int IsEmpty(struct Queue *q)
{
return q->size == 0;
}


char* Peek(struct Queue *q)
{
return q->first->student;
}



void PrintOne(struct Node *node)
{
if(node !=NULL)
{
int elapsed = ElapsedTime(node);
printTime(elapsed, node->student);
//printf("%s\n", node->student);
}
}

void PrintAll(struct Node* node)
{
if (node !=NULL)
{
PrintAll(node->next);
PrintOne(node);
}
}


// returns the waiting time for a student node.
int ElapsedTime(struct Node* node)
{
int elapsed;
time_t stop_time;
stop_time = time(NULL);
elapsed = difftime( stop_time , node->start_time );

return elapsed;
}

void printTime(int elapsed, char* student_name)
{
printf("%s : waiting for ", student_name);
int minutes_or_hours = 0; //Stores a zero to indicate that it is not neccesary to print minutes or hours.
//Stores a one to indicate that hours and/or minutes have been printed.

if( (elapsed / 3600) >= 1)
{
int hours = elapsed/3600;
if(hours == 1)
{
printf("1 hour, ");
}
else
{
printf("%d hours, ", hours);
}
elapsed = elapsed - (hours*3600);

minutes_or_hours = 1;
}

if( (elapsed / 60) >= 1)
{
int minutes = elapsed/60;
if(minutes == 1)
{
printf("1 minute, ");
}
else
{
printf("%d minutes, ", minutes);
}
minutes_or_hours = 1;

elapsed = elapsed - (minutes*60);
}

if(minutes_or_hours == 1)
{
printf("and ");
}

printf("%d seconds\n", elapsed);
}

时间.h:

#ifndef TIME_H_
#define TIME_H_
#include <stdio.h>
#include <stdlib.h>
#include <time.h>



struct Node
{
time_t start_time;
struct Node* next;
char* student;
};

struct Queue
{
int size;
struct Node* first;
struct Node* last;
};

struct Queue* CreateQueue();
void Enqueue(struct Queue* , char* );
char* Dequeue(struct Queue* );
int IsEmpty(struct Queue *);
char* Peek(struct Queue *);
void PrintOne(struct Node *);
void PrintAll(struct Node *);
int ElapsedTime(struct Node* );
void printTime(int , char* );

#endif /* TIME_H_ */

最佳答案

在函数 Enqueue() 中,您仅将字符串指针复制到您的结构中。在第一种情况下,这是有效的,因为所有四个字符串都有不同的指向字符串文字的指针。但在第二个示例中,您存储数据条目 name 的指针,并且该字符串的内容随每个条目而变化。每个结构都存储相同的指针,因此都指向您最近输入的字符串。如果您的结构存储实际的字符串,那么它会起作用(但您需要小心字符串长度)。

struct Node
{
time_t start_time;
struct Node* next;
char student[31];
};

void Enqueue(struct Queue* queue, char* string)
{
...
strncpy (newNode->student, 30, string);
...
}

关于c - 当用户给出输入时,在 C 中遍历和打印队列的行为有所不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27179098/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com