Problem mit char Variablen



  • char variable[40];
    

    das nimmst du wenn du weißt das du 1-39 zeichen in das array speichern wilst.
    kann also auch erst zur laufzeit enschieden werden da genug speicher
    reserviert/allokiert wurde.

    char variable[] = "Inhalt";          
    char *variable = "Inhalt";
    

    beim 2. wird deutlicher das ein zeiger benutzt wird, wird beim 1. intern aber
    auch gemacht, zeiger auf das erste zeicehn im string.
    ich würde sagen das ist für den normalfall egal 🤡



  • Ach so okay danke.
    Ich habe hier ein Beispielprogramm:

    #include <stdio.h>                          /*Standarb Library*/
    #include <stdbool.h>                        /*bool kann anstelle von _Bool verwendet werden*/
    #include <stdlib.h>                         /*Standarb Library*/
    #include <string.h>                         /*String Library*/
    
                                                /*Aufgabe: Userdaten checken*/
                                                /*Parameter: vorname,nachname,passwort*/
                                                /*Return: bool (1,0)*/
    bool checkuser (char vorname[40], char nachname[40], char passwort[40], char admin_vorname[40], char admin_nachname[40], char admin_passwort[40])
    {
    bool userok;
    if (strcmp(vorname,admin_vorname) == 0 && strcmp(nachname,admin_nachname) == 0 && strcmp(passwort,admin_passwort) == 0)
    { userok = 1; }
    else { userok = 0; } 
    return userok;
    }
    
    int main(int argc, char *argv[])
    {
    char puffer[40] = "";                       /*Einlese Puffer*/
    char vorname[40] = "";                      /*Vornameeingabe des Users*/
    char nachname[40] = "";                     /*Nachnameeingabe des Users*/
    char passwort[40] = "";                     /*Passworteingabe des Users*/
    char admin_vorname[40] = "Berni";           /**/
    char admin_nachname[40] = "Berni";          /**/
    char admin_passwort[40] = "Berni";          /**/
    char userfile[10]       = "users.cfg";      /*Dateipfad der Userdaten*/
    bool userok = false;                        /*Korrektes Login?*/
    bool loadfile = false;                      /*Userdaten korretes geladen?*/
    
    /*Userfile laden*/
    loadfile = fopen("userfile","w+");
    if(loadfile == true)
    {                                           /*Wenn die Userdaten geladen wurden*/
      printf("%s erfolgreich geladen\n",userfile);
    
    }
    else
    {                                           /*Wenn die Userdaten nicht geladen werden konnten*/
      printf("%s Datei konnte nicht geladen werden\n",userfile);
    }
    
    printf("\nGeben Sie den Vornamen ein.\n");  /*Logindaten einlesen*/
    fgets(puffer,sizeof(puffer),stdin);
    sscanf(puffer,"%s",vorname);
    printf("Geben Sie den Nachnamen ein.\n");
    fgets(puffer,sizeof(puffer),stdin);
    sscanf(puffer,"%s",nachname);
    printf("Geben Sie das Kennwort ein.\n");
    fgets(puffer,sizeof(puffer),stdin);
    sscanf(puffer,"%s",passwort);   
    
                                                /*Prüfen ob die Logindaten korrekt sind*/  
    userok = checkuser(vorname,nachname,passwort,admin_vorname,admin_nachname,admin_passwort); 
    
      if(userok == 1)
      { 
        printf("Login Erfolgreich.\n");         /*Wenn eingeloggt*/
        printf("Beim naechsten Tastendruck wird das Programm beendet.\n");          
        getch();
      }
      else
      {    
        printf("Sie haben kein Zugriffsrechte.\n"); /*Wenn Fehler*/
        getch();
      }
    
    return 0;
    }
    

    Wenn ich bei den Variablen definierung

    char puffer[40] = "";                       /*Einlese Puffer*/
    char vorname[40] = "";                      /*Vornameeingabe des Users*/
    char nachname[40] = "";                     /*Nachnameeingabe des Users*/
    char passwort[40] = "";                     /*Passworteingabe des Users*/
    char admin_vorname[40] = "Berni";           /**/
    char admin_nachname[40] = "Berni";          /**/
    char admin_passwort[40] = "Berni";          /**/
    char userfile[10]       = "users.cfg";      /*Dateipfad der Userdaten*/
    bool userok = false;                        /*Korrektes Login?*/
    bool loadfile = false;                      /*Userdaten korretes geladen?*/
    

    Die Zahlen rausnehme und das programm kompiliere und starte, dann gibt er mir sofort aus, dass ich keinen Zugriff habe, obwohl ich noch gar nichts angegeben habe.. Also er wartet gar nicht, bis ich meine "Daten" eingegeben habe. Wiso das' muss ich nun die 40 trotzdem stehen lassen? Ein Namen könnte theoretisch ja auch länger sein 🙄



  • joa ist klar, habe ich vlt nicht deutlich genug gesagt, also:

    char admin_vorname[40] = "Berni";     /* hier kannste auch char admin_vorname[] = "Berni"; schreiben */
    
    char puffer[40] = "";               /* aber hier nicht */
    

    wenn du das so angibst

    []
    

    dann wird die größe das strings angenommen
    der da steht, wenn du also

    char string[] = "";
    

    dann ist der gleich null
    es wird kein speicher reserviert, also kann da auch nichts rein, du müsstest
    zusätzlich "manuell" speicher reservieren.

    naja kann das glaub ich net so gut erklären...
    wie wars mit einem guten tutorial pronix ?



  • Ach so...

    1.) Wenn ich der Variable am Anfang des Programmes keinen Wert zuweise muss ich Speicher reservieren.

    2.) Wenn ich der Variable am Anfang des Programmes einen Wert zuweise, nimmt er die grösse dieses Strings an.

    a.) Was ist jetzt wenn ich am Anfag einen String von 8 Zeichen mit var[] angebe und dann einen grösseren Wert zuweisen möchte? Sollte logischerweise einen Fehler ausgeben, oder einfach nur die ersten 8 Zeichen gespeichert werden, oder?

    b.) Kann ich eine Variable zuerst mit var[40] definieren und während dem Ablauf des Programmes auf var[80] erweitern, falls es nötig ist? Oder muss ich da bereits am Anfang auf 80 gehen?

    c.) Muss ich mich auf der Website registrieren, also mir einen eigenen Account anlegen um die Tutorials lesen zu können?

    d.) Für was ist eigentlich der * (Stern)? char *variable....?

    Herzlichen Dank für deine Hilfe! 👍



  • 1.)ja

    2.) ja, wert bzw. länge musst du angeben.
    außerdem musst du immer stringlänge +1 rechnen, weil der string noch automatisch
    mit \0 terminiert wird, dafür muss also noch platz sein.

    a) sollte ein fehler kommen, weil versucht wird auf nicht freigegebenen speicherbereich zu schreiben...

    b)mhm..., ich glaub du kannst die "erweitern" (probiers aus 😉 )

    c) schwachsinn 🤡 , probier doch ob du lesen kannst...ja kannst du

    d) zeigerdeklination



  • Herzlichen Dank für deine Antworten! Es hat mir sehr weitergeholfen und ich werde jetzt versuchen mit dem Tutorial (Buch) weiterzuarbeiten. ich hoffe wenn ich irgendwelche Fragen habe, darf ich mich wieder an dich wenden?
    Herzlichen Dank 👍



  • np
    du kannst es versuchen,
    aber ich bin selber ziemlich schlecht.
    d.h du wirst dann wahrscheinlich schon besser sein als ich^^



  • habt ihr beide eigentlich schon ein tutorial gelesen, in dem diese sachen beschrieben sind?
    waere naemlich ziemlich ratsam, wenn ich euch so beobachte...



  • wenn es konkrete fehler sind, wäre es super wenn du uns
    aufklären könntest 👍
    möchte schließlich nicht mit falschem wissen sterben.



  • erstmal find ich es gut, dass du (icepacker) eins der besseren tutorials vorgeschlagen hast und dass du (Bernasconi) es dir anschauen willst. damit ist schonmal viel gewonnen.

    zeigerdeklination hab ich echt noch nicht gehoert. kann stimmen oder nicht. ich fuer meinen teil nenne die sache "to cast" oder eingedeutscht "casten".

    ein array ist kein pointer. der unterschied ist vorhanden, wenn auch kaum wahrnehmbar.
    arrays lassen sich wie const pointer verwenden, ohne dass man sie casten muss.
    ein sizeof() auf arrays gibt die laenge des arrays in bytes zurueck, nicht die breite eines pointers.
    arrays haben dimensionslaengen gespeichert (int matrix[10][20]).
    wenn man arrays an eine funktion uebergibt, uebergibt man praktisch nur pointer. beispiel:

    // macht sinn
    void func(int *a, int len);
    
    // kann man machen, ist aber fehlleitend und bedeutet das gleiche wie int *a
    void func(int a[], int len);
    
    // ist unfug, weil arraygrenzen weder geprueft werden noch bei der uebergabe erhalten bleiben
    void func(int a[20]);
    
    // macht sinn, damit man das 3dimensionale array benutzen kann. alle bis auf die aeusserste dimension muessen angegeben werden.
    void func(int space[][20][10], int zdim);
    
    // die aeusserste dimension ([20]) anzugeben bringt nichts. es macht vielleicht den code lesbarer, kann aber auch fehlinformation verbreiten.
    void func(int matrix[20][10]);
    
    // ein typ von selbstkonstruierten matrizen, bei dem matrix ein "array" von pointern ist, von denen jeder wiederum auf eine zeile zeigt
    void func(int **matrix, int xdim, int ydim);
    
    // auch ein typ von matrix, bei dem man die indices selber berechnen muss, um das richtige element zu bekommen: matrix[y*xdim + x]. das macht der compiler bei gewoehnlichen arrays auch so, indem er die beim kompilieren noch vorhandenen dimensionslaengen verwendet.
    void func(int matrix, int xdim, int ydim);
    

    so, kurzer abriss. wer mehr wissen will, konsultiert ein gutes buch oder tutorial.



  • c.rackwitz schrieb:

    // auch ein typ von matrix, bei dem man die indices selber berechnen muss, um das richtige element zu bekommen: matrix[y*xdim + x]. das macht der compiler bei gewoehnlichen arrays auch so, indem er die beim kompilieren noch vorhandenen dimensionslaengen verwendet.
    void func(int matrix, int xdim, int ydim);
    

    Typo. Besser so

    void func(int * matrix, int xdim, int ydim);
    

    Kurt



  • Achso...
    ist ein bisschen sehr kompliziert. Aber ich lese gerade dieses ca. 800 Seitige Tutorial... wenn ich dann fertig bin, habe ich es hoffentlich verstanden.


Anmelden zum Antworten