C - fopen() - hängt sich manchmal auf

SpeckHase

Grünschnabel
Hi,
vorne weg: Ich benutze Code::Blocks und beschäftige mich noch nicht all zu lang mit C.

Ich brauche für mein Programm jetzt fopen() und habe mich meines Erachtens auch komplett ans Lehrbuch gehalten. Mein Code sieht in etwa so aus:
Code:
FILE *datei;
        printf("Vor fopen");
       datei = fopen(argv[2], "w");
       printf("Nach fopen");
        if(datei != NULL)
            printf("Datei erfolgreich geoeffnet\n");
        else {
            printf("Fehler beim Oeffnen der Datei");
            return EXIT_FAILURE;
        }

/*Hier mache ich iwas mit fprintf*/
[.....]

flclose(datei);

Jetzt hängt sich das Programm aber "ab und zu" mal an genau der Stelle auf, wo ich fopen verwende. Soll heißen: Auf der Konsole wird noch "Vor fopen" ausgegeben, aber "Nach fopen" NICHT mehr.
Das kuriose ist: in sagen wir ca. 35% aller Fälle funktioniert alles problemlos.
Wobei ich den Eindruck habe, dass der Zeitabstand zwischen den Programmaufrufen dabei eine Rolle spielt. Ich arbeite nämlich jetzt schon etwas länger an dem Programm und mir ist´s eben erst aufgefallen. Hat vorher alles tadellos funktioniert und seitdem ich mal alle paar Sekunden zum Testen das Programm neustarten musste, habe ich den Fehler entdeckt.

Hoffe, mir kann hier einer helfen.
gruss micha
 
Hallo,
liegt es vielleicht an deinem Schreibfehler bei "fclose()" ?
Sonst fällt mir auf dem ersten Blick nichts ungewöhnliches auf. Wobei es bei falschem close auch nicht kompilieren sollte.

Achja lass dir mal dein Argument noch ausgeben, und checke ob die Datei existiert.
 
ups, hab das oben bloß nicht mit copy&paste eingefügt, im Code steht natürlich fclose(datei);

Was mir jetzt noch aufgefallen ist:
War jetzt ~15min nicht mehr am PC.....danach hat es wieder einige Male hintereinander funktioniert (hab nicht mitgezählt, waren denk ich mal 7-8 mal)....und dann habe ich wieder dasselbe Problem.

Achja lass dir mal dein Argument noch ausgeben, und checke ob die Datei existiert.

du meinst jetzt mein Argument argv[2] ?

.......WOW. Habs jetzt grad mal getestet. Mein Code sieht jetzt wie folgt aus:
Code:
FILE *datei;
        printf("Vor fopen");
        printf("Argv[2] %s\n", argv[2]);
       datei = fopen(argv[2], "w+");
       printf("Nach fopen");
        if(datei != NULL)
            printf("Datei erfolgreich geoeffnet\n");
        else {
            printf("Fehler beim Oeffnen der Datei");
            return EXIT_FAILURE;
        }
       
        ............
       fclose(datei);
Und jetzt hängt er sich doch tatsächlich wieder DIREKT nach "printf("Vor fopen");" auf. Also argv[2] wird gar nicht mehr ausgegeben.

Das ist mir aber wirklich schleierhaft, warum das so ist.
Meine main sieht zwar so aus:
Code:
int main(int argc, char *argv[])
allerdings definiere ich die ganzen Argumente kurz danach neu, damit ich´s besser testen kann.....also ich starte das Programm nicht über die Konsole, sondern direkt mit "Build & Run" in Code::Blocks......

edit: zum Thema, ob die Datei schon existiert: Tut sie! Allerdings kann man ja oben im neuen Code sehen, dass ich jetzt bei fopen als Parameter anstatt "w", hier "w+" genommen habe, so dass es da auch keine Probleme geben sollte......
 
Zuletzt bearbeitet:
Poste doch mal bitte den gesamten Code, wie du ihn auch kompilierst, sodass ich das ggf testen kann.
Aus dem Ausschnitt kann ich gerade nicht viel erkennen.
 
Rufst du es denn auch mit genug Argumenten auf? Bzw. prüfst du, ob du überhaupt genug Argumente erhalten hast, um in argv[2] einen gültigen Wert zu haben?
 
ja eigentlich schon......ich hab den Code jetzt mal soweit gekürzt, dass ich immer noch denselben Fehler bekomme, aber alle Operationen mit argv noch drin sind:
Code:
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    char modus;
   /* zum Testen: */
   argc = 5; argv[1] = "test"; argv[2] = "test.txt"; argv[3] = "12345"; argv[4] = "123";
 int *key;

       int i, j;
       /*Eingabeueberpruefung*/
       if(strspn(argv[3], "0123456789") < keylength) {
           printf("Die Eingabe war inkorrekt!");
           return EXIT_FAILURE;
       }
       if(strspn(argv[4], "0123456789") < n_length) {
           printf("Die Eingabe war inkorrekt!");
           return EXIT_FAILURE;
       }
        /* den Schluessel in key speichern */
       if((key = malloc(keylength * sizeof(int))) != NULL){
           for(i = 0; i < keylength; i++){
               *(key + i) = ((*(argv[3] + i)) - 48);
           }
       } else {
          printf("Kein Speicher mehr verfügbar!\n");
          return EXIT_FAILURE;
       }
       /*2te Eingabe*/
       int n = 0, power_of_ten = 1;
       for(i = 0; i < n_length; i++){
           for(j = 0; j < n_length - i - 1; j++){
               power_of_ten *= 10;
           }
           n += ((*(argv[4] + i) - 48) * power_of_ten);
           power_of_ten = 1;
       }
       free(key);


        /*Datei schreiben*/
       FILE *datei;
        printf("Vor fopen");
        printf("Argv[2] %s\n", argv[2]);
       datei = fopen(argv[2], "w+");
       printf("Nach fopen");
        if(datei != NULL)
            printf("Datei erfolgreich geoeffnet\n");
        else {
            printf("Fehler beim Oeffnen der Datei");
            return EXIT_FAILURE;
        }
        fclose(datei);
   }
   return EXIT_SUCCESS;
}

.......ok.....hab jetzt gerade nochmal die Zeile
Code:
 argc = 5; argv[1] = "creation"; argv[2] = "karten.txt"; argv[3] = "12789023456"; argv[4] = "300";
auskommentiert und die Argumente alle via Kommandozeile eingegeben......und siehe da: es klappt 100x hintereinander......

Wär aber toll, wenn mir trotzdem jemand sagen kann, was an dieser Zeile falsch ist.....und vor allem: warum es manchmal funktioniert und dann wieder nicht !******!?

edit: Quellcode gekürzt......mir ist das nämlich auch erst aufgefallen, als ich hier schon den halben Text geschrieben hab ;)

Doppeledit: Quellcode wieder eingefügt. Wenn ich Zeile 8-38 entferne funktioniert das Testprogramm einwandfrei......mit den Zeilen aber nicht mehr.
Jetzt bin ich völlig verwirrt.....
 
Zuletzt bearbeitet:
Hi

wenn du so
C++:
argc = 5; argv[1] = "test"; argv[2] = "test.txt"; argv[3] = "12345"; argv[4] = "123";
zum Testen Werte erzeugst (und dafür keine "echten" Parameter übergibst):
Wer sagt denn, dass es überhaupt ein argv[2] usw. gibt, dem man dann was zuweisen könnte?
...
argv ist ja praktisch ein Array aus Pointern (auf Strings).
Wenn man so einen Pointer hat kann man ihm schon was zuweisen,
aber das argv-Array muss erstmal genug Pointer haben. Nur argc setzen reicht nicht.

Und wenn man so dann irgendwelche anderen Sachen im Programm überschreibt kann schon mal was Seltsames wie dieses fopen-Problem passieren.

Noch was: Wenn die argv-Werte eventuell irgendwo im Programm direkt geändert werden (ohne zuerst in eine neue Variable kopiert zu werden) kommt es durch die Literale sowieso zu einem Problem.
 
Hallo SpeckHase,

wenn du dir Testdaten erzeugen willst, dann darfst du aus schon genannten Gründen nicht die an main() übergebenen Parameter verwenden sondern musst sie neu erzeugen:
C++:
int main( /*int argc, char *argv[]*/)  // Parameter auskommentieren
{
    // Beachten: argv[0] enthält immer den Programmnamen
    char* argv[] = { "myprogramm.exe", "test", "test.txt", "12345", "123" };
    int   argc   = 5;

    // ...
   
    return 0;    
}
Gruß
MCoder
 
Vielen Dank für die Hilfe!
Mit dem Code von MCoder klappts jetzt auch wunderbar.
argv ist ja praktisch ein Array aus Pointern (auf Strings).
Wenn man so einen Pointer hat kann man ihm schon was zuweisen,
aber das argv-Array muss erstmal genug Pointer haben. Nur argc setzen reicht nicht.

Und wenn man so dann irgendwelche anderen Sachen im Programm überschreibt kann schon mal was Seltsames wie dieses fopen-Problem passieren.

Da frage ich mich doch, mit wievielen pointern argv dann initialisiert wird. Kann ja nicht zufällig sein, oder!? Vor allem schmeisst er ja keinen Fehler, wenn ich "argv[2] = "test.txt" schreibe.....

Noch was: Wenn die argv-Werte eventuell irgendwo im Programm direkt geändert werden (ohne zuerst in eine neue Variable kopiert zu werden) kommt es durch die Literale sowieso zu einem Problem.
argv[2] benutze ich vorher ja überhaupt nicht. Ich benutze nur argv[1, 3 und 4].....und die ändere ich auch gar nicht, sondern prüfe nur auf richtige Eingabe etc.

Bin auf jeden Fall froh, dass mein Code nicht irgendwelche schwerwiegenden Fehler hat :D
funktioniert alles wunderbar, danke an alle nochmal :)
 
Da frage ich mich doch, mit wievielen pointern argv dann initialisiert wird. Kann ja nicht zufällig sein, oder!?
Vermutlich soviel, wie für die wirklich übergebenen Parameter gebraucht werden.
Weniger natürlich nicht, und mehr wäre Speicher/Zeitverschwendung.

Vor allem schmeisst er ja keinen Fehler, wenn ich "argv[2] = "test.txt" schreibe.....
Das ist eben ein großer Unterschied von C zu zB. Java.
Java prüft alles doppelt und dreifach (auch wenn man weiß, dass dieser Fehler dort nicht auftreten kann) und haut einem hunderte Exceptions um die Ohren.
C macht gar nichts in die Richtung.
Unter Anderem durch die fehlende Prüfung (und einige andere Sachen) kann man schnellere Programme als in Java machen, aber man muss dafür eben selbst auf sowas aufpassen.
Wenn so ein Fehler passiert hat man ein Problem.
 
Zurück