String wird in DosBox ausgegeben, aber nicht in der Datei



  • Zunächsteinmal die Funktion des Programms:
    Das Programm fragt nach Daten eines Films (Titel, FSK, Regie, Schauspieler etc.), die dann vom Nutzer eingegeben werden. Nach Eingabe der Daten werden diese dann zunächst in der DosBox ausgegeben und dann wird eine html-Datei erstellt, in welcher die Daten ebenfalls ausgegeben werden. So kann der Nutzer sich seine persönliche Filmesammlung auflisten.

    Dann bekommt ihr mal den kompletten Quellcode:

    #include <stdio.h>
    
    int main (void)
    { FILE *fp;
      char Filmname[40], Medium[20], BAR[20], ProdLand[40], Genre[20], Antwort, picpath[200];
      char Regie[40], Schauspieler1[40], Schauspieler2[40], Schauspieler3[40];
      int Bewertung, FSK;
      unsigned short Jahr, geszeit, zeit, hours;
      float Preis;
    
        puts("Herzlich Willkommen, /* anonym */ !");
    
        printf("\n\n\n");
    
        printf("Filmtitel: ");
        gets(Filmname);
        printf("Genre: ");
        gets(Genre);
        printf("Datentraegertyp: ");
        gets(Medium);
        printf("EAN: ");
        gets(BAR);
        printf("Erscheinungsjahr: ");
        scanf("%hd", &Jahr);
        printf("Preis: ");
        scanf("%f", &Preis);
        printf("FSK: ");
        scanf("%d", &FSK);
        printf("Laufzeit (in Min.): ");
        scanf("%hd", &zeit);
        geszeit=zeit;
        fflush(stdin);
        printf("Produktionsland: ");
        gets(ProdLand);
        printf("Name des Regisseurs: ");
        gets(Regie);
        printf("Name des Schauspielers #1: ");
        gets(Schauspieler1);
        printf("Name des Schauspielers #2: ");
        gets(Schauspieler2);
        printf("Name des Schauspielers #3: ");
        gets(Schauspieler3);
        printf("Bewertung: ");
        scanf("%d", &Bewertung);
    
        fflush(stdin);
    
        printf("\n\nName: %s\n", Filmname);
        printf("Bewertung: %d\n", Bewertung);
        printf("Genre: %s\n", Genre);
        printf("Typ: %s\n", Medium);
        printf("BAR-Code: %s\n", BAR);
        printf("FSK: ab %d Jahre\n", FSK);
        printf("Preis: %.2f Euro\n", Preis);
    
        while(zeit>60)
        { hours+=1;
          zeit-=60;
        }
        if(hours==1)
        { printf("Dauer: %hd Minuten (%hd:%hd Stunde)\n", geszeit, hours, zeit);
        }
        if(hours>1)
        { printf("Dauer: %hd Minuten (%hd:%hd Stunden)\n", geszeit, hours, zeit);
        }
        printf("Erscheinungsjahr: %hd\n", Jahr);
        printf("Land: %s\n", ProdLand);
        printf("Regie: %s\n", Regie);
        printf("Schauspieler 1: %s\n", Schauspieler1);
        printf("Schauspieler 2: %s\n", Schauspieler2);
        printf("Schauspieler 3: %s\n", Schauspieler3);
    
        fp = fopen("Filmesammlung.html","at");
    
        fprintf(fp, "<html>\n\n");
        fprintf(fp, "<head><title>Filmesammlung</title></head>\n\n");
        fprintf(fp, "<body>\n\n");
    
        printf("\nNeue Liste oder Anhang an alte Liste? (Antwort: n/a n:neu a: alt)");
        scanf("%s", &Antwort);
        if(Antwort == 'n' || Antwort == 'N')
          { fprintf(fp, "<center><font size=""12"">Filmesammlung</font></center><br><br>\n");
          }
    
        fprintf(fp, "<hr>"); 
        fprintf(fp, "<table><tr>");
        fprintf(fp, "\n\n<td><B><i>Name:</B></i> %s<br>\n", Filmname);
        fprintf(fp, "<B><i>Bewertung:</B></i> %d<br>\n", Bewertung);
        fprintf(fp, "<B><i>Typ:</B></i> %s<br>\n", Medium);
        fprintf(fp, "<B><i>Genre:</B></i> %s<br>\n", Genre);
        fprintf(fp, "<B><i>BAR-Code:</B></i> %s<br>\n", BAR);
        fprintf(fp, "<B><i>FSK:</B></i> ab %d Jahre<br>\n", FSK);
        if(hours==1)
        { fprintf(fp, "<B><i>Spieldauer:</B></i> %hd Minuten (%hd:%hd Stunde)<br>\n", geszeit, hours, zeit);
        }
        if(hours>1)
        { fprintf(fp, "<B><i>Spieldauer:</B></i> %hd Minuten (%hd:%hd Stunden)<br>\n", geszeit, hours, zeit);
        }
        fprintf(fp, "<B><i>Erscheinungsjahr:</B></i> %hd<br>\n", Jahr);
        fprintf(fp, "<B><i>Land:</B></i> %s<br>\n", ProdLand);
        fprintf(fp, "<B><i>Regie:</B></i> %s<br>\n", Regie);
        fprintf(fp, "<B><i>Schauspieler:</B></i> %s, %s, %s</td>\n", Schauspieler1, Schauspieler2, Schauspieler3);
        printf("\nCover einfuegen? (j/n)");
        scanf("%s", &Antwort);
        if(Antwort == 'j' || Antwort == 'J')
        { printf("Ist das Bild auf der Festplatte oder im Internet? (F/I)");
          scanf("%s", &Antwort);
          if(Antwort == 'f' || Antwort == 'F')
          { printf("Pfad eingeben: ");
            scanf("%s", &picpath);
            fprintf(fp, "<td><a href=%s><IMG src=%s width=250 height=300></a></td>\n", picpath, picpath);
          }
          if(Antwort == 'i' || Antwort == 'I')
          { printf("Link eingeben: ");
            scanf("%s", &picpath);
            fprintf(fp, "<td><a href=%s><IMG src=%s width=250 height=300></a></td>\n", picpath, picpath);
          }
        }
        fprintf(fp, "</tr></table>");
        fprintf(fp, "<br><br><br>\n\n\n\n");
    
        zeit=hours=geszeit=0;
    
        printf("\n\n");
        printf("Noch einen Film hinzufuegen? (j/n)");
        scanf("%s", &Antwort);
        printf("\n\n\n");
    
        while(Antwort == 'j' || Antwort == 'J')
        { fflush(stdin);
          printf("Filmtitel: ");
          gets(Filmname);
          printf("Genre: ");
          gets(Genre);
          printf("Datentraegertyp: ");
          gets(Medium);
          printf("EAN: ");
          gets(BAR);
          printf("Erscheinungsjahr: ");
          scanf("%hd", &Jahr);
          printf("Preis: ");
          scanf("%f", &Preis);
          printf("FSK: ");
          scanf("%d", &FSK);
          printf("Laufzeit (in Min.): ");
          scanf("%hd", &zeit);
          geszeit=zeit;
          fflush(stdin);
          printf("Produktionsland: ");
          gets(ProdLand);
          printf("Name des Regisseurs: ");
          gets(Regie);
          printf("Name des Schauspielers #1: ");
          gets(Schauspieler1);
          printf("Name des Schauspielers #2: ");
          gets(Schauspieler2);
          printf("Name des Schauspielers #3: ");
          gets(Schauspieler3);
          printf("Bewertung: ");
          scanf("%d", &Bewertung);
    
          fflush(stdin);
    
          printf("\n\nName: %s\n", Filmname);
          printf("Bewertung: %d\n", Bewertung);
          printf("Genre: %s\n", Genre);
          printf("Typ: %s\n", Medium);
          printf("BAR-Code: %s\n", BAR);
          printf("FSK: ab %d Jahre\n", FSK);
          printf("Preis: %.2f Euro\n", Preis);
          while(zeit>60)
          { hours+=1;
            zeit-=60;
          }
          if(hours==1)
          { printf("Dauer: %hd Minuten (%hd:%hd Stunde)\n", geszeit, hours, zeit);
          }
          if(hours>1)
          { printf("Dauer: %hd Minuten (%hd:%hd Stunden)\n", geszeit, hours, zeit);
          }
          printf("Erscheinungsjahr: %hd\n", Jahr);
          printf("Land: %s\n", ProdLand);
          printf("Regie: %s\n", Regie);
          printf("Schauspieler 1: %s\n", Schauspieler1);
          printf("Schauspieler 2: %s\n", Schauspieler2);
          printf("Schauspieler 3: %s\n", Schauspieler3);
    
          fprintf(fp, "<hr>");
          fprintf(fp, "<table><tr>");   
          fprintf(fp, "\n\n<td><B><i>Name:</B></i> %s<br>\n", Filmname);
          fprintf(fp, "<B><i>Bewertung:</B></i> %d<br>\n", Bewertung);
          fprintf(fp, "<B><i>Typ:</B></i> %s<br>\n", Medium);
          fprintf(fp, "<B><i>Genre:</B></i> %s<br>\n", Genre);
          fprintf(fp, "<B><i>BAR-Code:</B></i> %s<br>\n", BAR);
          fprintf(fp, "<B><i>FSK:</B></i> ab %d Jahre<br>\n", FSK);
          if(hours==1)
          { fprintf(fp, "<B><i>Spieldauer:</B></i> %hd Minuten (%hd:%hd Stunde)<br>\n", geszeit, hours, zeit);
          }
          if(hours>1)
          { fprintf(fp, "<B><i>Spieldauer:</B></i> %hd Minuten (%hd:%hd Stunden)<br>\n", geszeit, hours, zeit);
          }
          fprintf(fp, "<B><i>Erscheinungsjahr:</B></i> %hd<br>\n", Jahr);
          fprintf(fp, "<B><i>Land:</B></i> %s<br>\n", ProdLand);
          fprintf(fp, "<B><i>Regie:</B></i> %s<br>\n", Regie);
          fprintf(fp, "<B><i>Schauspieler:</B></i> %s, %s, %s</td>\n", Schauspieler1, Schauspieler2, Schauspieler3);
          printf("\nCover einfuegen? (j/n)");
          scanf("%s", &Antwort);
          if(Antwort == 'j' || Antwort == 'J')
           { printf("Ist das Bild auf der Festplatte oder im Internet? (F/I)");
             scanf("%s", &Antwort);
             if(Antwort == 'f' || Antwort == 'F')
             { printf("Pfad eingeben: ");
               scanf("%s", &picpath);
               fprintf(fp, "<td><a href=%s><IMG src=%s width=250 height=300></a></td>\n", picpath, picpath);
             }
             if(Antwort == 'i' || Antwort == 'I')
             { printf("Link eingeben: ");
               scanf("%s", &picpath);
               fprintf(fp, "<td><a href=%s><IMG src=%s width=250 height=300></a></td>\n", picpath, picpath);
             }
           }
          fprintf(fp, "</tr></table>");
          fprintf(fp, "<br><br><br>\n\n\n\n");
    
          zeit=hours=geszeit=0;
    
          printf("\n\n");
          printf("Noch einen Film hinzufuegen? (j/n)");
          scanf("%s", &Antwort);
          printf("\n\n\n");
        } 
    
        fprintf(fp, "</body>\n");
        fprintf(fp, "</html>");
        fclose(fp);
    
        printf("\n\n\nAuf Wiedersehen, /* anonym */...");
    
        fflush(stdin);
        getchar();
    
        return 0;
    
    }
    

    Ich habe hierauf 2 Fragen, wobei meine Hauptfrage 1) ist:

    1. Wenn man das Genre eingibt wird der String korrekt gelesen (Zeilen 22 und 139) und korrekt in der DosBox ausgegeben (Zeilen 54 und 171). Doch in der html-Datei spuckt er den String nicht aus (Zeilen 95 und 199) und ich habe absolut keine Ahnung warum. Alle anderen Strings werden korrekt ausgegeben. Ich hoffe ihr seht das oder könnt euch irgendwie vorstellen warum er das nicht ausgibt.

    2. In html schreibt man ganz korrekt ja folgendermaßen (Beispiel aus Zeile 220):

    <td><a href="%s"><IMG src="%s" width="250" height="300"></a></td>
    

    Ich bekomme das aber nur so hin

    <td><a href=%s><IMG src=%s width=250 height=300></a></td>
    

    Also ohne die Anführungszeichen um die definierten Werte. Ohne die Anführungszeichen geht es zwar auch, weil html ja so einiges verzeiht, aber ich möchte das lieber ganz korrekt darstellen. Wie schaffe ich es also, dass das Programm innerhalb der Anführungszeichen von C die Anführungszeichen selbst darstellt? Ich habe schon gedacht das mit Hilfe der ASCII-Tabelle und %c hinzuschreiben, aber in der ASCII-Tabelle sehe ich keine Anführungszeichen.



  • zu 1. mit dem MS-VC8 Express funktioniert die Ausgabe in die HTML-Datei

    zu 2.
    mit \" wird in einem char-array das Zeichen " ausgegeben, siehe Zeile unten als Beispiel aus deinem Code

    fprintf(fp, "<td><a href=%s><IMG src=\"%s\" width=250 height=300></a></td>\n", picpath, picpath);

    A.) Am Rande bemerkt, die scanf-Funktion mit char Antwort ist nicht sicher (VC8 meldet beim debuggen leichte Probleme), zumindest char Antwort[2] wäre besser, aber immer noch nicht schön. aber so ist es halt mit C ...

    B.) hours wird vor seiner Verwendung nicht initialisiert

    Gruss
    xator

    P.S.: warum nicht das ganze in C++ ....



  • also die Darstellung in meiner Antwort ist nicht korrekt dargestellt.

    um das Zeichen " innerhalb einer C-Zeichenkette darzustellen muss man eingeben

    Backslash"

    gruss
    xator



  • OK, das mit den Anführungszeichen funktioniert schonmal. Danke für die Antwort bezüglich darauf.

    Was du zu 1 sagst verstehe ich aber nicht. Ist MS-VC8 ein Compiler? Ich benutze DevC++.

    zu a) Dann sagtest du Antwort[2] wäre besser als Antwort. Warum gerade Antwort[2]? Meiner Meinung nach würde doch sogar Antwort[1] ausreichen? Man soll als Antwort ja ohnehin nur einen Buchstaben eingeben. Antwort[0] für den Buchstaben und Antwort[1] für das "\0".

    zu b) Was heißt nicht initialisiert? Ich habe jetzt vor der ersten Verwendung von hours "hours=0;" geschrieben? Ist das damit nun initialisiert oder ist das was anderes? Und welche Fehler könnten dadurch auftreten, wenn ich eine Variable nicht initialisiere? Also mein Prof meinte dazu, wenn man einer Variablen vor der Nutzung keinen Wert zuweist könnte da später dann unweigerlich irgendwelcher Datenmüll vom VOrgänger drin stehen. Ist es das?

    Ich benutze C++ nicht, weil ich es nicht kann und erst dabei bin C zu lernen. Alles schön der Reihe nach. Ich habe keinen Stress.



  • Zu b) In den Zeilen 61, 64, 67 ... wird hours gelesen, aber erst in Zeile 127 mit 0 initialisiert. Die Folge ist, dass dort Blödsinn drin steht, also ein unverlässlicher pseudozufälliger Wert. Je nachdem welchen Wert hours annimmt verhält sich dein Programm potentiell anders und zwar bei jedem Starten.

    Deine Zeilen mit gets sind unsicher. Du hast zum Beispiel 20 Bytes als Speicher für Medium reserviert, wenn der Nutzer nun mehr als 19 Zeichen eintippt (Nummer 20 braucht man fürs '\0'-Zeichen) hast du einen Pufferüberlauf: http://de.wikipedia.org/wiki/Buffer_overflow.
    Um das abzusichern kannst du zum Beispiel scanf benutzen.

    //Statt
    gets(Medium);
    //lieber
    scanf("%20s", Medium);
    

    Das ergibt dann das Problem, dass bei einer zu langen Eingabe nicht alles gelesen wird, und das was übrig bleibt wird beim nächsten mal gelesen, sodass der Rest von Medium in BAR landet.
    Es gibt verschiedene Möglichkeiten den Eingabepuffer zu leeren, musste mal nach suchen.

    Zu a) Selbiges Problem. Der Nutzer soll einen Buchstaben eingeben, aber Nutzer sind per Definition doof und geben gern Blödsinn ein. Dein Programm sollte damit klar kommen. Ein scanf("%c", Antwort) ließt schonmal nur ein Zeichen ein. Dann noch den Eingabepuffer leeren und es sollte klappen.

    Übrigens ist C++ nicht wirklich eine Erweiterung von C, sondern einfach anders. Du solltest nicht C lernen um C++ zu lernen, das ist eher kontraproduktiv. C lernen und C++ ignorieren ist hingegen eine gute Idee, C++ lernen und C ignorieren würde ich persönlich lassen. Beides lernen ist schwer, weil man automatisch Dinge vermischt die sich nicht gut vertragen.



  • Ich lerne C nicht, um später C++ zu lernen. Ich lerne C, weil ich einfach Vorlesungen zu C habe und es mich sehr interessiert. C++ werde ich dann lernen, wenn ich den Studiengang gewechselt habe und in dem Studiengang (Angewandte Informatik) kommt C++ auch erst im dritten Semester, aber gleichzeitig mit C. Im ersten Semester kommt erstmal Java, im zweiten objektorinetierte Programmierung und im dritten erst C und C++ parallel. Also dauert das noch eine Weile. Ich will auch lieber nichts überstürzen.

    Also gut, hours habe ich jetzt in Zeile 51 mit 0 initialisiert.

    OK, danke. Deine Erklärung hat meine Vermutungen bestätigt, wobei ich dachte, dass man %c nutzt, um Symbole aus der ASCII-Tabelle darzustellen. Zumindest habe ich %c nur in diesem Zusammenhang kennengelernt. Wozu ist %c noch alles gut? Übrigens könnte ich dafür doch genau so gut einfach scanf("%1s", &Antwort[0]); schreiben oder?

    Ich werde jetzt erstmal alle gets durch scanf ersetzen. Noch eine Frage zur Begrenzung: Wie man Zeichen begrenzt ist nun klar. Wie kann ich aber begrenzen, dass man bei FSK zum Beispiel einen maximalen Integer-Wert von 18 eingeben kann?

    nwp2 schrieb:

    Deine Zeilen mit gets sind unsicher. Du hast zum Beispiel 20 Bytes als Speicher für Medium reserviert, wenn der Nutzer nun mehr als 19 Zeichen eintippt (Nummer 20 braucht man fürs '\0'-Zeichen) hast du einen Pufferüberlauf: http://de.wikipedia.org/wiki/Buffer_overflow.
    Um das abzusichern kannst du zum Beispiel scanf benutzen.

    //Statt
    gets(Medium);
    //lieber
    scanf("%20s", Medium);
    

    Das ergibt dann das Problem, dass bei einer zu langen Eingabe nicht alles gelesen wird, und das was übrig bleibt wird beim nächsten mal gelesen, sodass der Rest von Medium in BAR landet.
    Es gibt verschiedene Möglichkeiten den Eingabepuffer zu leeren, musste mal nach suchen.

    Dazu nochmal kurz: Muss man da aber nicht im Code %18s schreiben? Der String geht doch von 0 bis 19 und das letzte Byte(19) muss doch für die \0 frei bleiben oder nicht?

    Edit: Habe das Programm jetzt umgeschrieben, doch wird das scanf für Genre einfach übersprungen und er fragt direkt nach dem Datenträgertyp.

    #include <stdio.h>
    
    int main (void)
    { FILE *fp;
      char Filmname[42], Medium[22], BAR[32], ProdLand[42], Genre[32], Antwort[1], picpath[200];
      char Regie[40], Schauspieler1[40], Schauspieler2[40], Schauspieler3[40];
      int Bewertung, FSK;
      unsigned short Jahr, geszeit, zeit, hours;
      float Preis;
    
        puts("Herzlich Willkommen, /* anonym */ !");
    
        printf("\n\n\n");
    
        printf("Filmtitel: ");
        scanf("%40s", &Filmname);
        printf("Genre: ");
        scanf("%30s", &Genre);
        printf("Datentraegertyp: ");
        scanf("%20s", &Medium);
        printf("EAN: ");
        scanf("%30s", &BAR);
        printf("Erscheinungsjahr: ");
        scanf("%hd", &Jahr);
        printf("Preis: ");
        scanf("%f", &Preis);
        printf("FSK: ");
        scanf("%d", &FSK);
        printf("Laufzeit (in Min.): ");
        scanf("%hd", &zeit);
        geszeit=zeit;
        fflush(stdin);
        printf("Produktionsland: ");
        scanf("%40s", &ProdLand);
        printf("Name des Regisseurs: ");
        scanf("%38s", &Regie);
        printf("Name des Schauspielers #1: ");
        scanf("%38s", &Schauspieler1);
        printf("Name des Schauspielers #2: ");
        scanf("%38s", &Schauspieler2);
        printf("Name des Schauspielers #3: ");
        scanf("%38s", &Schauspieler3);
        printf("Bewertung: ");
        scanf("%d", &Bewertung);
    
        fflush(stdin);
        hours=0; 
        printf("\n\nName: %s\n", Filmname);
        printf("Bewertung: %d\n", Bewertung);
        printf("Genre: %s\n", Genre);
        printf("Typ: %s\n", Medium);
        printf("BAR-Code: %s\n", BAR);
        printf("FSK: ab %d Jahre\n", FSK);
        printf("Preis: %.2f Euro\n", Preis);
    
        while(zeit>60)
        { hours+=1;
          zeit-=60;
        }
        if(hours==1)
        { printf("Dauer: %hd Minuten (%hd:%hd Stunde)\n", geszeit, hours, zeit);
        }
        if(hours>1)
        { printf("Dauer: %hd Minuten (%hd:%hd Stunden)\n", geszeit, hours, zeit);
        }
        printf("Erscheinungsjahr: %hd\n", Jahr);
        printf("Land: %s\n", ProdLand);
        printf("Regie: %s\n", Regie);
        printf("Schauspieler 1: %s\n", Schauspieler1);
        printf("Schauspieler 2: %s\n", Schauspieler2);
        printf("Schauspieler 3: %s\n", Schauspieler3);
    
        fp = fopen("Filmesammlung.html","at");
    
        fprintf(fp, "<html>\n\n");
        fprintf(fp, "<head><title>Filmesammlung</title></head>\n\n");
        fprintf(fp, "<body>\n\n");
    
        printf("\nNeue Liste oder Anhang an alte Liste? (Antwort: n/a n:neu a: alt)");
        scanf("%1s", &Antwort[0]);
        if(Antwort[0] == 'n' || Antwort[0] == 'N')
          { fprintf(fp, "<center><font size=\"12\">Filmesammlung</font></center><br><br>\n");
          }
    
        fprintf(fp, "<hr>"); 
        fprintf(fp, "<table><tr>");
        fprintf(fp, "\n\n<td><B><i>Name:</B></i> %s<br>\n", Filmname);
        fprintf(fp, "<B><i>Bewertung:</B></i> %d<br>\n", Bewertung);
        fprintf(fp, "<B><i>Typ:</B></i> %s<br>\n", Medium);
        fprintf(fp, "<B><i>Genre:</B></i> %s<br>\n", Genre);
        fprintf(fp, "<B><i>BAR-Code:</B></i> %s<br>\n", BAR);
        fprintf(fp, "<B><i>FSK:</B></i> ab %d Jahre<br>\n", FSK);
        if(hours==1)
        { fprintf(fp, "<B><i>Spieldauer:</B></i> %hd Minuten (%hd:%hd Stunde)<br>\n", geszeit, hours, zeit);
        }
        if(hours>1)
        { fprintf(fp, "<B><i>Spieldauer:</B></i> %hd Minuten (%hd:%hd Stunden)<br>\n", geszeit, hours, zeit);
        }
        fprintf(fp, "<B><i>Erscheinungsjahr:</B></i> %hd<br>\n", Jahr);
        fprintf(fp, "<B><i>Land:</B></i> %s<br>\n", ProdLand);
        fprintf(fp, "<B><i>Regie:</B></i> %s<br>\n", Regie);
        fprintf(fp, "<B><i>Schauspieler:</B></i> %s, %s, %s</td>\n", Schauspieler1, Schauspieler2, Schauspieler3);
        printf("\nCover einfuegen? (j/n)");
        scanf("%1s", &Antwort[0]);
        if(Antwort[0] == 'j' || Antwort[0] == 'J')
        { printf("Ist das Bild auf der Festplatte oder im Internet? (F/I)");
          scanf("%1s", &Antwort[0]);
          if(Antwort[0] == 'f' || Antwort[0] == 'F')
          { printf("Pfad eingeben: ");
            scanf("%s", &picpath);
            fprintf(fp, "<td><a href=\"%s\"><IMG src=\"%s\" width=\"250\" height=\"300\"></a></td>\n", picpath, picpath);
          }
          if(Antwort[0] == 'i' || Antwort[0] == 'I')
          { printf("Link eingeben: ");
            scanf("%s", &picpath);
            fprintf(fp, "<td><a href=\"%s\"><IMG src=\"%s\" width=\"250\" height=\"300\"></a></td>\n", picpath, picpath);
          }
        }
        fprintf(fp, "</tr></table>");
        fprintf(fp, "<br><br><br>\n\n\n\n");
    
        zeit=hours=geszeit=0;
    
        printf("\n\n");
        printf("Noch einen Film hinzufuegen? (j/n)");
        scanf("%1s", &Antwort[0]);
        printf("\n\n\n");
    
        while(Antwort[0] == 'j' || Antwort[0] == 'J')
        { fflush(stdin);
          printf("Filmtitel: ");
          scanf("%40s", &Filmname);
          printf("Genre: ");
          scanf("%29s", &Genre);
          printf("Datentraegertyp: ");
          scanf("%20s", &Medium);
          printf("EAN: ");
          scanf("%30s", &BAR);
          printf("Erscheinungsjahr: ");
          scanf("%hd", &Jahr);
          printf("Preis: ");
          scanf("%f", &Preis);
          printf("FSK: ");
          scanf("%d", &FSK);
          printf("Laufzeit (in Min.): ");
          scanf("%hd", &zeit);
          geszeit=zeit;
          fflush(stdin);
          printf("Produktionsland: ");
          scanf("%40s", &ProdLand);
          printf("Name des Regisseurs: ");
          scanf("%38s", &Regie);
          printf("Name des Schauspielers #1: ");
          scanf("%38s", &Schauspieler1);
          printf("Name des Schauspielers #2: ");
          scanf("%38s", &Schauspieler2);
          printf("Name des Schauspielers #3: ");
          scanf("%38s", &Schauspieler3);
          printf("Bewertung: ");
          scanf("%d", &Bewertung);
    
          fflush(stdin);
    
          printf("\n\nName: %s\n", Filmname);
          printf("Bewertung: %d\n", Bewertung);
          printf("Genre: %s\n", Genre);
          printf("Typ: %s\n", Medium);
          printf("BAR-Code: %s\n", BAR);
          printf("FSK: ab %d Jahre\n", FSK);
          printf("Preis: %.2f Euro\n", Preis);
          while(zeit>60)
          { hours+=1;
            zeit-=60;
          }
          if(hours==1)
          { printf("Dauer: %hd Minuten (%hd:%hd Stunde)\n", geszeit, hours, zeit);
          }
          if(hours>1)
          { printf("Dauer: %hd Minuten (%hd:%hd Stunden)\n", geszeit, hours, zeit);
          }
          printf("Erscheinungsjahr: %hd\n", Jahr);
          printf("Land: %s\n", ProdLand);
          printf("Regie: %s\n", Regie);
          printf("Schauspieler 1: %s\n", Schauspieler1);
          printf("Schauspieler 2: %s\n", Schauspieler2);
          printf("Schauspieler 3: %s\n", Schauspieler3);
    
          fprintf(fp, "<hr>");
          fprintf(fp, "<table><tr>");   
          fprintf(fp, "\n\n<td><B><i>Name:</B></i> %s<br>\n", Filmname);
          fprintf(fp, "<B><i>Bewertung:</B></i> %d<br>\n", Bewertung);
          fprintf(fp, "<B><i>Typ:</B></i> %s<br>\n", Medium);
          fprintf(fp, "<B><i>Genre:</B></i> %s<br>\n", Genre);
          fprintf(fp, "<B><i>BAR-Code:</B></i> %s<br>\n", BAR);
          fprintf(fp, "<B><i>FSK:</B></i> ab %d Jahre<br>\n", FSK);
          if(hours==1)
          { fprintf(fp, "<B><i>Spieldauer:</B></i> %hd Minuten (%hd:%hd Stunde)<br>\n", geszeit, hours, zeit);
          }
          if(hours>1)
          { fprintf(fp, "<B><i>Spieldauer:</B></i> %hd Minuten (%hd:%hd Stunden)<br>\n", geszeit, hours, zeit);
          }
          fprintf(fp, "<B><i>Erscheinungsjahr:</B></i> %hd<br>\n", Jahr);
          fprintf(fp, "<B><i>Land:</B></i> %s<br>\n", ProdLand);
          fprintf(fp, "<B><i>Regie:</B></i> %s<br>\n", Regie);
          fprintf(fp, "<B><i>Schauspieler:</B></i> %s, %s, %s</td>\n", Schauspieler1, Schauspieler2, Schauspieler3);
          printf("\nCover einfuegen? (j/n)");
          scanf("%1s", &Antwort[0]);
          if(Antwort[0] == 'j' || Antwort[0] == 'J')
           { printf("Ist das Bild auf der Festplatte oder im Internet? (F/I)");
             scanf("%1s", &Antwort[0]);
             if(Antwort[0] == 'f' || Antwort[0] == 'F')
             { printf("Pfad eingeben: ");
               scanf("%s", &picpath);
               fprintf(fp, "<td><a href=\"%s\"><IMG src=\"%s\" width=\"250\" height=\"300\"></a></td>\n", picpath, picpath);
             }
             if(Antwort[0] == 'i' || Antwort[0] == 'I')
             { printf("Link eingeben: ");
               scanf("%s", &picpath);
               fprintf(fp, "<td><a href=\"%s\"><IMG src=\"%s\" width=\"250\" height=\"300\"></a></td>\n", picpath, picpath);
             }
           }
          fprintf(fp, "</tr></table>");
          fprintf(fp, "<br><br><br>\n\n\n\n");
    
          zeit=hours=geszeit=0;
    
          printf("\n\n");
          printf("Noch einen Film hinzufuegen? (j/n)");
          scanf("%1s", &Antwort[0]);
          printf("\n\n\n");
        } 
    
        fprintf(fp, "</body>\n");
        fprintf(fp, "</html>");
        fclose(fp);
    
        printf("\n\n\nAuf Wiedersehen, /* anonym */...");
    
        fflush(stdin);
        getchar();
    
        return 0;
    
    }
    


  • Jolka schrieb:

    Wozu ist %c noch alles gut? Übrigens könnte ich dafür doch genau so gut einfach scanf("%1s", &Antwort[0]); schreiben oder?

    %c heißt direkt Datentyp char. scanf("%c", var) bedeutet "lese einen Wert vom Typ char ein und packe den Wert in var", genau das was du willst.

    %1s hingegen ist eine Zeichenkette der Länge 1. Der Unterschied ist, dass bei %1s noch das Sting-Ende-Zeichen hinterher kommt, damit ist %c ein einzelnes Zeichen, %1s sind 2 Zeichen. So ähnlich ist das mit dem Unterschied zwischen "a" und 'a'. "a" ist eine Zeichenkette der Länge 1 und ist 2 Zeichen lang, 'a' ist ein einzelnes Zeichen. "a" = {'a', '\0'}

    Jolka schrieb:

    Wie kann ich aber begrenzen, dass man bei FSK zum Beispiel einen maximalen Integer-Wert von 18 eingeben kann?

    Das geht nicht so direkt. Entweder du lässt alle Zahlen zu und überprüfst dann ob die Zahl gültig ist und lässt den Nutzer die Eingabe wiederholen wenn er Mist gebaut hat, oder du ließt zeichenweise und akzeptierst zum Beispiel eine 1 und wenn der Nutzer dann eine 9 eingibt löschst du die 9 wieder. Das sieht dann so aus als könne man keine 9 eingeben. Ist aber etwas kompliziert und nicht plattformunabhängig machbar.

    Jolka schrieb:

    Dazu nochmal kurz: Muss man da aber nicht im Code %18s schreiben? Der String geht doch von 0 bis 19 und das letzte Byte(19) muss doch für die \0 frei bleiben oder nicht?

    Der String geht von Medium[0] bis Medium[19], wobei spätestens Medium[19] das '\0'-Zeichen sein muss, soweit richtig. Von Medium[0] bis Medium[19] sind es allerdings 20 Zeichen. Kann man sich vielleicht so klar machen:
    Zeichen 1: Medium[0]
    Zeichen 2: Medium[1]
    ...
    Zeichen 19: Medium[18]
    Zeichen 20: Medium[19]
    Damit kannst du gefahrlos 19 Zeichen von Medium[0] bis Medium[18] schreiben und hast noch ein char für das '\0'-Zeichen übrig.

    Edit:
    Vielleicht war die Eingabe zu lang, keine Ahnung. Eingabepuffer leeren hast du vergessen, und vielleicht irgendwas machen wenn dieser nicht leer war. fflush(stdin) soll öfter mal nicht funktionieren, ließ mal das hier: http://www.c-plusplus.net/forum/viewtopic-var-t-is-257376-and-highlight-is-eingabepuffer+leeren.html
    Ich glaube

    while (getchar() != EOF);
    

    ist ganz vernünftig, aber ich bin nicht ganz sicher dass das immer geht.
    Um nicht noch 100 Zeilen mehr schreiben zu müssen könntest du eine Funktion bauen, sowas wie das hier:

    getString(char *formattedString, char *buffer){
        scanf(formattedString, buffer);
        while (getchar() != EOF);
    }
    


  • Also jetzt zeigt er mir den Wert von Genre auch in der Datei an. Liegt daran, dass ich jetzt Code::Blocks benutzt habe. DevC++ scheint echt nicht so toll zu sein.

    Außerdem hab ich die ganzen scanf wieder durch gets ersetzt, da die scanf mehr Probleme brachten als sie lösten. Kannn aber auch mit DevC++ zusammenhängen. Wer weiß.

    Ich hätte da noch eine Frage wegen diesem Programm, aber das hat eigentlich nichts mit C zu tun, sondern mit html, also wäre das hier wohl verkehrt. Falls das nicht verkehrt ist sagt bescheid. Dann stelle ich die Frage doch noch. 🙂



  • soso freundchen horror stil, will ich doch mal versuchen dir zu helfen 😉

    Außerdem hab ich die ganzen scanf wieder durch gets ersetzt, da die scanf mehr Probleme brachten als sie lösten. Kannn aber auch mit DevC++ zusammenhängen. Wer weiß.

    gets ist böse, da es wie nwp2 schon gesagt hat die länge nicht testet...
    du solltest dir die tipps schon zu herzen nehmen, wir schreiben das nicht weil wir so spaß am tippseln haben...
    könnte auch sein das keiner mehr lust hat zeit zu investieren dir zu helfen wenn du die tipps eh nicht umsetzt...

    ich meine hier auch deine code formatierung...

    nun aber mal zu deinem teil...

    pack das doch alles schön in functionen und structuren, dann macht das mit c auch mächtig spaß:) und du kommst nicht auf die idee c++ zu verwenden da dort eh alles so viel schöner geht...

    typedef struct _eintrag{
      char Filmname[40];
      char Medium[20];
      char BAR[20];
      char ProdLand[40];
      char Genre[20];
      char Antwort[20];
      char picpath[200];
      char Regie[40];
      char Schauspieler1[40];
      char Schauspieler2[40];
      char Schauspieler3[40];
      int Bewertung;
      int FSK;
      unsigned short Jahr;
      unsigned short geszeit;
      unsigned short zeit;
      unsigned short hours;
      float Preis; 
    }eintrag;
    

    dann machst du eine function zum einlesen und eine zum ausgeben, und eine helper zum einlesen wie nwp2 schon schrieb...

    void getValueFromStdIn(char *formattedString, void *buffer){
      int buff;
      scanf(formattedString, buffer);
      while((buff=getchar()) != -1 && buff !='\n');
    }
    
    void printEintragToFile(FILE *fp,eintrag *film){
      fprintf(fp,
        "<B><i>Name:</i></B> %s<br>"
        "<B><i>Bewertung:</i></B> %d<br>"
        "<B><i>Typ:</i></B> %s<br>"
        "<B><i>Genre:</i></B> %s<br>"
        "<B><i>BAR-Code:</i></B> %s<br>"
        "<B><i>FSK:</i></B> ab %d Jahre<br>"
        ,film->Filmname
        ,film->Bewertung
        ,film->Medium
        ,film->Genre
        ,film->BAR
        ,film->FSK
        //....
      ); 
    }
    
    void readEintragFromStdIn(eintrag *film){
      printf("\nFilmname: ");
      getValueFromStdIn("%15s",film->Filmname);
      printf("\nBewertung: ");
      getValueFromStdIn("%d",&film->Bewertung);
      printf("\nMedium: ");
      getValueFromStdIn("%15s",film->Medium);
      printf("\nGenre: ");
      getValueFromStdIn("%15s",film->Genre);
      printf("\nBAR: ");
      getValueFromStdIn("%15s",film->BAR);
      printf("\nFSK: ");
      getValueFromStdIn("%d",&film->FSK);
      //....
    }
    

    und in der main dann so

    int main(void){
      eintrag loloNoob;
      readEintragFromStdIn(&loloNoob);
      printEintragToFile(stdout,&loloNoob);
      return 0;
    }
    

    hoffe das ist jetzt nicht voll buggy...

    deine html fragen hier rein...
    http://www.c-plusplus.net/forum/viewforum-var-f-is-31.html

    na dann mal viel spaß 😉



  • Außerdem hab ich die ganzen scanf wieder durch gets ersetzt, da die scanf mehr Probleme brachten als sie lösten. Kannn aber auch mit DevC++ zusammenhängen. Wer weiß.

    scanf() und seine Familie sind die einzigen Funktionen aus der Bibliothek, mit denen ich immer noch meine Probleme hab. Ich persönlich kann sie nicht ausstehen.

    //Statt
    gets(Medium);
    //lieber
    scanf("%20s", Medium);
    

    Statt scanf() kann man in dem Fall auch einfach fgets() verwenden, und stdin als FILE-Argument übergeben. fgets() kennt nämlich noch ein drittes Argument für die maximale Länge.

    Du kannst getrost so tun, als gäbe es gets() nicht. Es ist wohl nahezu immer eine schlechte Idee, von der Aussenwelt Daten anzunehmen und die Länge nicht zu begrenzen.

    Und deine Funktion strotzt auch vor fflush(stdin) , deshalb ist es leider eine Wolfroutine.
    🙂



  • noobLolo schrieb:

    soso freundchen horror stil, will ich doch mal versuchen dir zu helfen 😉

    Aha, alles klar.

    könnte auch sein das keiner mehr lust hat zeit zu investieren dir zu helfen wenn du die tipps eh nicht umsetzt...

    Ich hab die Tipps zwar umgesetzt, aber gut. Nur hatte ich damit später mehr Probleme als mit der anderen Variante.

    ich meine hier auch deine code formatierung...

    Tut mir ja sehr Leid, dass dir das nicht gefällt, aber ich halte mich lieber an den Stil meines Professors, den ich persönlich auch am übersichtlichsten finde und der mir in der Klausur am meisten von Nutzen sein wird.

    deine html fragen hier rein...
    http://www.c-plusplus.net/forum/viewforum-var-f-is-31.html

    na dann mal viel spaß 😉

    Danke.



  • Jolka schrieb:

    Ich hab die Tipps zwar umgesetzt, aber gut. Nur hatte ich damit später mehr Probleme als mit der anderen Variante.

    sag doch gleich du wolltest es dir so einfach wie möglich machen :p

    Jolka schrieb:

    Tut mir ja sehr Leid, dass dir das nicht gefällt, aber ich halte mich lieber an den Stil meines Professors, den ich persönlich auch am übersichtlichsten finde und der mir in der Klausur am meisten von Nutzen sein wird.

    ich glaub das ist ihm rille, wenn er sowas wie deinen ersten oder zweiten post sieht und dir ne gute note gibt dann schickst ihn mal hier vorbei, und das hat jetzt nichts mit der formatierung zu tun 😉

    Jolka schrieb:

    deine html fragen hier rein...
    http://www.c-plusplus.net/forum/viewforum-var-f-is-31.html
    na dann mal viel spaß 😉
    Danke.

    Bitte.


Anmelden zum Antworten