werte in char[] einlesen



  • Hallo
    folgender code ausschnitt

    char *key_namen [] = {"Titel","Dozent"};
    
         char *feld_name[] = {
                 "                   Titel : ",
                 "                  Dozent : ",
                 "               Assistent : ",
                 "Typ (U)ebung (V)orlesung : ",
                 "               Schlüssel : ",
                 "                  Termin : ",
                 "                     Ort : ",
                  "               Kommentar : "
         };
    
         typedef struct s_vorlesungen{
                 struct s_vorlesungen *next;
                 struct s_vorlesungen *prev;
                 char * data [MAX_DATA] ;
         }t_vorlesungen; 
    
    /*  usw und dann  */
     int einlesen() {
        struct s_vorlesungen *temp;
        char bestaetigung='n';
        char * string;
        int i,j;
        // Neuen Speicher für Element reservieren
        temp = (struct s_vorlesungen*) malloc ( sizeof(temp) ) ;
        printf("\033[2J"); // Bildschirm löschen
        printf("Aufnahme der Vorlesungsdaten!\n");
        printf("=============================\n");
        printf("Bitte geben Sie folgende Daten an:");
        for ( i = 0; i < MAX_DATA ; i++) {
        printf("\n%s",feld_name[i]);
        scanf ("%s",temp->data[i]);
    
    /***
      hier gibts ein segmenation fault ?????
    **/
      }
    
    }
    

    Kann mir jemand helfen
    Danke hanns



  • temp = (struct s_vorlesungen*) malloc ( sizeof(temp) ) ;
    

    ... deine temp Variabel ist ein Pointer...
    .. ich nehme an die hat die Grösse 4 ... also:
    sizeof(temp) != sizeof(s_vorlesungen)

    Ausserdem ist "char * data [MAX_DATA];" ein Array von Pointern... nicht ein
    array von Chars... möchtest du das wirklich so?
    Wenn ja musst du selbstverständlich diesen Pointern ebenfalls einen Bereich
    zuordnen..

    [EDIT]
    Anscheinend möchtest du tatsächlich jede deiner Antworten in dieser "data"
    Variabel speichern -> also fehlt dir dort noch der Bereich.
    Wesshalb eigentlich der malloc? Du allozierst ja ohnehin nur _ein_
    Objekt -> also würde ein "struct s_vorlesungen temp; // kein pointer mehr"
    genügen..
    [/EDIT

    [ Dieser Beitrag wurde am 18.12.2002 um 17:11 Uhr von Solaris'dUKe editiert. ]



  • erst mal danke,
    were ichmorgen früh noch mal genau durchdenken
    Hanns



  • Hallo Solaris,
    scheint, daß ich grundlegende Verständnisprobleme habe:

    Was möchte ich erreichen?
    in der doppelt verk. Liste sollen maximal MAX_DATA Texte von beliebiger länge gespeichert werden.
    Die Struct beinhaltet daher:
    - einen Zeiger auf die nachfolgende struct,
    - einen Zeiger auf die vorgehende , und
    - ein Array von der Größe MAX_DATA, welches Zeiger auf die ( beliebig langen ) einzelnen "Texte" speichert.

    Das "Einlesen" müsste dann so ablaufen ??

    - erzeuge einen genügend großen EinleseBuffer
       - for ( jedes der elemente) {
           lies den Text ein;
           if ( text ist leer ) {
               notiere z.b NULL in data ;
           } else {
               fordere Speicher für den Bufferinhalt an;
               if ( es hat geklappt ) {
                   kopiere den Bufferihalt an diese Adresse;
                   speichere die Speicheradresse in data 
               }
           }
         }
    

    Ich habs noch mal überdacht, sollte eigentlich so klappen ??

    Zur nächsten Frage:
    Du schreibst, "struct s_vorlesungen temp;" reiche ! Was passiert, wenn ich dies so erkläre?
    Wird damit Speicher für in der größe einer struct s_vorlesungen bereitgestellt ?
    ich entheme das Deinen Worten, daß malloc überflüssig sein.

    Dabei merke ich, daß ich wohl noch einen anderen Fehler gemacht habe
    temp ist ja lokal zur function einlesen, ergo wird der Speicher nach dem Verlassen freigeben ?! Weise ich vor dem verlassen die adresse von temp meiner Liste zu, dann gibt es Müll nach dem Verlassen, da &temp dannauf Speicher zeigt, der nicht mehr ( oder von anderen ) belegt ist. ??
    Um das zu vermeiden, muss ich der aufrufenden Funktion temp zurückgeben ?
    dazu müsste der funtionstyp auf "structur " geändert werden ?
    z.B. so?

    struct s_vorlesungen einlesen() {
        struct s_vorlesungen temp;
        // daten einlesen
        if ( erfolgreich) {
            return temp;
        }
        return NULL;
    }
    

    Falls dies so richtig wäre, müsste der Speicher für temp auch nach der Rückkehr erhalten bleiben ?
    Ist das korrekt ?

    Danke im Voraus für Deine (oder eines anderen ) Antwort
    Hanns



  • Ich glaube was du brauchst ist in etwa folgendes:

    struct s_vorlesungen *anker = (struct s_vorlesungen *)0;
    do
    {
      Frage: "weitere Vorlesung registrieren?"
      if (ja)
      {
         erstelle neues Element; (malloc)
         for (MAX_DATA)
         {
           lese String ein
           fordere Speicher für nächsten Daten-Pointer an (Stringlänge + 1)
           kopiere String in den allokierten Bereich
         }
         verhänge das neue Element mit der Kette (anker)
      }
    } while (kein Abbruch)
    

    So ist deine Liste genau so gross, wie eingegebene Datensätze existieren.
    Du musst also für jedes neue Element Speicher erzeugen, sowie für jede
    neue Eingabe (dein Pointer-Array).

    Falls dies so richtig wäre, müsste der Speicher für temp auch nach der
    Rückkehr erhalten bleiben ?
    Ist das korrekt ?

    Nicht ganz... die Variabel wird mit dem verlassen der Funktion wirklich
    freigegeben. Aber ihr Inhalt wird vorher in die zugewiesene Variabel kopiert.
    var = eingabe(); // wird in var kopiert

    [ Dieser Beitrag wurde am 19.12.2002 um 19:12 Uhr von Solaris'dUKe editiert. ]



  • Original erstellt von Solaris'dUKe:
    **```cpp
    struct s_vorlesungen *anker = (struct s_vorlesungen *)0;

    He he, das ist mal n lustiger cast 🙂



  • Hallo Solaris'dUKe

    ja so ist es, das Drumherum ist auch schon fertig.
    Die Probleme steckten wohl darin, daß ich GLAUBTE pointer zu können.
    Mittlerweile hab ich schon die EInleseroutine, die auch klappt.

    Aber doch noch ne Frage zum freigeben der lokalen Var:
    Du schreibst:

    Nicht ganz... die Variabel wird mit dem verlassen der Funktion wirklich
    freigegeben. Aber ihr Inhalt wird vorher in die zugewiesene Variabel kopiert.
    var = eingabe(); // wird in var kopiert

    ich konsturiere mal;
    a) in eingabe() klappt es, die temp. var anzulegen.
    b) vor rückgabe wird tem pnach var kopiert ?
    wenn dann aber kein speicher für var frei ist ??

    oder :
    in eingabe () steht var an adresse nn mit einer länge von m.
    vor ende der func wird temp kopiert, sagen wir mal an nn + ( m * type-länge),
    also idealerweise gleich hinter das ende von temp, und dann wird nn freigegebn.
    dann hab ich doch ein Loch. wärs nicht einfacher, währedn der Laufzeit, würde einfach die interne Var-Tabelle aktualisert, indem var die adresse von temp zugewiesen bekommt ??

    .. (struct s_vorlesungen 😉 0; ( was Shade so lustig findet ) ist das korrekt?
    Na ja korrekt schon, aber ist es auch anwendbar resp. macht es sinn, so zu initialisieren, wäre nicht NULL einfacher zu lesen ?
    Naj obwohl es wohl egal ist, ob ich später prüfe auf
    if ( aktueller != NULL ) {
    oder
    if ( aktueller != 0 ) {

    Es grüßt euch hanns

    Und noch ne Frage


Anmelden zum Antworten