简体   繁体   English

C程序设计打印链接列表,不沿列表移动并崩溃

[英]C programming printing a linked list, not moving along list and crashing

I am trying to print a linked list, it is acting strangely, when it is suppose to move to the next item it will not, for instance the first item printed is "Granny Smith" and then the rest in the struct, when it goes to the next line what should be a new food is "ranny Smith" Always without the G, and most of the other details are corrupted or gibberish. 我正在尝试打印一个链表,它的行为很奇怪,假设要移动到下一个项目,它将不会,例如,打印的第一个项目是“ Granny Smith”,然后其余的在结构中(当它进入时)到下一行,应该是新食物的是“兰尼·史密斯”(Ranny Smith),始终没有G,其他大多数细节都已损坏或乱码。 Any help would be greatly appreciated. 任何帮助将不胜感激。

#define _CRT_SECURE_NO_WARNINGS

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

#define cls system("cls");
#define flush fflush(stdin)
#define pause system("pause");


struct food  // Declaration of struct
{
    char produce[20];
    char type[20];
    char soldBy[20];
    float price;
    int quantityInStock;
    struct food *next;
};


void addPres(struct food** tip, char tokenPro[20], char tokenType[20], char tokenSold[20], float tokenFloat, int tokenInt);
void display ();
void displayMenu ();
int getChoice ();
void readDataIn();




int main()
{
    int choice = 0;
    int ;
    struct food first;
    char *saveFloat, *saveInt;
    char tokenPro[20], tokenType[20], tokenSold[20], savePro[20], saveType[20], saveSold[20], j[1900];
    float tokenFloat, messFloat;
    int danint, tokenInt;
    struct food* a = NULL;
    FILE* file;

    a = NULL; // sets the first item on the list to empty

//readDataIn();
    do
    {
        choice = getChoice();//function to present choices and receive an answer
        switch (choice)//switch routes the choice
        {
        case 1: //to enter a new node on the list
            cls;
            printf("Enter the produce type: ");
            fgets(tokenPro, 20, stdin);
            printf("Enter the type: ");
            fgets(tokenType, 20, stdin);
            printf("Enter the units of measurement: ");
            fgets(tokenSold, 20, stdin);
            printf("\nEnter the price per %s: ", &tokenSold);
            scanf("%f", &tokenFloat );
            printf("\nEnter the quantity in stock: ");
            scanf("%i", &tokenInt );
            //pause;
            addPres(&a, tokenPro, tokenType, tokenSold, tokenFloat, tokenInt);
            break;
        case 2: //to display the linked list
            display(a);

            break;
        case 3: //to reverse the order

            if((file=fopen("AssignmentTwoInput.txt", "r")) != NULL)  //opens files
            {
                while(fgets(j, sizeof(j), file))  //while information is being sent to j from the file
                {
                    strcpy(savePro, strtok(j, ","));
                    strcpy(saveType, strtok(NULL, ","));
                    strcpy(saveSold, strtok(NULL, ","));
                    saveFloat = strtok(NULL, ",");
                    saveInt = strtok(NULL, "\n");
                    messFloat = atof(saveFloat); //ID number is assigned to token2
                    danint = atoi(saveInt); //converts  the value token2 points to into an int (previously read in as an string)
                    addPres(&a, savePro, saveType, saveSold, messFloat, danint); //sends the name and ID to the function to add a person
//printf("\n %s \t %s \t %s \t %f \t %i", savePro, saveType, saveSold, messFloat, danint);
//pause;
                }//end while loop
            }//end if loop
            printf("\nSuccessfully loaded input file\n\n\n"); //message to tell user the back was found and imported successfully
            pause;
            fclose(file);
            break;
        case 4: //to export data

            break;
        case 5: //option to exit

            exit(0);
            break;
        default://error checking
            printf("Please enter a valid choice.\n");
            break;
        }//switch loop close

    }
    while (choice != 5);   //end menu choices


    return 0;
}//end main


void addPres(struct food** tip, char tokenPro[20], char tokenType[20], char tokenSold[20], float tokenFloat, int tokenInt)
{


    struct food* temp =

        (struct food*) malloc(sizeof(struct food));
    strcpy(temp->produce, tokenPro);
    strcpy(temp->type, tokenType);
    strcpy(temp->soldBy, tokenSold);
    temp->price = tokenFloat;
    temp->quantityInStock = tokenInt;

//printf("\n %s \t %s \t %s \t %f \t %i", temp->produce, temp->type, temp->soldBy, temp->price, temp->quantityInStock);
//pause;
    if (tip == NULL) //if the tip node is empty
    {
        tip = temp; //tip node becomes this node
        (*tip)->next = NULL; // since there are no others yet the next node will be empty
    }


    else
    {
        temp->next = tip; // reassigns the tip node to the next one
        (*tip) = temp; //inserts current node as the tip
    }
}

void display(struct food* c)
{
//c = first; //assigns c to the first node on the linked list
    int count = 1;
    struct food *temp;
    temp = c;
    cls;
    printf("==========================================================================\n"); //prints a header to say which info is which
    printf(" Item #   Produce       Type             Sold By         Price    In Stock\n");
    printf("==========================================================================\n");
    while( c != NULL)
    {
        printf("%3i \t", count);
        printf("%s \t", c->produce ); //prints name
        printf("%s \t", c->type ); //prints name
        printf("%s \t", c->soldBy); //prints name
        printf("%-3.2f \t", c->price); //prints ID
        printf("%i\n", c->quantityInStock); //prints ID
        pause;
        count = count + 1;
        c = c->next; //advances to next item in the linked list

        if(c == NULL)
        {
            printf("\n end \n"); //once end is found user is told

            pause;
        }
    }
    printf("\n done \n");
    pause;
}//end display

You have three important mistakes, one of them seems to be caused by copying and pasting some code, 您有三个重要的错误,其中之一似乎是由于复制和粘贴某些代码而引起的,

  1. This printf() statement would cause undefined behavior printf()语句将导致未定义的行为

     printf("\\nEnter the price per %s: ", &tokenSold); 

    because you are passing the correct address but the pointer type is wrong so pointer arithmetic will cause undefined behavior inside printf() 因为您传递的是正确的地址,但指针类型错误,所以指针算术将导致printf()内部发生未定义的行为

     printf("\\nEnter the price per %s: ", tokenSold); /* remove the & --------------------^ here */ 
  2. You passed a double pointer to addPres but you never dereference it to access the actual poitner, which is what you want to modify, that is causing both, undefined behavior and the observed effect of an empty list, since once the function returns it did not alter the original poitner, you should access the double pointer with the dereference operator inside this function, for example instead of 您向addPres传递了一个双指针,但是您从未取消对其的引用以访问实际的poitner,这是您要修改的,这会导致未定义的行为和观察到的空列表的影响,因为一旦函数返回,它就不会更改原始poitner,则应使用此函数内的dereference运算符访问double指针,例如,

     if (tip == NULL) 

    it has to be 它一定要是

     if (*tip == NULL) 

    and the same applies for every access inside this function. 对于此函数内部的每次访问也是如此。

    • How did I find out all these problems so quickly? 我怎么这么快发现所有这些问题?

      Because I compiled your programs with compiler warnings enabled and it started showing those problems. 因为我在启用编译器警告的情况下编译了程序,所以它开始显示这些问题。

    • Will there be other issues in your code? 您的代码中还会有其他问题吗?

      Yes probably, but you need to fix these first. 可能是的,但是您首先需要解决这些问题。

  3. You fflush(stdin) , a very common mistake which seems to come from some tutorials or books or online resources, the standard clearly states that fflush() is for output streams, and the behavior is undefined for input streams, the following was taken from the C11 draft fflush(stdin) ,这是一个非常常见的错误,似乎来自某些教程,书籍或在线资源,该标准明确指出fflush()用于输出流,而行为未定义用于输入流,以下内容摘自C11草案

    7.21.5.2 The fflush function 7.21.5.2 fflush功能

    1. If stream points to an output stream or an update stream in which the most recent operation was not input, the fflush function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; 如果流指向未输入最新操作的输出流或更新流,则fflush函数会使该流的所有未写入数据都被传递到主机环境中,并写入文件中; otherwise, the behavior is undefined. 否则,行为是不确定的。

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

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