Добавление данных в структуру внутри функции, но в противном случае значения пусты - PullRequest
0 голосов
/ 06 января 2020

Прежде всего, мне жаль, если это новый вопрос, но я только начинаю учиться C.

У меня есть эта структура

struct item_s {
unsigned id;
char manufacturer [16];
char model [16];
unsigned rack;
unsigned position;
unsigned quantity;
};
#define MAX_NR_ITEMS 10000
struct item_s stock[MAX_NR_ITEMS];

Структура заполняется такими элементами

    while ((stock_size < MAX_NR_ITEMS) && (len == 6))
{
    stock[stock_size].id = id;
    strcpy(stock[stock_size].manufacturer, manufacturer);
    strcpy(stock[stock_size].model, model);
    stock[stock_size].rack = rack;
    stock[stock_size].position = position;
    stock[stock_size].quantity = quantity;
    stock_size++;
    len = fscanf(fp, "%i %s %s %i %i %i", &id, manufacturer, model, &rack, &position, &quantity);
}

Это прекрасно работает, но теперь, когда я пытаюсь добавить еще один элемент в функцию, подобную этой

    stock_size++;
    stock[stock_size].id = id;
    strcpy(stock[stock_size].manufacturer, hersteller);
    strcpy(stock[stock_size].model, modell);
    stock[stock_size].rack = regal;
    stock[stock_size].position = fach;
    stock[stock_size].quantity = nr;

, она прекрасно работает, если я печатаю элементы внутри функции, но всякий раз, когда я попробуйте получить доступ к новым элементам вне этой функции, она просто дает мне пустые значения

Может кто-нибудь сказать мне, почему это происходит и как правильно добавить другой элемент?

Это код с некоторыми вещами вырезка, которая не влияет на этот

//
//  stock.c
//

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


/* structure to store all information about items */

struct item_s {
    unsigned id;
    char manufacturer [16];
    char model [16];
    unsigned rack;
    unsigned position;
    unsigned quantity;
};


#define MAX_NR_ITEMS 10000
struct item_s stock[MAX_NR_ITEMS];
unsigned stock_size = 0;
unsigned structsize;

/* read at most max_nr items from file "filename" and write them to array items
 * the number of items actually read is returned */

void read_items_from_file(char *filename)
{
    // storage to preliminarily store the information of an item
    unsigned id; char manufacturer[16]; char model[16];
    unsigned rack; unsigned position; unsigned quantity;
    // number of tokens read from current input line
    size_t len = 0;

    // open the input file for reading
    FILE * fp = fopen(filename, "r");
    if (fp == NULL)
    {
        // if file could not be opened (wrong path, not readable, ...)
        // output a short message and immediately exit
        char resp;
        printf("Eingabedatei kann nicht geoeffnet werden.\n");
        scanf("%c", &resp);
        exit(EXIT_FAILURE);
    }

    // the following loop reads a new item in every iteration
    // until the end of the file (or an invalid entry appears)
    len = fscanf(fp, "%i %s %s %i %i %i", &id, manufacturer, model, &rack, &position, &quantity);

    // as long as there is space in the array and a correct line is read
    while ((stock_size < MAX_NR_ITEMS) && (len == 6))
    {
        stock[stock_size].id = id;
        strcpy(stock[stock_size].manufacturer, manufacturer);
        strcpy(stock[stock_size].model, model);
        stock[stock_size].rack = rack;
        stock[stock_size].position = position;
        stock[stock_size].quantity = quantity;
        stock_size++;
        // reading next item
        len = fscanf(fp, "%i %s %s %i %i %i", &id, manufacturer, model, &rack, &position, &quantity);
    }

    // finally close the input file
    fclose(fp);
}

struct item_s enter_new_item(unsigned id){
    char hersteller [16];
    char modell [16];
    unsigned regal;
    unsigned fach;
    printf("\n Neue ID! Bitte geben sie den Hersteller an\n");
    scanf("%s", hersteller);
    printf("\n Bitte geben sie das Modell an\n");
    scanf("%s", modell);
    unsigned exitloop = 1;
    do
    {
        printf("\n Bitte geben sie das Lagerregal an\n");
        scanf("%i", &regal);
        printf("\n Bitte geben sie das Lagerfach an\n");
        scanf("%i", &fach);
        for(unsigned i=0; i<stock_size; i++)
        {
            if (regal == stock[i].rack && fach == stock[i].position){
                printf("\nDer ausgewählte Lagerort ist bereits belegt!");
                exitloop = 0;
            }
        }
    } while(exitloop == 0);

    printf("\nGeben sie die Anzahl der neuen Elemente ein\n");
    unsigned amount;
    scanf("%d", &amount);

    struct item_s new_item;
    new_item.id = id;
    strcpy(new_item.manufacturer, hersteller);
    strcpy(new_item.model, modell);
    new_item.rack = regal;
    new_item.position = fach;
    new_item.quantity = amount;

    return new_item;
}
void add_items_to_stock(unsigned id)
{
    unsigned newitem = 1;
    for(unsigned i=0; i<stock_size; i++)
    {
        if (id == stock[i].id){
            printf("\nID %d erkannt! Die neuen Artikel werden am gleichen Ort eingelagert (Regal %i Fach %i)", id, stock[i].rack,stock[i].position);
            printf("\nGeben sie die Anzahl der neuen Elemente ein\n");
            unsigned amount;
            scanf("%d", &amount);
            stock[i].quantity = stock[i].quantity + amount;
            newitem = 0;
        }
    }
    if (newitem == 1){
        structsize++;
        stock[structsize] = enter_new_item(id);
        printf("ID %d ", stock[structsize].id);
        printf("manu %s ", stock[structsize].manufacturer);
        printf("model %s ", stock[structsize].model);
        printf("rack %d ", stock[structsize].rack);
        printf("position %d ", stock[structsize].position);
        printf("quantity %d ", stock[structsize].quantity);
    }
}



void print_stock()
{
    for(unsigned i=0; i<structsize; i++) {
        printf("\n ID : %04d Hersteller : %s Modell : %s - Regal :  %d Fach : %d - Anzahl : %d\n",
               stock[i].id,
               stock[i].manufacturer,
               stock[i].model,
               stock[i].rack,
               stock[i].position,
               stock[i].quantity );
    }
}

int main()
{

    // read intial stock from files
    read_items_from_file("lager.txt");
    structsize = stock_size;
    //
    do {
        printf("\n\nSelect one\n");
        printf("(1) \n");
        printf("(2) Add Elements\n");
        printf("(3) \n");
        printf("(4) Print Inventory\n");
        printf("(0) End Programm\n");
        printf("\tYour Choice");

        unsigned  choice;
        scanf("%d", &choice);
        while (getchar() != '\n');

        unsigned id;
        // menu items
        switch(choice)
        {

            case 1:

                break;
            case 2:
                printf("\nGeben sie die ID des Elementes ein\n");
                scanf("%d", &id);
                add_items_to_stock(id);
                break;
            case 3:

                break;
            case 4:
                print_stock();
                break;
            case 0:
                return 0;
            default:
                printf("Incorrect Input\n");
        }

    } while(1);
}

Файл, в который он получает свои данные, выглядит следующим образом

11 Hersteller-A Modell-A 54 4 12
22 Hersteller-B Modell-B 6 34 101
53 Hersteller-C Modell-C 14 20 20
84 Hersteller-D Modell-D 85 2 18
101 Hersteller-E Modell-E 25 4 12
102 Hersteller-F Modell-X1 56 3 101
322 Hersteller-F Modell-X2 61 70 20
411 Hersteller-G Modell-Y1 88 82 18
561 Hersteller-G Modell-Y2 95 4 12
772 Hersteller-G Modell-Y3 56 03 101
883 Hersteller-H Modell-H2 41 90 20
954 Hersteller-I Modell-I 68 92 18

1 Ответ

0 голосов
/ 07 января 2020

В вашем коде у вас есть это (выделение добавлено с комментариями):

    while ((stock_size < MAX_NR_ITEMS) && (len == 6))
    {
        stock[stock_size].id = id;
        strcpy(stock[stock_size].manufacturer, manufacturer);
        strcpy(stock[stock_size].model, model);
        stock[stock_size].rack = rack;
        stock[stock_size].position = position;
        stock[stock_size].quantity = quantity;

        stock_size++;   //<<------------------ THIS LINE

        // reading next item
        len = fscanf(fp, "%i %s %s %i %i %i", &id, manufacturer, model, &rack, &position, &quantity);
    }

Но в следующем разделе у вас есть это (выделение добавлено):

    if (newitem == 1){

        structsize++;   //<<------------------  THIS LINE

        stock[structsize] = enter_new_item(id);
        printf("ID %d ", stock[structsize].id);
        printf("manu %s ", stock[structsize].manufacturer);
        printf("model %s ", stock[structsize].model);
        printf("rack %d ", stock[structsize].rack);
        printf("position %d ", stock[structsize].position);
        printf("quantity %d ", stock[structsize].quantity);
    }

Почему я указать это? Поскольку вы отслеживаете количество элементов в вашем массиве с помощью stock_size, который увеличивается после , данные помещаются в массив, но во втором блоке кода вы ссылаетесь на structsize который инициализируется равным stock_size, но увеличивается до , когда данные помещаются в массив. Это приведет к тому, что данные в памяти будут выглядеть следующим образом:

d = data
n = null

Initialize stock_size to 0.
Add first item and increment stock_size to 1.
---------
| 0 | 1 |
---------
| D | N |
---------

Add 2nd item and increment stock_size to 2.
-------------
| 0 | 1 | 2 |
-------------
| D | D | N |
-------------

Keep adding items and incrementing stock_size after adding the data until you've added 6 items.
-----------------------------
| 0 | 1 | 2 | 3 | 4 | 5 | 6 |
-----------------------------
| D | D | D | D | D | D | N |
-----------------------------

Set structsize equal to stock_size.
Increment structsize to 7 and add item.
---------------------------------
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---------------------------------
| D | D | D | D | D | D | N | D |
---------------------------------

В моем примере область памяти, представленная stock[6], пуста, потому что вы увеличили индекс массива в неправильное время, и есть неинициализированный раздел вашего массива между хорошими данными. Переключение и увеличение structsize после добавления данных исправляет это, и данные будут отображаться правильно.

См. Мой код здесь: https://onlinegdb.com/BkLZ_7-lU

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...