c - fgets 的链表程序段错误?

标签 c linked-list segmentation-fault fgets

第一次运行效果很好。我可以添加一个项目,然后用显示功能显示。但是当我尝试添加第二个值时,一旦我在 fgets 处点击“a”,就会出现段错误。我已在顶部注释掉了。

(除了“添加”之外,我还没有考虑过其他功能。)

#include    <stdio.h>
#include    <stdlib.h>
#include    <string.h>
#include    <ctype.h>
#include    "sortedll.h"

int     main(void)
{

int             intVal;
LNode           *headPtr = NULL;
char            buf[BUFLEN];
int             result;

do  {
    // ask the user what they want to do
    DisplayMenu();
    printf("Please enter a selection: ");
    fgets(buf, BUFLEN, stdin);
    *buf = toupper(*buf);
    switch (*buf)
        {
        case   'A':
            // prompt the user for a value; if we get one, add it to the
            // list
            printf("Please enter an integer value to add: ");
            fgets(buf, BUFLEN, stdin);

            //=======================================================================
            printf("check"); //doesn't print this second time around. seg fault at fgets?
            //=======================================================================

            if (1 != sscanf(buf, "%d", &intVal))
                {
                puts("Error reading the integer value...");
                }
            else
                {
                printf("1");
                headPtr = AddItem(headPtr, intVal);
                }
            break;

        case   'R':
            // if the list is empty display a message; else, get a value
            // from the user and attempt to remove it from the list
            if (NULL == headPtr)
                {
                puts("The list is currently empty...");
                }
            else
                {
                printf("Please enter an integer value to remove: ");
                fgets(buf, BUFLEN, stdin);
                if (1 != sscanf(buf, "%d", &intVal))
                    {
                    puts("Error reading the integer value...");
                    }
                else
                    {
                    headPtr = RemoveItem(headPtr, intVal);
                    }
                }
            break;

        case   'D':
            // display the current contents of the list
            result = DisplayList(headPtr);
            printf("Currently there %s %d node%s in the list.\n"
                                , (result != 1) ? "are" : "is"
                                , result
                                , (result != 1) ? "s" : "");
            break;

        case   'Q':
            // release all allocated memory and set the head pointer to
            // NULL to indicate that it is empty
            result = ReleaseMemory(headPtr);
            printf("There %s %d node%s released."
                                , (result != 1) ? "were" : "was"
                                , result
                                , (result != 1) ? "s" : "");
            headPtr = NULL;
            break;

        default:
            puts("Unrecognized option; please try again.");
            break;
        }
    puts(" ");

    } while ('Q' != *buf);

puts("Thanks for playing!  Bye!!\n");
return  0;

}  // end of "main"



// ==== AddItem ===============================================================


LNode*  AddItem(LNode  *headPtr, int  newItem)
{
    LNode *node = malloc(sizeof(*node));
    node->value = newItem;


    if(headPtr == NULL)
        {
        node->next = NULL;
        return node;
        }

    LNode *leadPtr = headPtr;
    LNode *trailPtr = headPtr;

    while(leadPtr->value != newItem)
        {
        leadPtr = leadPtr->next;
        trailPtr = leadPtr;
        }    

    leadPtr = leadPtr->next;
    free(trailPtr->next);    
    trailPtr->next = node;
    node->next = leadPtr;

    return headPtr;

}  // end of "AddItem"



// ==== DisplayList ===========================================================


int     DisplayList(LNode  *nodePtr)
{
    auto    int         counter = 0;

    // if the list is empty, indicate as such and return zero
    if (NULL == nodePtr)
        {
        puts("The list is currently empty...");
        return (0);
        }

    while (NULL != nodePtr)
        {
        printf("%d\n", nodePtr->value);
        nodePtr = nodePtr->next;
        counter++;
        }

    return (counter);

}  // end of "DisplayList"



// ==== DisplayMenu ===========================================================


void    DisplayMenu(void)
{
    puts("A)dd a value");
    puts("R)emove a value");
    puts("D)isplay the list");
    puts("Q)uit");

}  // end of "DisplayMenu"



// ==== ReleaseMemory =========================================================


int     ReleaseMemory(LNode  *headPtr)
{


}  // end of "ReleaseMemory"



// ==== RemoveItem ============================================================


LNode*  RemoveItem(LNode  *headPtr, int  targetItem)
{


}  // end of "RemoveItem"

最佳答案

看起来您正在尝试在此处访问 LeadPtr->value,而此时 LeadPtr 可能为 NULL。

while(leadPtr->value != newItem)
    {
    leadPtr = leadPtr->next;
    trailPtr = leadPtr;
    }

在尝试访问它的成员之前,您需要确保 LeadPtr != NULL。

我建议你重构代码片段所属的函数,它在内存访问方面看起来有点脆弱。

关于c - fgets 的链表程序段错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13292268/

相关文章:

c - 查找此输出的逻辑

c - 如何对现有的双向循环链表进行排序?

MATLAB链表

c - C 中指针的哈希表?

c - 存储的错误值和其他

c++ - 在 C++ : segmentation fault when accessing the returned array 中使用指针的数组

c++ - gdb:不在上下文中的结构的大小?

c++ - 测试 C/C++ 源代码

C题: why char actually occupies 4 bytes in memory?

c - 计算链表中的元素时出现段错误