字节似乎被转移了

时间:2018-03-14 08:14:12

标签: c arrays pointers struct

我写了一个程序,其中有一个错误。我从昨天中午开始试图解决这个问题,但这似乎是不可能的。 我在这里删除了很多方法,让你看到重要的代码。当我从文件中读取数据时会发生错误。阅读工作和数组上的写作也应该有效。但是如果我在读完之后输出数据(使用ausgabeBS()),那么就会有完全随机的数字。 请查看开关的情况6和方法read()。

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

typedef struct baustein
{
    int hoehe;
    int breite;
    int length;
    int rot;
    int gruen;
    int blau;
} BAUSTEIN;

void eingabeBS(BAUSTEIN *bs);
void ausgabeBS(BAUSTEIN bs);
int compareBS(BAUSTEIN bs1, BAUSTEIN bs2);
void rem(BAUSTEIN *bs, int stelle, int length);
int auswahl();
int getVolume(BAUSTEIN bs);
void compare(int length, BAUSTEIN *lego);
void quicksort(int links, int rechts, BAUSTEIN feld[]);
void speichern(int length, BAUSTEIN *lego);
int read(BAUSTEIN *lego, int length);

int main()
{
    BAUSTEIN *legobausteine;
    legobausteine = (BAUSTEIN*)malloc(1 * sizeof(BAUSTEIN));
    int length = 0;
    int command = 1;
    int chosen;
    while (1)
    {
        system("cls");
        command = auswahl();
        switch (command)
        {
        case 0:
            length++;
            legobausteine = (BAUSTEIN *)realloc(legobausteine, sizeof(BAUSTEIN) * length);
            eingabeBS(&legobausteine[length - 1]);
            break;
        case 1:
            printf("Welches der Elemente von [0; %d[ soll ausgegeben werden: ", length);
            scanf("%d", &chosen);
            if (chosen < 0 || chosen > length - 1)
            {
                printf("Dies ist keine gueltige Eingabe!\n");
                system("pause");
                break;
            }
            ausgabeBS(legobausteine[chosen]);
            break;
        case 2:
            printf("Welches der Elemente von [0; %d[ soll entfernt werden: ", length);
            scanf("%d", &chosen);
            if (chosen < 0 || chosen > length - 1)
            {
                printf("Dies ist keine gueltige Eingabe!\n");
                system("pause");
                break;
            }
            rem(legobausteine, chosen, length);
            length--;
            break;
        case 3:
            compare(length, legobausteine);
            break;
        case 4:
            if (length != 0)
            {
                quicksort(0, length - 1, legobausteine);
            }
            else
            {
                printf("\nEs sind keine Inhalte vorhanden!\n");
                system("pause");
            }
            break;
        case 5:
            speichern(length, legobausteine);
            break;
        case 6:
            length = read(legobausteine, length);
            printf("FINAL: %d", legobausteine[length - 1].length); //here a random number is outputed.
            break;
        case 7:
            return 0;
        default:
            printf("Das ist kein gueltiger Befehl!\n");
            system("pause");
            break;
        }
    }
    return 0;
}

void speichern(int length, BAUSTEIN *lego)
{
    FILE *f = fopen("data.txt", "w");

    for (int i = 0; i < length; i++)
    {
        fprintf(f, "%d;%d;%d;%d;%d;%d;", lego[i].hoehe, lego[i].breite, lego[i].length, lego[i].rot, lego[i].gruen, lego[i].blau);
    }
    fprintf(f, "\n");
    fclose(f);
}

int read(BAUSTEIN *lego, int length)
{
    FILE *f;
    f = fopen("data.txt", "r");
    if (f)
    {
        int c;
        char buff[300];
        int counter = 0;
        printf("HIER \n");
        while ((c = getc(f)) != EOF)
        {
            buff[counter] = c;
            printf("%c", c);
            counter++;
        }
        fclose(f);

        char *data;
        data = strtok(buff, "\n");
        printf("Daten: %    s", &data[0]);
        int wert = 0;
        char *temp;

        temp = strtok(data, ";");

        while(temp != NULL){
            if(wert % 6 == 0){
                printf("\nReallokiert!\n");
                length++;
                lego = (BAUSTEIN *)realloc(lego, sizeof(BAUSTEIN) * length);
            }
            printf("\n%d", atoi(temp));
            switch(wert % 6){
                case 0:
                    lego[length - 1].hoehe = atoi(temp);
                    printf("Wert hier: %d\n",lego[length-1].hoehe);
                case 1:
                    lego[length - 1].breite = atoi(temp);
                case 2:
                    lego[length - 1].length = atoi(temp);
                case 3:
                    lego[length - 1].rot = atoi(temp);
                case 4:
                    lego[length - 1].gruen = atoi(temp);
                case 5:
                    lego[length - 1].blau = atoi(temp);
                }
            temp = strtok(NULL, ";");
            wert++;
        }
    }
    else
    {
        printf("Es sind noch keine Daten vorhanden!");
    }
    return length;
}

void ausgabeBS(BAUSTEIN bs)
{
    printf("Die Hoehe betraegt %d mm\n", bs.hoehe);
    printf("Die Breite betraegt %d mm\n", bs.breite);
    printf("Die length betraegt %d mm\n", bs.length);
    printf("Der Rotwert betraegt %d \n", bs.rot);
    printf("Der Gruenwert betraegt %d \n", bs.gruen);
    printf("Der Blauwert betraegt %d \n", bs.blau);
    system("pause");
}

1 个答案:

答案 0 :(得分:4)

read内部,您为lego中存储新值的结构重新分配缓冲区并使前一次无效,但是lego是一个函数参数,因此调用代码仍然具有旧值(现在无效) )指针legobausteine。如果要重新分配它,则需要将指针传递给该指针。此外,当您最初在legobausteine中为main分配缓冲区时,它永远不会被初始化并且最初包含垃圾。