简体   繁体   English

C LinkedList打印

[英]C LinkedList printing

I am writing a program that reads from a txt file and adds the contents to a linked list. 我正在编写一个从txt文件读取并将内容添加到链接列表的程序。 Then, with user interface in command prompt, I should be able to view the list, add/delete from the list, and search for an item in the list using the part number to see its full detail. 然后,在命令提示符下的用户界面下,我应该能够查看列表,从列表中添加/删除,以及使用零件号在列表中搜索项目以查看其详细信息。

Currently I am encountering two problems: 目前,我遇到两个问题:

1.In switch case 1 in the main function, where I insert a node, the tempNODE->item.dataitem = getInfo(); 1,在主函数的开关案例1中,我在其中插入一个节点,tempNODE-> item.dataitem = getInfo(); line works correctly outside of the while loop, but when I put it inside the while loop, it skips taking the name of the new item and goes directly to the part number. 该行在while循环外正常工作,但是当我将其放入while循环内时,它将跳过采用新项的名称并直接转到部件号。 I cannot figure out why it does this. 我不知道为什么要这么做。

2.In switch case 3 in the main function, I cannot figure out how to print the contents of the searched node, the DisplayNode function won't work on it because of the union inside the structure of NODE (I am want to figure out how to print this without changing the struct of NODE). 2,在主功能的开关情况3中,我无法弄清楚如何打印搜索到的节点的内容,由于节点结构内部的并集,DisplayNode函数无法在其上工作(我想弄清楚如何在不更改NODE结构的情况下进行打印)。

This is my current code: 这是我当前的代码:

#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;
}

And this is the text file I read from: 这是我从中读取的文本文件:

#1 Flat Blade Screwdriver
12489
36
.65
1.75
#2 Flat Blade Screwdriver
12488
24
.70
1.85
#1 Phillips Screwdriver
12456
27
0.67
1.80
#2 Phillips Screwdriver
12455
17
0.81
2.00
Claw Hammer
03448
14
3.27
4.89
Tack Hammer
03442
9
3.55
5.27
Cross Cut Saw
07224
6
6.97
8.25
Rip Saw
07228
5
6.48
7.99
6" Adjustable Wrench
06526
11
3.21
4.50

1.In switch case 1 in the main function, where I insert a node, the tempNODE->item.dataitem = getInfo(); 1,在主函数的开关案例1中,我在其中插入一个节点,tempNODE-> item.dataitem = getInfo(); line works correctly outside of the while loop, but when I put it inside the while loop, it skips taking the name of the new item and goes directly to the part number. 该行在while循环外正常工作,但是当我将其放入while循环内时,它将跳过采用新项的名称并直接转到部件号。 I cannot figure out why it does this. 我不知道为什么要这么做。

It's because the format string you passed to scanf() on line 241 didn't specify to read anything. 这是因为您在第241行传递给scanf()的格式字符串未指定读取任何内容。 That is, you have this: 也就是说,您有:

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

when it should be this: 什么时候应该是这样的:

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

2.In switch case 3 in the main function, I cannot figure out how to print the contents of the searched node, the DisplayNode function won't work on it because of the union inside the structure of NODE (I am want to figure out how to print this without changing the struct of NODE). 2,在主功能的开关情况3中,我无法弄清楚如何打印搜索到的节点的内容,由于节点结构内部的并集,DisplayNode函数无法在其上工作(我想弄清楚如何在不更改NODE结构的情况下进行打印)。

Well, you can print out the union like this: 好了,您可以像这样打印出联合:

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

Note of course that one of these two print lines will display incorrect/irrelevant information for any particular node, since a union can only be one of its constituent members at a time -- for example, if the particular node has been set to hold a nodeCounter (integer) value, then you shouldn't really be accessing the dataitem member value in the second line, or if the node has been set to hold a data item (pointer) value, then you shouldn't be accessing the nodeCounter member variable. 当然,请注意,这两个打印行之一将显示任何特定节点不正确/不相关的信息,因为一个联合一次只能是其组成成员之一-例如,如果特定节点已设置为保留一个nodeCounter(整数)值,那么您实际上不应访问第二行中的dataitem成员值,或者如果已将节点设置为保存数据项(指针)值,那么您不应访问nodeCounter成员变量。 So you should have some way to know which of those two union-members is the valid one and which is not. 因此,您应该以某种方式知道这两个工会成员中的哪个是有效成员,哪个不是。 The typical way is to add a separate member to the struct (outside of the union) that you set to indicate what the union is set to -- that's known as a tagged union. 典型的方法是将一个单独的成员添加到您设置的结构中(在联合之外),以指示该联合设置为什么-这称为标记联合。 But if you don't do it that way, you'll have to come up with some other mechanism instead. 但是,如果您不这样做,则必须提出其他一些机制。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM