Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 链接列表打印_C_Linked List - Fatal编程技术网

C 链接列表打印

C 链接列表打印,c,linked-list,C,Linked List,我正在编写一个程序,从一个txt文件中读取并将内容添加到一个链接列表中。然后,使用命令提示符中的用户界面,我应该能够查看列表,从列表中添加/删除,并使用零件号在列表中搜索项目,以查看其全部详细信息 目前我遇到两个问题: 1.在主函数中的开关情况1中,我插入了一个节点,tempNODE->item.dataitem=getInfo();行在while循环外正常工作,但当我将其放入while循环内时,它会跳过获取新项目的名称并直接转到零件号。我不明白它为什么会这样 2.在main函数中的switch

我正在编写一个程序,从一个txt文件中读取并将内容添加到一个链接列表中。然后,使用命令提示符中的用户界面,我应该能够查看列表,从列表中添加/删除,并使用零件号在列表中搜索项目,以查看其全部详细信息

目前我遇到两个问题:

1.在主函数中的开关情况1中,我插入了一个节点,tempNODE->item.dataitem=getInfo();行在while循环外正常工作,但当我将其放入while循环内时,它会跳过获取新项目的名称并直接转到零件号。我不明白它为什么会这样

2.在main函数中的switch case 3中,我不知道如何打印搜索到的节点的内容,DisplayNode函数不会对它起作用,因为节点的结构内部存在联合(我想知道如何在不更改节点的结构的情况下打印它)

这是我当前的代码:

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>

typedef struct inventory
{
    char invName[36];
    int  invPartNo;
    int  invQOH;
    float invUnitCost;
    float invPrice;
}stock;

struct  NODE
{
    union
    {
        int  nodeCounter;
        void  *dataitem;
    }item;
    struct NODE *link;
};

struct NODE *InitList();
void DisplayNode(struct inventory *);
struct inventory * ReadData(FILE *);
void DisplayList(struct NODE *);
struct NODE* GetNode(FILE *);
void  Add2List(struct NODE *, struct NODE *);
struct NODE* SearchList(struct NODE *, int );
void  DeleteNode(struct NODE *, int );
void readFromText(FILE *, struct NODE *);
struct inventory *getInfo();

int main(int argc, char* argv[])
{
    //create new linked list
    struct NODE *header;
    header = InitList();

    //open text file and read all inputs into the linked list
    FILE *fp = fopen("input.txt", "r");
    readFromText(fp, header);

    //divider
    printf("\n--------------------------------------------------\n\n");

    int input = 0;
    int a = 0;
    struct NODE *tempNODE = (struct NODE*)malloc(sizeof NODE);
    //tempNODE->item.dataitem = getInfo(); //lets user input info from cmd
    //Add2List(header, tempNODE); //inserts the new node into the list

    while(a == 0)
    {
        printf("\n\nEnter a number to select an option: \n");
        printf("1 Insert item \n");
        printf("2 Delete item \n");
        printf("3 Look up item \n");
        printf("4 Print current list of items \n");
        printf("5 Exit \n");

        scanf("%d", &input);
        switch(input)
        {
        case 1:
            //insert a node (Add2List function)
            tempNODE->item.dataitem = getInfo(); //lets user input info from cmd
            Add2List(header, tempNODE); //inserts the new node into the list

        break;

        case 2:
            printf("Enter item number to delete \n");
            int iNumber;
            scanf("%d", &iNumber);
            DeleteNode(header, iNumber);
            printf("Item %d deleted", iNumber);
        break;

        case 3:
            printf("Enter item number to search \n");
            int searchNumber;
            scanf("%d", &searchNumber);
            //create temp node to take value from search
            //struct NODE *tempNODE = (struct NODE*)malloc(sizeof NODE);
            tempNODE = SearchList(header, searchNumber); //returns a node
            //display node contents
            //DisplayNode(tempNODE->item);
        break;

        case 4:
            DisplayList(header);
        break;

        case 5:
            a = 1; //ends the while loop
        break;

        default:
            a = 1; //ends the while loop
        }

    }

    //divider
    printf("\n--------------------------------------------------\n\n");

    return 0;
}

struct NODE *InitList()
{
    struct NODE *temp = (struct NODE*)malloc(sizeof NODE);

    temp->item.nodeCounter = 0;
    temp->link = NULL;
    return temp;
}


void  Add2List(struct NODE *start, struct NODE *NewNode)
{
    struct NODE *current = start;

    while (current->link != NULL)
        current = current->link;

    current->link = NewNode;
    NewNode->link = NULL;

    start->item.nodeCounter++;
}


struct NODE* GetNode(FILE *fptr)
{
    struct NODE *temp = (struct NODE*)malloc(sizeof NODE);

    temp->item.dataitem = ReadData(fptr);
    temp->link = NULL;

    return temp;
}


void DisplayList(struct NODE *start)
{
    struct NODE *current = start->link;

    while (current != NULL)
    {
        DisplayNode((struct inventory *)current->item.dataitem);
        current = current->link;

    }
}


void DisplayNode(struct inventory *stuff)
{
    printf("Name: %s\n", stuff->invName);
    printf("Part Number: %.5d\n", stuff->invPartNo);//printf(“ %.9d”, x)
    printf("Quantity on hand: %d\n", stuff->invQOH);
    printf("Unit Cost: %0.2f\n", stuff->invUnitCost);
    printf("Price %0.2f\n\n", stuff->invPrice);
}


struct inventory * ReadData(FILE *fptr)
{
    struct inventory *temp = (struct inventory *)malloc(sizeof inventory);

    if(fptr==stdin)
        printf("Enter item name: ");
    fscanf_s(fptr, "%s", temp->invName);
    if(fptr==stdin)
        printf("Enter item part number: ");
    fscanf_s(fptr, "%d", &temp->invPartNo);
    if(fptr==stdin)
        printf("Enter item quantity on hand: ");
    fscanf_s(fptr, "%d", &temp->invQOH);
    if(fptr==stdin)
        printf("Enter item unit cost: ");
    fscanf_s(fptr, "%f", &temp->invUnitCost);
    if(fptr==stdin)
        printf("Enter item price: ");
    fscanf_s(fptr, "%f", &temp->invPrice);

    return temp;
}

struct NODE* SearchList(struct NODE *start, int oldData)
{
    struct NODE* current = start;
    struct inventory * st = (struct inventory *)current->link->item.dataitem;

    while (st->invPartNo != oldData && current != NULL)
    {
        current = current->link;
        if(current->link)
            st = (struct inventory *)current->link->item.dataitem;
    }
    return current;
}

void  DeleteNode(struct NODE *start, int oldData)
{
    struct NODE *current, *oldNode;

    current = SearchList( start, oldData);
    oldNode = current->link;
    current->link = oldNode->link;
    free(oldNode);
    start->item.nodeCounter -= 1;
}

void readFromText(FILE *fp, struct NODE *header)
{
    if( fp != NULL )
    {
        while(!feof(fp))
        {
            struct NODE *nNode =  (struct NODE*)malloc(sizeof NODE);
            struct inventory *newNode =  (struct inventory*)malloc(sizeof inventory);

            fgets(newNode->invName, 100, fp);
            fscanf(fp, " %d %d %f %f ", &newNode->invPartNo,&newNode->invQOH,&newNode->invUnitCost,&newNode->invPrice);
            nNode->item.dataitem = newNode;
            header->item.nodeCounter++;
            Add2List(header, nNode);
        }
     }
}

struct inventory *getInfo()
{
    struct inventory *temp =  (struct inventory*)malloc(sizeof inventory);

    printf("Enter item name: ");
    scanf("%99[^\n]", temp->invName); //scans whole line up to 99 characters or until \n

    printf("Enter item part number: ");
    scanf("%d", &temp->invPartNo);

    printf("Enter item quantity on hand: ");
    scanf("%d", &temp->invQOH);

    printf("Enter item unit cost: ");
    scanf("%f", &temp->invUnitCost);

    printf("Enter item price: ");
    scanf("%f", &temp->invPrice);

    return temp;
}
1.在主函数中的开关情况1中,我插入了一个节点,tempNODE->item.dataitem=getInfo();线路在外部正常工作 while循环,但当我把它放在while循环中时,它会跳过 获取新项目的名称并直接转到零件号。 我不明白它为什么会这样

这是因为在第241行上传递给scanf()的格式字符串没有指定读取任何内容。也就是说,您有:

scanf("%99[^\n]", temp->invName); //scans whole line up to 99 characters or until \n
什么时候应该是这样:

scanf("%99s[^\n]", temp->invName); //scans whole line up to 99 characters or until \n
2.在主功能中的开关情况3中,我不知道如何打印所搜索节点的内容,DisplayNode函数 由于节点(I)结构内部的并集,因此无法使用它 我想知道如何在不改变 节点)

嗯,你可以这样打印工会:

printf("tempNODE->item.nodeCounter=%i\n", tempNODE->item.nodeCounter);
printf("tempNODE->item.dataitem=%p\n", tempNODE->item.dataitem);

当然,请注意,这两个打印行中的一行将显示任何特定节点的不正确/不相关信息,因为联合一次只能是其组成成员之一——例如,如果特定节点已设置为保存nodeCounter(整型)值,然后,您不应该真正访问第二行中的dataitem成员值,或者如果节点已设置为保存数据项(指针)值,则不应该访问nodeCounter成员变量。所以你应该有办法知道这两个工会成员中哪一个是有效的,哪一个不是。典型的方法是将一个单独的成员添加到您设置的结构中(在联合外部),以指示联合被设置为什么——这称为标记的联合。但是如果你不这样做,你就必须想出一些其他的机制来代替。

第一个解决办法奏效了。但是,第二个给了我数据项的地址。我是否无法访问dataItem的库存项的invName、partNo等以打印它们?目标是,我可以输入一个零件号来获取我搜索的项目的信息(名称、价格等)。如果您知道dataitem指针实际上指向库存对象,您可以将其转换为一个类型指针:struct inventory*invPtr=(struct inventory*)tempNODE->item.nodeCounter;//然后可以像往常一样使用该指针访问字段。(但如果您出错,当您尝试使用指针时,您的程序可能会崩溃或以其他方式出现异常行为,因此请小心--无效指针这样做是危险的,因为它们不提供任何类型检查,通常在编译时会捕获错误!)我在开关案例3中使用了类型强制转换,但是,它将始终返回我搜索的项目之前的项目信息。有什么想法吗?这是我使用的代码:案例3:printf(“输入要搜索的项目编号”);整数搜索编号;scanf(“%d”、&searchNumber);tempNODE=搜索列表(标题、搜索编号)//返回一个节点invPtr=(struct inventory*)tempNODE->item.dataitem;显示节点(invPtr);打破我认为您的SeachList()函数不正确;试着在纸上画一个小链表(用圆圈表示节点,箭头表示链接),然后一步一步地看它在做什么,你可能会明白为什么。
printf("tempNODE->item.nodeCounter=%i\n", tempNODE->item.nodeCounter);
printf("tempNODE->item.dataitem=%p\n", tempNODE->item.dataitem);