[C] veraltete Funktionen fputs und fgets

Wu-mc

Mitglied
Hallo Forum,

ich programmiere gerade ein recht einfach gestricktes Programm zum verarbeiten kopieren von Dateien. Jetzt wird mir vom Compiler bei fgets und fputs angezeigt das diese veraltet sind. Da ich versuche so gut wie möglich (für einen Anfänger) zu programmieren möchte ich der Sache nachgehen. Ist es noch sinnvoll diese Funktionen einzusetzen? Sind die neuen besser/sicherer? Wie werden die neuen fgets_s usw. verwenden? Oder sollte ich gleich auf andere Funktionen zurück greifen?

Ich muss eine Datei die erste Zeile auslesen, diese Zeile als Dateiname für eine zweite Datei nehmen und diese dann vom Quellort zum Zielort kopieren. Sollte ich das anders lösen als mit fgets und fputs? Funktionieren tut es zwar, aber ist es auch ein guter Programmierstil?

Kann mir jemand auf die schnelle noch Funktionen zum Löschen von Dateien sagen?

Hier mal mein bisheriger Code, bitte um Kritik und Anregungen:

Code:
	// Terminal ID Datei öffnen
	strncpy (szBuffer, szPathNameDevice, MAX_PATH);
	strncat (szBuffer, "id.txt", 6);
	fDevice = fopen (szBuffer, "r");

	if (!fDevice)
		return FALSE;

	// Terminal ID auslesen
	fgets (szTerminalID, 21, fDevice);
	szTerminalID[20] = '\0';

	while (!fclose (fDevice));

	// Datendatei auf Gerät anlegen
	strncpy (szBuffer, szPathNameDevice, MAX_PATH);
	strncat (szBuffer, "daten.txt", 10);
	fDevice = fopen (szBuffer, "w");

	if (!fDevice)
		return FALSE;

	// Datendatei im BackOffice öffnen
	strncpy (szBuffer, szPathNameFile, MAX_PATH);
	strncat (szBuffer, szTerminalID, 21);
	strncat (szBuffer, ".txt", 5);
	fBackOffice = fopen (szBuffer, "r");

	if (!fBackOffice)
		return FALSE;

	// Daten auf Gerät kopieren
	while (fgets (szLine, MAX_COL, fBackOffice))
	{
		fputs (szLine, fDevice);
	}

	while (!fclose (fDevice));
	while (!fclose (fBackOffice));

	return TRUE;
 
Soweit ich das beurteilen kann, ist gerade die Verwendung von fgets eine gute Sache, da man hier explizit die Größe angibt, die eingelesen werden soll. Es ist überhaupt immer zu empfehlen, solcherlei Funktionen zu nehmen, also beispielsweise strncpy anstelle von strcpy, da ein Angreifer durch ungeschützte Funktionen den Puffer überschreiben kann und damit Zugriff auf geschützte Speicherbereiche erlangen oder eigenen Code einschleusen kann. Das machst Du da ja schon ganz richtig. :)
Unter Linux gibts die man pages zum Programmieren gratis dazu, man 3 fgets liefert dazu auch folgendes:
BUGS
Never use gets(). Because it is impossible to tell without knowing the
data in advance how many characters gets() will read, and because gets()
will continue to store characters past the end of the buffer, it is
extremely dangerous to use. It has been used to break computer security.
Use fgets() instead.

Eine fgets_s Funktion ist mir jetzt unbekannt. Ist das eine Bibliothekserweiterung eines bestimmten Compilers? Ich würde Dir gerade als Anfänger dazu raten, so gut es geht strikt standardkonform zu arbeiten, und beim Kompilieren immer alle möglichen Warnungen anzuschalten, beispielsweise beim gcc: -W -Wall -pedantic
 
Vielen Dank schon mal für deine Antwort. Hm, vielleicht ist es ne Compiler Sache. Ich verwende das Visual Studio 2005. Hab aber auch gerade gesehen das es garnicht bei fgets war sondern bei fopen und auch bei strncat und strncpy. Hier mal eine Auszug vom Compiler:

Code:
c:\backoffice\alpha001\backofficefile.c(73) : warning C4996: 'strncat' wurde als veraltet deklariert
        c:\programme\microsoft visual studio 8\vc\include\string.h(143): Siehe Deklaration von 'strncat'
        Meldung: "This function or variable may be unsafe. Consider using strncat_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details."

c:\backoffice\alpha001\backofficefile.c(74) : warning C4996: 'fopen' wurde als veraltet deklariert
        c:\programme\microsoft visual studio 8\vc\include\stdio.h(234): Siehe Deklaration von 'fopen'
        Meldung: "This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details."
 
Okay also löschen geht mit remove ( ), jedoch hab ich mittlerweile 22 Warnungen vom Compiler, sind diese nun berechtigt oder nicht? Wenn nein, wie kann man sowas unterdrücken, wird langsam unübersichtlich, vor allem da das Projekt ja noch wächst.
 
Microsoft hat in VS 2005 alle tendenziell gefährlichen C-Funktionen als veraltet deklariert und sichere Versionen bereitgestellt. Die Warnung besagt alles, was du wissen willst:

A) Welche Ersatzfunktion verwendet werden soll

und B) wie man die Warnung deaktivieren kann (To disable deprecation, use _CRT_SECURE_NO_DEPRECATE). Das kannst du als #define in den Code setzen oder besser im Preprocessor-Tab eintragen.

Sicherer wäre natürlich, die angesprochenen Ersatzfunktionen zu verwenden.
 
und was heißt sicherer? welche Probleme können auftreten?

Aber wenn das eine Sache von Microsoft VS ist, dann könnten die Sourcen mit keinem anderen Programm mehr compiliert werden, seh ich das richtig?
 
Hi.
Wu-mc hat gesagt.:
und was heißt sicherer? welche Probleme können auftreten?
Die Funktionen führen mehr Checks durch (ist der Buffer groß genug) oder stellen sicher das ein String nullterminiert ist etc. und rufen eine Fehlerbehandlungsroutine auf falls ein Check fehlschlägt. Nachzulesen hier: http://msdn2.microsoft.com/en-us/library/8ef0s5kh.aspx.

Wu-mc hat gesagt.:
Aber wenn das eine Sache von Microsoft VS ist, dann könnten die Sourcen mit keinem anderen Programm mehr compiliert werden, seh ich das richtig?
Richtig. Aber für sowas gäbe es Präprozessorvariablen - so kann man beim Microsoft Compiler ab einer bestimmten Version die sicherere Funktion aufrufen, bei anderen Compilern die normale.

Ich denke es kann durchaus sinnvoll sein die neuen Funktionen zu verwenden - allerdings würde ich in erster Linie die Kompatibilität zu anderen Umgebungen anstreben und möglichst konform zum Standard arbeiten. Außerdem ist natürlich nicht zu vergessen das zusätzliche Checks auch einen negativen Einfluss auf die Performance haben.

Gruß
 
Zurück