Проблема с печатью связанных списков структур чтения входных данных из файла CSV - PullRequest
0 голосов
/ 10 июня 2019

Я читаю CSV-файл с 3 данными для каждой строки. Кажется, что сам список заполняется данными, взятыми из файла Csv, потому что если я напечатал в Insert_list, он печатает правильные вещи, но все же, если я распечатываю список, он возвращает мне мусор.

Я думаю, что проблема в insert_list, потому что это единственный способ испортить список, но я не могу найти, который есть. Я попробовал много вариантов ввода в список и распечатать. То, что я на самом деле использую, кажется, лучший выбор, потому что по крайней мере, если я попрошу напечатать Lptr в insert_list, прямо сейчас, это даст мне правильные входные значения. Затем, если я распечатаю список, это дает мне мусор

Структуры, которые мне нужны в моей программе.

    typedef struct product {
        int prod_code;
        char prod_name[20];
        int price;
        int stockage;
}product;

    typedef struct prod_list {
        product  product;
        struct prod_list *next_ptr;

}prod_list;


typedef prod_list *Prod_ptr;
int threshold=10000; 

Функции:

void insert_list ( Prod_ptr *lptr , int code,  char *name,  int price);
void print_list( Prod_ptr *lptr);

Main:

int main (){
    prod_list *lptr = NULL ;
    FILE *file_ptr;
    file_ptr= fopen( "semplice.csv" , "r");

    if(file_ptr==NULL) {
        printf("error program name");
        return 1;
    }


    int code, price;
    char name[20];

    while (fscanf(file_ptr , "%d,%19[^,],%d", &code , name , &price) == 3) {
       insert_list ( &lptr , code , name , price); 
    }
    print_list(&lptr);


    fclose(file_ptr); 

    return 0;
}




void insert_list(Prod_ptr *lptr, int code , char *name , int price) {



    if(*lptr == NULL){
        Prod_ptr newPtr = malloc(sizeof(prod_list));

        if(newPtr != NULL){
            newPtr->product.prod_code = code;
            strcpy(newPtr->product.prod_name , name);
            newPtr->product.price = price;
            newPtr->product.stockage = rand() % (100001);
            newPtr->next_ptr = NULL;
            *lptr = newPtr;
        }
        else{
            puts(" memoria esaurita");
        }
    }
    else if ((*lptr)->product.prod_code >= code){
        Prod_ptr newPtr = malloc(sizeof(prod_list));

        if ( newPtr != NULL ) {
            newPtr->product.prod_code = code;
            strcpy(newPtr->product.prod_name , name);
            newPtr->product.price = price;
            newPtr->product.stockage = rand() % (100001);
            newPtr->next_ptr = *lptr;
            *lptr = newPtr;


        }
    else{
           puts("mem esaurita");
    }
}
    else{
        insert_list(&((*lptr)->next_ptr) , code , name, price);
    }
}



void print_list( Prod_ptr *lptr){
    Prod_ptr temp = lptr; 
    printf("Input Threshold:");
    while((scanf("%d" , &threshold))!=1 && threshold > 0){
        printf("error input");
        scanf("%*[^\n]%*c");  
    }

    if( temp == NULL){
        puts("Error");
    }
    else {
        for(temp = lptr; temp != NULL; temp = temp->next_ptr){
            if( temp->product.stockage < threshold){
                printf("Product code: %d\nProduct Name: %s\Product price: %d\Stockage: %d\n\n", temp->product.prod_code , temp->product.prod_name , temp->product.price ,  temp->product.stockage );
            }
        }
    }
 }

Он компилируется, но когда запускается print_list, он выдает такой мусор: Код товара: 11146320 Наименование товара: Цена продукта: 4199400 Склад: 0

но если я напечатаю значения lptr внутри insert_list, это даст мне правильные значения.

Файл CSV содержит:

4;Computer 3;950
12;Computer 4;1050
13;Computer 5;1150
24;Computer 6;1250
25;Computer 7;1350
27;Computer 8;1450
31;Computer 9;1550
32;Computer 10;1650
33;Telefono 1;103
35;Telefono 2;129
38;Telefono 3;155

Ответы [ 2 ]

1 голос
/ 10 июня 2019

Указатель на указатель в функции вставки является отличным способом избежать манипулирования с чрезмерными переменными и условиями. И: чтобы избежать рекурсии ...

Итак: используйте это!


void insert_list(struct prodlist **pp, int code , char *name , int price)
{
    struct prodlist *newp ;

        // Advance pp, until it points to the pointer
        // That *should* be pointing at the new entry
        // That pointer *could* be NULL. In that case, we reached the end of the list;
    for(        ; *pp; pp = &(*pp)->next){
        if((*pp)->product.prod_code >= code) break; // Found the place!
        }

    newp = malloc(sizeof *newp);
    if(!newp ){
         fprintf(stderr, "memoria esaurita\n");
         return;
         }

    newp->product.prod_code = code;
    strcpy(newp->product.prod_name , name);
    newp->product.price = price;
    newp->product.stockage = rand() % 100001;
    newp->next = *pp;
    *pp = newp;
}
1 голос
/ 10 июня 2019

Большинство ваших проблем связано с использованием typedef для указателя на prod_list. Я удалил это и использовал prod_list * напрямую. Это значительно упрощает кодирование и понимание. Смотрите комментарии, которые я вставил в код.

#include "stdio.h"
#include "stdlib.h"
#include "string.h"

typedef struct product {
    int prod_code;
    char prod_name[20];
    int price;
    int stockage;
} product;

typedef struct prod_list {
    product  product;
    struct prod_list *next_ptr;

} prod_list;

//typedef prod_list *Prod_ptr;

//void insert_list(Prod_ptr *lptr, int code, char *name, int price);
//void print_list(Prod_ptr *lptr);
void insert_list(prod_list **lptr, int code, char *name, int price);
void print_list(prod_list *lptr);

int threshold = 10000;

int main() {
    prod_list *lptr = NULL;
    FILE *file_ptr;
    file_ptr = fopen("C:\\Users\\rbaron\\Documents\\Visual Studio 2015\\Projects\\ConsoleApplication3\\ConsoleApplication3\\Debug\\semplice.csv", "r");

    if (file_ptr == NULL) {
        printf("error program name");
        return 1;
    }

    int code, price;
    char name[20];

    while (fscanf(file_ptr, "%d,%19[^,],%d", &code, name, &price) == 3) {
        //insert_list(&lptr, code, name, price);
        insert_list(&lptr, code, name, price);
    }
    //print_list(&lptr);
    print_list(lptr);
    fclose(file_ptr);

    return 0;
}

//void insert_list(Prod_ptr *lptr, int code, char *name, int price) {
void insert_list(prod_list **lptr, int code, char *name, int price) {

    if (*lptr == NULL) {
        //Prod_ptr newPtr = malloc(sizeof(prod_list));
        prod_list * newPtr = malloc(sizeof(prod_list));

        if (newPtr != NULL) {
            newPtr->product.prod_code = code;
            strcpy(newPtr->product.prod_name, name);
            newPtr->product.price = price;
            newPtr->product.stockage = rand() % (100001);
            newPtr->next_ptr = NULL;
            *lptr = newPtr;
        }
        else {
            puts(" memoria esaurita");
        }
    }
    else if ((*lptr)->product.prod_code >= code) {
        //Prod_ptr newPtr = malloc(sizeof(prod_list));
        prod_list * newPtr = malloc(sizeof(prod_list));

        if (newPtr != NULL) {
            newPtr->product.prod_code = code;
            strcpy(newPtr->product.prod_name, name);
            newPtr->product.price = price;
            newPtr->product.stockage = rand() % (100001);
            newPtr->next_ptr = *lptr;
            *lptr = newPtr;


        }
        else {
            puts("mem esaurita");
        }
    }
    else {
        insert_list(&((*lptr)->next_ptr), code, name, price);
    }
}

//void print_list(Prod_ptr *lptr) {
void print_list(prod_list *lptr) {
    prod_list * temp = lptr;

    // Not sure what this is doing???
    //printf("Input Threshold:");
    //while ((scanf("%d", &threshold)) != 1 && threshold > 0) {
    //    printf("error input");
    //    scanf("%*[^\n]%*c");
    //}

    if (temp == NULL) {
        puts("Error");
    }
    else {
        for (temp = lptr; temp != NULL; temp = temp->next_ptr) {
            if (temp->product.stockage < threshold) {
                //printf("Product code: %d\nProduct Name: %s\Product price: %d\Stockage: %d\n\n", temp->product.prod_code, temp->product.prod_name, temp->product.price, temp->product.stockage);
                printf("Product code: %d\nProduct Name: %s\nProduct price: %d\nStockage: %d\n\n", temp->product.prod_code, temp->product.prod_name, temp->product.price, temp->product.stockage);
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...