[C/C++] Personenliste

Dieses Thema im Forum "Programmierung & Entwicklung" wurde erstellt von leex, 28. Juli 2009 .

  1. 28. Juli 2009
    Personenliste

    Hi Leute,
    habe ein kleines Problem bei meinem Programm
    hier mal der Source-Code:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
     struct schueler
     {
     int verwaltungsnummer, plz, geburtsdatum[3];
     char name[10], vorname[10], strasse[15], wohnort[20], schule[10], klasse[5], geschlecht, bemerkung[30];
     }a;
    
    struct schueler eingabe(void);
    void ausgabe(struct schueler);
    FILE *fp;
    int main(void)
    {
     struct schueler x;
     fp = fopen("myfile.txt", "w");
     if((fp=fopen("myfile.txt","w"))!=NULL)printf("Datei geoffnet!!!\n\n");
     else printf("ERROR, konnte Datei nicht oeffnen!!!\n");
     x=eingabe();
     ausgabe(x);
    
     fclose(fp);
    
    
    return(EXIT_SUCCESS);
    }
    
    struct schueler eingabe(void)
    {
     printf("Verwaltungsnummer: "); scanf("%d",&a.verwaltungsnummer);
    
     printf("Vorname: "); getchar(); fgets(a.vorname,20,stdin);
    
     printf("Name: "); fgets(a.name,20,stdin);
    
     printf("Geburtstdatum:\n");
     do{printf("Tag [dd]: "); scanf("%d",&a.geburtsdatum[0]);}while(a.geburtsdatum[0] >31);
     do{printf("Monat [mm]: "); scanf("%d",&a.geburtsdatum[1]);}while(a.geburtsdatum[1] >12 || a.geburtsdatum[1] < 1);
     do{printf("Jahr [jj]: "); scanf("%d",&a.geburtsdatum[2]);}while(a.geburtsdatum[2] < 1900);
    
     do{
     printf("Geschlecht [m/w]: "); getchar(); scanf("%c",&a.geschlecht);
     }while(a.geschlecht != 'm' && a.geschlecht != 'w');
    
     printf("Strasse: "); getchar(); fgets(a.strasse,20,stdin);
    
     printf("PLZ: "); scanf("%d",&a.plz);
    
     printf("Wohnort: "); getchar(); fgets(a.wohnort,20,stdin);
    
     printf("Schule: "); fgets(a.schule,20,stdin);
    
     printf("Klasse: "); fgets(a.klasse,20,stdin);
    
     printf("Bemerkung: "); fgets(a.bemerkung,50,stdin);
    
     fprintf(fp, "Verw.-Nr\t Vorn.\t\t Name\t\t Geb-Dat\t Geschlecht\t StrasseNr\t PLZ\t Ort\t Schule\t\t Klasse\t\t Bemerkung\n");
    
     fprintf(fp ,"%d\t\t %s\t %s\t %d.%d.%d\t %c\t %s\t %d\t %s\t %s\t %s\t %s\n",a.verwaltungsnummer, a.vorname, a.name, a.geburtsdatum[0], a.geburtsdatum[1], a.geburtsdatum[2], a.geschlecht, a.strasse, a.plz, a.wohnort, a.schule, a.klasse, a.bemerkung);
    
    
    }
    
    void ausgabe(struct schueler x)
    {
     printf("---------------------------------------------\n\n");
    
     printf("Verwaltungsnummer:\t %d",a.verwaltungsnummer);
    
     printf("\nName:\t\t\t %s",&a.name);
    
     printf("Vorname:\t\t %s",&a.vorname);
    
     printf("Geburtstdatum:\t\t %d.%d.%d\n",a.geburtsdatum[0],a.geburtsdatum[1],a.geburtsdatum[2]);
    
     printf("Geschlecht:\t\t %c\n",a.geschlecht);
    
     printf("Strasse:\t\t %s",&a.strasse);
    
     printf("PLZ:\t\t\t %d\n",a.plz);
    
     printf("Wohnort:\t\t %s",&a.wohnort);
     printf("Schule:\t\t\t %s",&a.schule);
     printf("Klasse:\t\t\t %s",&a.klasse);
    
     printf("Bemerkung:\t\t %s\n",&a.bemerkung);
    
    }
    

    Programm funktioniert soweit, nur die Ausgabe in der Datei bekomm ich nicht struckturiert hin. Da macht er irgendwie immer eine neue Zeile und nicht nebeneinander, so wie ich das will.
    Außerdem wird manchmal das Geschlecht einfach nicht angezeigt..sowohl in der Ausgabe in der Konsole, als auch in der Datei.

    Bitte um Hilfe.
    Danke im Vorraus

    PS.: bin noch Anfäger
     
  2. 28. Juli 2009
    AW: Personenliste

    ersma muss ich sagen dein code is hässlich. Kann sich jeder selber entscheiden wie er seinen code gestaltet aber ich persönlich finde es grausig das du mehrere anweisungen in eine zeile schreibst, auch wenn sie zusammen gehören. Einfach einen block mit nem kommentar drüber is imho übersichtilicher. Hab ers die hälfte deines codes deshalb übersehen.

    Zu deiner frage:
    fgets() hängt das eingelesene \n (wenn du auf die enter taste nach der eingabe drückst) an den string an.
    Wie das f bei fgets schon sagt ist es eigentlich zum auslesen aus FILES gedacht. Natürlich kann man es mit stdin auch zu eingaben von der tastatur verwenden aber in deinem fall würde ich gets() nehmen (macht genau das selbe nur dass du stdin nich als source angeben musst und es nimmt das abschließende \n nicht in den string auf, was ja meistens nicht gewollt ist wenn du von der tasta ausliest)


    mfg tobZel
     
  3. 28. Juli 2009
    AW: Personenliste

    Ich hab mal son paar allgemeine Fragen zu deinem code.
    1. wieso erzeugst du einen Schueler x, wenn der nie gebraucht wird?!
    2. hast du eine funktion die einen wert zurückgeben soll, macht das aber nicht --> sinnlos!!
    3. fordet deine funktion ausgabe einen wert, nutzt den aber nicht --> schon wieder sinnlos!!
    4. nutzt du für deine eingabe und ausgabe immer eine globale Variabel "a" die du eigentlich nicht brauchst!!

    Ich selber nutze kein printf etc mehr, aber soweit ich sehe übergibts du bei deinen strings bei printf immer einen Pointer, bei fprintf machst du das aber nicht. --> da stimmt irgentwas nicht

    zu deiner Frage: wann macht der das?! nur bei den srings, oder bei jeder variable?!
    wenns nur bei den strings ist, dann häng mal ans ende von jeden '\0' vllt hilft das, wenn ne dann musst du jeden einzelnen bearbeiten und die '\n' rauslöschen oder wie vorposter gesagt hat gets() nehmen um die '\n' am ende weg zu lassen!

    greeze C4rc4ss
     
  4. 28. Juli 2009
    AW: Personenliste

    ein paar Antworten:
    - den code verbessere ich noch bezüglich der übersichtlichkeit
    - zu der structure und den sinnlosen Dingen: ich verwende das so weil wir das in der Schule gerade gemacht haben und ich damit arbeiten will...werde versuchen auf eure Kritikpunkte einzugehen und das zu verbessern, sofern ich das hinbekomme
    - das mit dem gets hat funkioniert, Danke


    Bin gerne noch für Verbesserungsvorschläge und konstruktive Kritik offen. Wie gesagt bin noch Anfänger.
     
  5. 29. Juli 2009
    AW: Personenliste

    Is ja alles kein Problem jeder fängt irgendwann mal an
    ich kann dir ja mal paar sachen vorschlagen, die ich auf jeden Fall anders machen würde.

    1. Also als erstes würde ich um die Übersicht bei deinem Prohgramm zu bewähren keine globalen Variablen verwenden! Ich hab das am anfang auch gemacht und dann schnell gemerkt, dass man bei "größeren" ( da reichen schon 1000 zeilen Quellcode ) Projekten unglaublich schnell den Überblick verliert.

    Einfach die Funktionen so gestallten:
    Code:
    void Ausgabe( struct schueler &_schueler );
    struct schueler Eingabe ( FILE *_file );
    2. Bei der Übergabe von Struckturen und Klassen empfiehlt es sich Zeiger ( * ) oder Referenzen ( & ) zu verwenden, weil dann die Variabel nicht kopiert wird, sondern nur Pointer übergeben werden. Wobei es einfacher ist Referenzen zu nehmen, weil man sie wie normale Variabeln handeln kann und keine besondere Syntax beachten muss! ( bedenke aber, dass bei Zeigern und Referenzen Änderungen an der Variable in der Funktion sich auch auf die übergebe Variable auswirken!! )

    Dann musst du aber auch in den Funktionen die übergeben Variablen verwenden, bzw eine Variable auch zurückgeben!

    Code:
    void Ausgabe ( struct schueler &_schueler )
    {
     printf("---------------------------------------------\n\n");
    
     printf("Verwaltungsnummer:\t %d",_scheuler.verwaltungsnummer);
    
     printf("\nName:\t\t\t %s",&_schueler.name);
    
     printf("Vorname:\t\t %s",&_schueler.vorname);
    
     printf("Geburtstdatum:\t\t %d.%d.%d\n",_schueler.geburtsdatum[0]
     ,_schueler.geburtsdatum[1],_schueler.geburtsdatum[2]);
    
     printf("Geschlecht:\t\t %c\n",_schueler.geschlecht);
    
     printf("Strasse:\t\t %s",&_schueler.strasse);
    
     printf("PLZ:\t\t\t %d\n",_schueler.plz);
    
     printf("Wohnort:\t\t %s",&_schueler.wohnort);
     printf("Schule:\t\t\t %s",&_schueler.schule);
     printf("Klasse:\t\t\t %s",&_schueler.klasse);
    
     printf("Bemerkung:\t\t %s\n",&_schueler.bemerkung);
    
    }
    und bei der Eingabe auch die Variable auf jeden Fall zurückgeben ( eigentlich müsste dir dein Compiler auch einen Fehler ausspucken, wenn du eine Funktion benutzt, die einen Rückgabewert hat, aber nix zurückgibts! )

    Code:
    struct schueler Eingabe( FILE *_file )
    {
     struct schueler temSchueler;
     // Einlesen der Daten in temSchueler
     // und jetzt ganz wichtig
     return temSchueler;
    } 
    In der main darfst dann aber auch ne vergessen den File mit zu übergeben!
    Code:
    int main( void ) 
    {
     FILE *fp;
     struct schueler actSchueler;
     // File öffnen und co
     actSchueler = Eingabe ( fp );
     Ausgabe ( actSchueler );
     
     fclose( fp );
     printf ( "\n\nEverything went ok :D \nThanks for using my program!\n\n" );
    }
    bei Fragen oder Hilfestellungen kannst du mir auch gern ne pm schicken!

    greeze C4rc4ss

    PS: ne BW wenn wir helfen konnten wäre auch nicht schlecht
     
  6. 29. Juli 2009
    AW: Personenliste

    ok danke für die hilfe...werde am we mal versuchen das umzusetzen, sodass ichs auch verstehen
    bw haste ;-)
     
  7. 30. Juli 2009
    AW: Personenliste

    Deine Funktion Ausgabe, sowie Eingabe, ist fehlerhaft.
    Du übergibst printf() in Ausgabe mehrmals einen doppelten Zeiger:

    Code:
    struct schueler
     {
     int verwaltungsnummer, plz, geburtsdatum[3];
     char name[10], vorname[10], strasse[15], wohnort[20], schule[10], klasse[5], geschlecht, bemerkung[30];
     };
    
    Code:
    printf("\nName:\t\t\t %s",&_schueler.name);
    Du übergibst printf also einen Zeiger auf den Zeiger (struct schueler).name.

    Bei deiner Eingabefunktion gibst du eine Struktur zurück, das geht nicht, denn diese Variable ist nur innerhalb deiner Funktion gültig, es sei denn, du deklarierst sie als Statisch.

    Grüße.
     
  8. 30. Juli 2009
    AW: Personenliste

    Hm ich bin mir jetzt nicht ganz sicher, ich glaube aber das meine Funktion Eingabe stimmt. Da ich keine Referenz oder einen Zeiger zurück übergebe, wird der Rückgabewert in den Wert rein kopiert. Es wird also eine Kopie von meiner Variable temSchueler actschueler zugewiesen. Somit müsste es nach meinem Verständnis funktionieren.

    Und bei dem Printf bin ich mir nicht sicher ob das stimmt was du sagst, aber ich glaube dir jetzt, denn ich habe selber keinen richtig guten Schimmer mehr von printf(), da ich selber lieber std::cin/std::cout verwende.

    greeze C4rc4ss
     
  9. 30. Juli 2009
    AW: Personenliste

    werden das mal überprüfen....danke

    neue frage:
    habe meinem prog jetzt noch eine funktion hinzugefügt, die aber nicht funktioniert, bzw nicht richtig.
    Ich möchte das man am anfang angeben kann ob eine neue Datei erzeugt wird oder ob man einen Datensatz anhängen will an eine bestehende Datei.
    Jedoch weiß ich nicht wie man prüfen kann ob eine Datei schon vorhanden ist!?. Kann mir da einer weiterhelfen?
     
  10. 31. Juli 2009
    AW: Personenliste

    Um zu überprüfen ob eine datei schon vorhanden ist guckst du einfach ob die datei sich öffnen lässt.
    Code:
    FILE *fp;
    fp = fopen( filepath, "r" );
    if ( fp == NULL )
     printf( "Datei noch nicht vorhanden\n" );
    else
     printf( "Datei vorhanden\n" );
    
    fclose (fp);
    //jetzt file mit schreibrechten öffnen :D
    hoffe konnte helfen!

    greeze C4rc4ss
     
  11. 31. Juli 2009
    AW: Personenliste

    kk danke...funktioniert so..
    hab aber noch ein problem...
    bei manchen namen wie jessie zb oder matteo schreibt er mir diese nicht in die datei...keine ahnung warum!?

    hier nochmal mein aktueller code (noch nicht aufgeräumt )
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    
     char antwort;
     char dateiname[40], modus[5];
     struct schueler
     {
     int verwaltungsnummer, plz, geburtsdatum[3];
     char name[10], vorname[20], strasse[15], wohnort[20], schule[10], klasse[5], geschlecht, bemerkung[30];
     }a;
    
    struct schueler eingabe(void);
    //void ausgabe(struct schueler);
    FILE *fp;
    
    int main(void)
    {
     struct schueler x;
     int i=0;
    
     printf("Anfügen an Datei [a] oder neue Datei [n] "); scanf("%c",&antwort);
    
     if(antwort == 'n' || antwort == 'N')
     {
     i=1;
     printf("Dateiname: "); getchar(); gets(dateiname);
     //dateiname[strlen(dateiname)-1]='\0';
     printf("Modus: "); gets(modus);
     //dateiname[strlen(modus)-1]='\0';
    
     strcat(dateiname,".txt");
     fp = fopen(dateiname, modus);
    
     if((fp=fopen(dateiname, modus))!=NULL)printf("Datei geoffnet!!!\n\n");
     else printf("ERROR, konnte Datei nicht oeffnen!!!\n\n");
     }
    
     if(antwort == 'a' || antwort == 'A')
     {
     printf("Welche Datei soll verwendet werden? "); getchar(); gets(dateiname);
     strcat(dateiname,".txt");
    
     if ( (fp = fopen ( dateiname, "r" ) ) == NULL )
     {
     printf ( "Datei existiert nicht!!!\n\n" ); i=0;
     }else
     {
     printf ( "Datei existiert!!!!\n\n" ); i=1;
     fclose ( fp );
     }
     if(i=1)fp = fopen(dateiname, "a");
    
     }
    
    
    
     if(i==1){
     x=eingabe();}
     // ausgabe(x);
    
     fclose(fp);
     if(fclose == 0)printf("\nDatei geoffnet!!!\n\n");
     else printf("\nDatei geschlossen!!!\n");
    
    
    return(EXIT_SUCCESS);
    }
    
    struct schueler eingabe(void)
    {
     printf("Verwaltungsnummer: "); scanf("%d",&a.verwaltungsnummer);
    
     printf("Vorname: "); getchar(); gets(a.vorname);
    
     printf("Name: "); gets(a.name);
    
     printf("Geburtstdatum:\n");
     do{printf("Tag [dd]: "); scanf("%d",&a.geburtsdatum[0]);}while(a.geburtsdatum[0] >31);
     do{printf("Monat [mm]: "); scanf("%d",&a.geburtsdatum[1]);}while(a.geburtsdatum[1] >12 || a.geburtsdatum[1] < 1);
     do{printf("Jahr [jj]: "); scanf("%d",&a.geburtsdatum[2]);}while(a.geburtsdatum[2] < 1900 || a.geburtsdatum[2] > 2010);
    
    
     do{
     printf("Geschlecht [m/w]: "); getchar(); scanf("%c",&a.geschlecht);
     }while(a.geschlecht != 'm' && a.geschlecht != 'w');
    
     printf("Strasse: "); getchar(); gets(a.strasse);
    
     printf("PLZ: "); scanf("%d",&a.plz);
    
     printf("Wohnort: "); getchar(); gets(a.wohnort);
    
     printf("Schule: "); gets(a.schule);
    
     printf("Klasse: "); gets(a.klasse);
    
     printf("Bemerkung: "); gets(a.bemerkung);
    
     if(antwort=='n' || antwort=='n')
     {
     fprintf(fp,"------------------------------------------------------------------------------------------------------------------------------------------------------------\n");
     fprintf(fp,"|Verw.-Nr| Vorname | Name | Geb-Dat | Geschlecht | StrasseNr | PLZ | Ort | Schule | Klasse | Bemerkung |\n");
     fprintf(fp,"------------------------------------------------------------------------------------------------------------------------------------------------------------\n");
     }
    
     fprintf(fp,"\n|%8d|%10s|%12s|%4d.%d.%d|%12c|%25s|%9d|%16s|%12s|%10s|%20s|",a.verwaltungsnummer, a.vorname, a.name, a.geburtsdatum[0], a.geburtsdatum[1], a.geburtsdatum[2], a.geschlecht, a.strasse, a.plz, a.wohnort, a.schule, a.klasse, a.bemerkung);
    
    
    }
    
    /*void ausgabe(struct schueler x)
    {
     printf("---------------------------------------------\n\n");
    
     printf("Verwaltungsnummer:\t %d",a.verwaltungsnummer);
    
     printf("\nName:\t\t\t %s",&a.name);
    
     printf("Vorname:\t\t %s",&a.vorname);
    
     printf("Geburtstdatum:\t\t %d.%d.%d\n",a.geburtsdatum[0],a.geburtsdatum[1],a.geburtsdatum[2]);
    
     printf("Geschlecht:\t\t %c\n",a.geschlecht);
    
     printf("Strasse:\t\t %s",&a.strasse);
    
     printf("PLZ:\t\t\t %d\n",a.plz);
    
     printf("Wohnort:\t\t %s",&a.wohnort);
     printf("Schule:\t\t\t %s",&a.schule);
     printf("Klasse:\t\t\t %s",&a.klasse);
    
     printf("Bemerkung:\t\t %s\n",&a.bemerkung);
    
    }*/
    
     
  12. 31. Juli 2009
    AW: Personenliste

    hm ... das ist komisch.
    Die einzige erklärung die ich hätte wäre, dass du ja in deinem fprintf () die länge der strings limitierst und da denke ich, dass die vornamen dann zu lang sind um sie zu übergeben. Veränder mal die Länge und guck, ob sich an dem verhalten was verändert.

    greeze C4rc4ss

    //Edit: Text überarbeitet
     
  13. 31. Juli 2009
    AW: Personenliste

    das hab ich schon...ist lang genug...Thomas zb geht und is au net länger als Jessie
    hab dich in icq mal geaddet hast dich aber noch nicht gmeldet ;-)
     
  14. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.