Probleme bei Programmieraufgabe



  • Hallo, zusammen!

    Okay, habe ich mir schon gedacht.

    Ich sage das aber mal im übertragenen Sinne:
    Wenn man Integrale rechnen kann, kommt einem das Ein-Mal-Eins auch sehr einfach vor.
    Man kann sich aber auch schon mit dem Ein-Mal-Eins schwer tun...

    Ich verstehe es natürlich voll, dass ihr nicht meine Arbeit machen wollt.
    Deswegen werde ich mich da selber rein hängen.



  • function
    <cstdio>
    fclose

    int fclose ( FILE * stream );

    Close file
    Closes the file associated with the stream and disassociates it.

    All internal buffers associated with the stream are disassociated from it and flushed: the content of any unwritten output buffer is written and the content of any unread input buffer is discarded.

    Even if the call fails, the stream passed as parameter will no longer be associated with the file nor its buffers.

    Parameters

    stream
    Pointer to a FILE object that specifies the stream to be closed.

    Return Value
    If the stream is successfully closed, a zero value is returned.
    On failure, EOF is returned.

    Nach dem fett markierten Teil sollte der return-Wert eigentlich egal sein. Du merkst es spätestens wenn du die Datei neu öffnen willst. Nehme ich an.



  • EOP schrieb:

    function
    <cstdio>
    fclose

    int fclose ( FILE * stream );

    Close file
    Closes the file associated with the stream and disassociates it.

    All internal buffers associated with the stream are disassociated from it and flushed: the content of any unwritten output buffer is written and the content of any unread input buffer is discarded.

    Even if the call fails, the stream passed as parameter will no longer be associated with the file nor its buffers.

    Parameters

    stream
    Pointer to a FILE object that specifies the stream to be closed.

    Return Value
    If the stream is successfully closed, a zero value is returned.
    On failure, EOF is returned.

    Nach dem fett markierten Teil sollte der return-Wert eigentlich egal sein. Du merkst es spätestens wenn du die Datei neu öffnen willst. Nehme ich an.

    Der return-Wert von fclose() ist nicht egal, wenn man erfahren möchte, ob alles wie gewünscht verlaufen ist, insbesondere bei vorangegangenen Schreiboperationen auf die Datei. Der fett markierten Teil besagt nur, dass es keinen Sinn ergibt, nach dem fclose(), egal ob fehlgeschlagen oder nicht, weitere Dateioperationen mit dem Filepointer durchzuführen, ohne die Datei erneut zu öffnen, wobei dieses Öffnen nun möglicherwiese, aber nicht zwingend, zu einem Fehler führt.



  • fclose() schrieb:

    Der return-Wert von fclose() ist nicht egal, wenn man erfahren möchte, ob alles wie gewünscht verlaufen ist, insbesondere bei vorangegangenen Schreiboperationen auf die Datei. Der fett markierten Teil besagt nur, dass es keinen Sinn ergibt, nach dem fclose(), egal ob fehlgeschlagen oder nicht, weitere Dateioperationen mit dem Filepointer durchzuführen, ohne die Datei erneut zu öffnen, wobei dieses Öffnen nun möglicherwiese, aber nicht zwingend, zu einem Fehler führt.

    Wer macht schon Dateioperationen wenn er zuvor die Datei geschlossen bzw. zu schließen versucht hat?


  • Mod

    EOP schrieb:

    Wer macht schon Dateioperationen wenn er zuvor die Datei geschlossen bzw. zu schließen versucht hat?

    Die Idee liegt nahe, zu versuchen, die Datei einfach noch einmal zu schließen.



  • SeppJ schrieb:

    EOP schrieb:

    Wer macht schon Dateioperationen wenn er zuvor die Datei geschlossen bzw. zu schließen versucht hat?

    Die Idee liegt nahe, zu versuchen, die Datei einfach noch einmal zu schließen.

    Haha, ziemlich cool gedacht:

    while (fclose(datei) == EOF)
      printf("\nFehler beim Schliessen der Datei! Wir versuchen es einfach noch einmal.\n");
    


  • Hallo, alle zusammen!

    Erstmal danke für eure bisherige Hilfe, mein Programm läuft inzwischen dank eurer Hilfe. 👍

    Eine Frage hätte ich allerdings noch:
    Ich muss mein Programm mit mehreren anderen Programmen jetzt in einem Menü abrufbar machen.
    Da unser Dozent das so möchte, haben ich jetzt jedes Programm in einer eigenen Datei als Funktion definiert, z.B.:

    Datei "teilprogramm_drucken.c"

    int funct_drucken()
    {
    ...
    }
    

    In einem weiteren Programm wird in einer Main-Funktion dann das Menü dargestellt, die Dateien der Funktionen werden oben per include aufgerufen.
    Die Funktion möchte ich dann an der entsprechenden Stelle des Quelltext vom Menü aufrufen und abspielen lassen.
    Also so:

    Datei "hauptmenue.c"

    ...
    #include "teilprogramm_drucken.c"
    
    ...
    
    int main(void)
    {
    do
    {
    switch...
    case...
    funct_drucken();
    ...
    }while...
    }
    

    Dieser Funktionsaufruf klappt bei einem Testprogramm
    (wie diesem:)

    ...
    #include "teilprogramm_drucken.c"
    ...
    int main(void)
    {
    funct_drucken();
    }
    

    ohne Schleifen wie if, for, while, switch-case und do-while einwandfrei,
    leider aber nicht in diesen Schleifen.

    Das Programm lädt die Funktionen zunächst scheinbar ordnungsgemäß, sie funktionieren bis zur ersten Benutzereingabe.
    Dann gibt aber das Programm irgendwie automatisch die Eingabe.
    D.h. das Programm pausiert nicht, sodass man Zeit für die Eingabe hat, sondern läuft mit irgendeinem Eingabewert weiter.
    Da diese Eingabe nicht der entspricht, welche ich in der Funktion festgelegt habe, bricht die Funktion ab.
    So habe ich das für eine falsche Eingabe festgelegt.

    Könnte mir einer von euch erklären, woran das eventuell liegen könnte und wie ich das fixen kann?
    Oder geht das generell nicht und man muss das irgendwie anders machen?

    Vielen Dank im Voraus für eure Hilfe, es ist toll, dass es dieses Forum gibt. 👍



  • C_AMATEUR schrieb:

    #include "teilprogramm_drucken.c"
    

    Man inkludiert keine .c-Dateien, man kompiliert diese. Das Interface der .c-Dateien packt man in Header-Dateien (.h), die inkludiert man.

    Warum? Nun, wenn man irgendwann Programme mit mehreren Übersetzungseinheiten hat und nie Interface-Dateien erstellt, sondern immer nur die Code-Dateien eingebunden hat, dann bekommt der Linker beim Zusammenführen eine Krise nach der anderen.

    So soll das also aussehen:

    /*foo.h*/
    #if !defined(FOO_H)
    #define FOO_H FOO_H
    
    int foo(void);
    
    #endif /*!defined(FOO_H)*/
    
    /*foo.c*/
    #include "foo.h"
    
    int foo(void)
    {
        /*....*/
    }
    

    Das kompilierst du dann zu foo.obj oder foo.a. Dann kann du in deinem Programm die Funktion foo so aufrufen:

    /*programm.c*/
    #include "foo.h"
    
    int main(void)
    {
        foo();
        return 0;
    }
    

    Dem Linker musst du dann halt noch sagen, dass er foo.obj/foo.a einbinden soll, sonst gibt er dir Fehlermeldungen wegen undefinierten Symbolen (Google nutzen für Linkerdoku).

    C_AMATEUR schrieb:

    Das Programm lädt die Funktionen zunächst scheinbar ordnungsgemäß, sie funktionieren bis zur ersten Benutzereingabe. Dann gibt aber das Programm irgendwie automatisch die Eingabe.

    Code zeigen! Wie lädst du die Eingabedaten?



  • C_AMATEUR schrieb:

    Dann gibt aber das Programm irgendwie automatisch die Eingabe.
    D.h. das Programm pausiert nicht, sodass man Zeit für die Eingabe hat, sondern läuft mit irgendeinem Eingabewert weiter.
    Da diese Eingabe nicht der entspricht, welche ich in der Funktion festgelegt habe, bricht die Funktion ab.
    So habe ich das für eine falsche Eingabe festgelegt.

    Könnte mir einer von euch erklären, woran das eventuell liegen könnte und wie ich das fixen kann?
    Oder geht das generell nicht und man muss das irgendwie anders machen?

    Nur geraten, da du keinen Code zeigst:
    Du liest mit scanf ein und daher ist das '\n' von der Entertaste noch im Eingabestrom.
    Danach machst du mit fgets weiter.

    Du kannst nach dem scanf den Rest der Eingabe (bis zum '\n') überlesen: https://www.c-plusplus.net/forum/p1146014#1146014

    Den Mist mit dem #include "teilprogramm_drucken.c" hat dir ja schon dachschaden erklärt.



  • Guten Abend,

    erstmal vielen Dank für eure Beiträge, das Unterdrücken des Rests hat das Problem gelöst.

    Es gibt allerdings ein weiteres Problem.

    Ich stelle euch mal den relevanten Teil des Menüs ein:

    int main(void){
    	int aktion;
    	int a;
    	a=1;
    	do {
    
    	printf("\n Waehlen sie eine Aktion aus, indem sie die dazugehoerige Zahl eingeben:\n ");
    	printf("(1) Schreiben mehrerer Saetze mit fortlaufender Geraetenummer \n ");
    	printf("(2) Anhaengen eines Satzes mit automatisch generierter Geraetenummer \n ");
    	printf("(3) Aendern eines beliebigen Satzes \n (4) Loeschen eines beliebigen Satzes \n ");
    	printf("(5) Druckeretikett eines beliebigen Satzes erstellen\n Folgende Aktion soll durchgefuehrt werden:\n");
    	scanf("%d",&aktion);
    
    	switch (aktion){
    		case 1 :f_erstellen();
    				printf("\nWollen sie noch eine Aktion durchfuehren?\n Fuer 'Ja' 1 eingeben\n Fuer 'Nein' 2 eingeben\n");
    				scanf("%d",&a); 
    				if (a!=1&&a!=2){
    					do{
    				printf("\nFalsche Eingabe. Wollen sie noch eine Aktion durchfuehren?\n Fuer 'Ja' 1 eingeben\n Fuer 'Nein' 2 eingeben\n");
    				scanf("%d",&a); 
    				} while (a!=1&&a!=2);
    
    				}
    				break;
    
    		 (...)
    
    		default: printf("\nBitte geben Sie eine der optionalen Aktionen von 1-5 an");
    		 }
    
    } while (a==1);
    
    }
    

    Das Programm soll nach Beendigung der Funktion wieder wenn gewünscht zum "Hauptmenü" zurückkehren. Dafür ist die Auswahl mit "Wollen Sie noch eine Aktion..." da.
    Vor dem Einbinden der Funktionen hat das auch noch einwandfrei funktioniert.

    Jetzt ist es aber so, dass die Funktionen einwandfrei ablaufen, dann kommt auch die Auswahl mit der Aktion, das Programm beendet sich aber nach der Eingabe und geht nicht wie gewünscht zum Menü zurück.

    Wäre echt super, wenn ihr mir da nochmal helfen könntet, dann sollte das Programm fertig sein.

    Vielen Dank im Voraus und noch einen schönen Abend.



  • Nimm einen Debugger oder lass dir die interessanten Werte (mit printf) ausgeben.


Anmelden zum Antworten