2016-08-16 2 views
0

Ich machte einige einfache Lese-/Schreibvorgänge für Dateien mit MS Visual Studio. Hier ist eine vereinfachte Version des Codes Ich schrieb:Ein sehr seltsames Problem mit Std :: Fclose()

#include <cstdio> 
#include <cstring> 

void write_into_file(const char* filename); 

int main() 
{ 
    write_into_file("settings.ini"); 
    write_into_file("com4.ini"); 
    return 0; 
} 

void write_into_file(const char* filename) 
{ 
    FILE* f = std::fopen(filename, "wb"); 
    const char* text = "Some text I want to write..."; 
    std::fwrite(text, 1, strlen(text), f); 
    std::fclose(f); 
} 

Jedes Mal, wenn ich das Programm ausführen, wird sie fest und nicht zu Ende. Ich debuggte den Code und fuhr damit fort. Es stellte sich heraus, dass alle Teile des Codes in Ordnung sind und ohne Probleme ausgeführt werden, mit Ausnahme der Zeile, die fclose enthält. Ich meine, der Debugger bleibt stecken, wenn er diese Zeile erreicht. Warum passiert das und was ist das Problem?

EDIT: Ich vermuten, dass das Problem mit dem Namen von Dateien ist, speziell com4.ini. Also änderte ich den Code wie folgt:

#include <fstream> 
#include <sys/stat.h> 

void write_into_file(const char* filename) 
{ 
    std::ofstream fp(filename, std::ios::out); 
    if (fp.is_open()) 
     fp.close(); 
    struct stat info; 
    if (stat(filename, &info) != 0) 
    { 
     perror("An error occurred. Write permissions maybe?!!"); 
     return; 
    } 
    FILE* f = std::fopen(filename, "wb"); 
    const char* text = "Some text I want to write..."; 
    std::fwrite(text, 1, strlen(text), f); 
    std::fclose(f); 
} 

Das Komische ist, ist es die erste Datei erfolgreich schreibt. Für die zweite Datei besteht sie die Existenzprüfung und bleibt in der letzten Zeile stecken. Es wirft nicht einmal eine Ausnahme auf! Nur bleibt es nichts zu tun ...

+2

dies wie ein Berechtigungen oder Zugriffsproblem sieht für mich (aber ich bin nur spekulieren). Können Sie die Dateien manuell erstellen? (Wenn es ein Berechtigungsproblem ist, werden Sie nicht in der Lage sein). Wenn Sie vor std :: fclose einen std :: fflush-Aufruf hinzufügen, bleibt Ihre Anwendung stattdessen im fflush-Aufruf stecken. Wenn dies der Fall ist, würden die Lösungen (1) die Berechtigungen auf Betriebssystemebene korrigieren oder (2) das aktuelle Arbeitsverzeichnis in Ihrer Anwendung explizit festlegen oder (3) den Pfad für die Dateien explizit auf einen Speicherort festlegen, an den Sie Schreibzugriff haben . – utnapistim

+0

Es hat nichts mit diesem Problem, aber Sie müssen 'std :: strlen' anstelle von' strlen' verwenden. – ikh

+1

... oder ändern Sie in std :: string und verwenden Sie es Größe –

Antwort

4

Sie nicht COM4.ini als Dateinamen verwenden können, finden Sie https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx specifially

„CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, ​​COM5 , COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8 und LPT9. Vermeiden Sie auch diese Namen sofort gefolgt von einer Erweiterung, zum Beispiel wird NUL.txt nicht empfohlen Informationen finden Sie unter Namespaces. "

Es wird versucht, eine serielle Schnittstelle COM4 genannt, statt zu öffnen ...

+0

Also, wie kann ich nach solchen Namen suchen, ohne stecken zu bleiben? –

+0

@polfosol Wahrscheinlich ist der einfachste Weg, den Namensteil (vor dem Punkt und nach dem letzten Verzeichnistrennzeichen oder Laufwerksbuchstaben, falls vorhanden) mit der gegebenen Liste reservierter Namen zu vergleichen. –

+0

Alternativ können Sie reservierte Dateinamen als gültige Dateinamen zulassen. Wenn Sie "com4.ini" angeben, nimmt das System an, dass Sie wirklich meinen, was Sie sagen, d. H. Sie möchten in den COM-Port schreiben.In einigen Fällen ist es eine gute Sache zu tun. In Ihrem Fall ist es das nicht, also nennen Sie es zunächst nicht so, ohne eine "Kindermädchen" -Funktion schreiben zu müssen, um das zu verhindern. –