Erstellen Sie eine Datei, falls keine vorhanden ist – C

Lesezeit: 3 Minuten

Benutzeravatar von karoma
Karoma

Ich möchte, dass mein Programm eine Datei öffnet, falls vorhanden, oder die Datei erstellt. Ich versuche den folgenden Code, aber ich erhalte eine Debug-Assertion bei freopen.c. Wäre es besser, wenn ich fclose und dann gleich danach fopen verwende?

FILE *fptr;
    fptr = fopen("scores.dat", "rb+");
    if(fptr == NULL) //if file does not exist, create it
    {
        freopen("scores.dat", "wb", fptr);
    } 

  • @tbert – Ich bin genauso besorgt, dass die Leute die Antwort, die den Fehler erklärt, nicht positiv bewerten. Gott sei Dank ist es Freitag 🙂

    – gbulmer

    23. März 2012 um 14:57 Uhr


Benutzeravatar von Dietrich Epp
Dietrich Ep

Normalerweise müssen Sie dies in einem einzigen Systemaufruf tun, sonst erhalten Sie eine Race-Condition.

Dies wird zum Lesen und Schreiben geöffnet und erstellt die Datei bei Bedarf.

FILE *fp = fopen("scores.dat", "ab+");

Wenn Sie es lesen und dann eine neue Version von Grund auf neu schreiben möchten, dann tun Sie dies in zwei Schritten.

FILE *fp = fopen("scores.dat", "rb");
if (fp) {
    read_scores(fp);
}

// Later...

// truncates the file
FILE *fp = fopen("scores.dat", "wb");
if (!fp)
    error();
write_scores(fp);

  • Es sieht so aus, als ob das OP versucht, es im schreibgeschützten Modus zu öffnen, wenn es bereits existiert (ich verstehe jedoch nicht, warum sie es in diesem Fall überhaupt erstellen wollen).

    – James McLaughlin

    23. März 2012 um 14:12 Uhr


  • Nun, wenn er nicht schreiben will, muss er das auch nicht. Soweit ich weiß, gibt es keine Möglichkeit, schreibgeschützt unter der Bedingung zu öffnen, dass es existiert, ohne eine unnötige Race-Bedingung zu erstellen.

    – Dietrich Ep

    23. März 2012 um 14:14 Uhr


  • @JamesMcLaughlin Ich dachte, der rb+ lässt mich auch schreiben? Nach diesem Codeabschnitt muss ich alles aus der Datei lesen und die Datei später von Grund auf neu schreiben.

    – Karoma

    23. März 2012 um 14:15 Uhr

Benutzeravatar von Shahbaz
Shahbaz

Wenn fptr ist NULL, dann haben Sie keine geöffnete Datei. Daher können Sie nicht freopen es, sollten Sie nur fopen es.

FILE *fptr;
fptr = fopen("scores.dat", "rb+");
if(fptr == NULL) //if file does not exist, create it
{
    fptr = fopen("scores.dat", "wb");
}

HinweisHinweis: Da das Verhalten Ihres Programms davon abhängt, ob die Datei im Lese- oder Schreibmodus geöffnet wird, müssen Sie höchstwahrscheinlich auch eine Variable beibehalten, die angibt, was der Fall ist.

Ein vollständiges Beispiel

int main()
{
    FILE *fptr;
    char there_was_error = 0;
    char opened_in_read  = 1;
    fptr = fopen("scores.dat", "rb+");
    if(fptr == NULL) //if file does not exist, create it
    {
        opened_in_read = 0;
        fptr = fopen("scores.dat", "wb");
        if (fptr == NULL)
            there_was_error = 1;
    }
    if (there_was_error)
    {
        printf("Disc full or no permission\n");
        return EXIT_FAILURE;
    }
    if (opened_in_read)
        printf("The file is opened in read mode."
               " Let's read some cached data\n");
    else
        printf("The file is opened in write mode."
               " Let's do some processing and cache the results\n");
    return EXIT_SUCCESS;
}

  • Dies hat eine Race-Bedingung, es schlägt fehl, wenn ein anderer Prozess die Datei zwischen den beiden Aufrufen erstellt fopen.

    – Dietrich Ep

    23. März 2012 um 14:13 Uhr

  • @DietrichEpp Hätte ich nicht gedacht!

    – Shahbaz

    23. März 2012 um 14:20 Uhr

  • Wenn der Ausgangspunkt „If fptr ist NULL, dann haben Sie keine geöffnete Datei. Daher können Sie nicht reopen it.“ erklärt das Verhalten, das das OP sieht (was ich glaube), dann könnte es sich aus Gründen der Klarheit lohnen, den Text zu bearbeiten, um diesen Punkt von der anschließenden Vorgehensweise zur Behebung zu trennen. (Auch Reopen sollte freopen sein)

    – gbulmer

    23. März 2012 um 14:38 Uhr


  • @Shahbaz – gerne geschehen. Ich denke, die andere Antwort kann den entscheidenden Punkt nicht identifizieren, den sie haben wird noch nie Arbeit. Die Leute könnten also diese Antwort lesen und ihr Mitnehmen könnte sich auf die Rennbedingungen beziehen, insbesondere da sie positiv bewertet wurde, obwohl sie eigentlich viel einfacher ist. Ich könnte mir vorstellen, Stunden damit zu verbringen, die Rennbedingungen festzunageln (was nicht da ist 🙂

    – gbulmer

    23. März 2012 um 14:55 Uhr

1407960cookie-checkErstellen Sie eine Datei, falls keine vorhanden ist – C

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy