我正在尝试实现一种将文件名输入列表头部位置的方法。一旦列表有了第一个条目,在函数插入中第二次运行时,我想输入另一个文件名,但这次是在下一个(pNext)位置。
我有一个关于如何在纸上实现的想法,但实现让我感到困惑。我第一次能够传递文件名。但对于第二次尝试,我创建了一个条件: if (frame->pNext != NULL) {//should add to the pnextposition
但是这个条件总是在我插入第一帧之前执行。 frame->pNext 为 NULL,但由于我使用了 malloc,它指向垃圾内存,因此该条件始终为 true,但我只需要在第一次运行时它为 false。
这样我就在头部添加一个列表,然后下次运行时我在位置 2 添加第二个文件名......等等。
示例:文件名:[第一] [第二] [第三]
#include <crtdbg.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
typedef enum { FALSE = 0, TRUE } BOOL;
struct Frame {
char* fileName;
struct Frame* pNext;
};
struct Animation {
struct Frame* frames;
};
// Forward declarations
void initAnimation(struct Animation*);
void insertFrame(struct Animation*);
void runFrames(struct Animation*);
int main(void)
{
char response;
BOOL RUNNING = TRUE;
struct Animation A;
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
initAnimation(&A);
while (RUNNING)
{
printf("MENU\n 1. Insert a Frame\n 2. Delete all the Frames\n 3. Run the Animation\n 4. Quit\n");
scanf("%c", &response);
switch (response)
{
case '1':insertFrame(&A); break;
case '3':runFrames(&A); break;
case '4':RUNNING = FALSE; break;
default:printf("Please enter a valid option\n");
}
printf("\n");
while ((response = getchar()) != '\n' && response != EOF);// clear input buffer
}
return 0;
}
void initAnimation(struct Animation* pA) {
pA = NULL;
}
void insertFrame(struct Animation* pA) {
char* fileName;
struct Frame* frame;
fileName = (char *)malloc(sizeof(char)); //filename
frame = (struct Frame *)malloc(sizeof(struct Frame)); //next frame
frame->fileName = (struct Frame *)malloc(sizeof(struct Frame)); //filename
frame->pNext = (struct Frame *)malloc(sizeof(struct Frame)); //for next frames
printf("Insert a Frame in the Animation\n");
printf("Please enter the Frame filename :");
scanf("%s", fileName);
strcpy(frame->fileName, fileName); //store into filename
if (frame->pNext != NULL) { //add to pnext frame
printf("next frames");
frame->pNext = frame;
}
else { //add to first frame once
printf("this is the first frame");
pA->frames = frame;
}
}
最佳答案
回答有关如何使条件仅在添加第一个节点后运行的问题。您必须将 malloc 移至 else 语句中,位于 pA->frames = frame
之后。就此而言,您应该注意一些事情。
首先,您缺少 malloc 所需的 stdlib.h
库。
(来源:CLion,gcc 错误)
其次,库 crtdbg.h
似乎是一个 C++ 库,而不是一个 C 库(来源:light google search)。
第三,插入帧功能不存储正在创建的帧。这是因为变量 A 没有声明为指针。除此之外,在InsertFrame中初始化pNext时,需要相对于pA->frames
来引用它,frame->pNext =frame;
也是如此> 在 if 语句中。
最后,您可以考虑添加一个指向第一个节点的头节点,以便您可以开始。
希望这有帮助,祝你好运
编辑: 我编写了我自己的 insertFrame() 函数版本:
void insertFrame(struct Animation* pA) {
struct frame* frame;
frame = (struct frame *)malloc(sizeof(struct frame)); //next frame
frame->fileName = (char*)malloc(sizeof(char)); //filename
printf("Insert a Frame in the Animation\n");
printf("Please enter the Frame filename :");
scanf("%s", frame->fileName);
//Skips to else the first time because pA->frames->pNext == Null
//The extra if is how I stopped a segmentation fault.
if(pA->frames != NULL) {
//Check if the current node has memory space reserved
if (pA->frames->pNext != NULL) { //add to pnext frame
printf("next frames\n");
pA->frames->pNext = frame;
pA->frames = pA->frames->pNext;
}
}
else { //add to first frame once
printf("this is the first frame\n");
//fill the first frame
pA->frames = frame;
//Set head node next value to the first node in the list
pA->head->pNext= pA->frames;
//Because pA->frames->pNext is declared and initialilzed here, it keeps
//the if statement above from running the first time
pA->frames->pNext = (struct frame *)malloc(sizeof(struct frame));
}
}
编辑2: 我认为在声明它时将其分配到 main 中而不是使用 initAnimation 更有意义。当您不初始化它或将其设置为 NULL 时,就没有地方可以存储帧。
关于C 链表条件语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46270120/