• Aktualisierte Forenregeln

    Eine kleine Änderung hat es im Bereich Forenregeln unter Abschnitt 2 gegeben, wo wir nun explizit darauf verweisen, dass Forenkommentare in unserer Heftrubrik Leserbriefe landen können.

    Forenregeln


    Vielen Dank

Problem mit kleinem C Programm zur Dateiverwaltung und der Funktion gets()

T

Thomsn

Gast
Ich will ein einfaches Programm schreiben, mit dem ich Datein erstellen kann, löschen, weiterführen etc.

IDE: DEV-C++ 4.9.9.2 (Nutzt ANSI-Standard)


Dabei bin ich auf ein unerwartetes Problem gestoßen.

Es geht um die Funktion: gets()

Hier ein Ausschnitt des Programms.

#include <stdio.h>

void neue_datei();

main()
{
int auswahl;

printf(" [1] neue Datei anlegen\t[2] bestehende Datei bearbeiten\
\n [3] Datei loeschen\t[4] Programm beenden\n>");
scanf("%i", &auswahl);

switch(auswahl)
{
case 1:
neue_datei();
break;
default:
printf("\n\nFALSCHE EINGABE!!");
}
}

void neue_datei()
{
FILE *datei;
char dateiname[70];

printf("\nDateiname >");
gets(dateiname);
datei = fopen(dateiname, "w");
if(datei != NULL)
fclose(datei);
}

Das Problem, welches ich habe ist, dass das Programm nach dem Sprung in die Funktion "neue_datei" einfach beendet wird.
Man sieht zwar noch die Ausgabe "Dateiname >", aber das Programm ist beendet.
Es hat also nicht auf die eingabe von "dateiname" gewartet (was ja die aufgabe des "gets()" sein sollte), und folglich wurde auch keine Datei erstellt.

Aber falsch in dem Sinne kann die Funktion nicht sein, denn wenn ich einfach ein Programm schreibe, welches nur diese eine Aufgabe hat, funktioniert der Code.

#include <stdio.h>

main()
{
FILE *datei;
char dateiname[70];

gets(dateiname);
datei = fopen(dateiname, "w");
if(datei != NULL)
{
fclose(datei);
}
}

Der selbe Code, wie der aus der Funktion von oben, funktioniert hier wie erwartet.


Ich weiß einfach nicht, woran es liegt. :B

BTW, wenn ich den Code nicht in eine Funktion verlagere, also direkt in das switch() herein schreibe, passiert das selbe.

EDIT: oO Ich sehe gerade, dass das Forum die Code-Formatierung nicht übernommen hat...ich hoffe, es ist nicht zu unübersichtlich gewurden...eigentlich war er normal formatiert. :B
 
Ich hatte als ich das versucht hatte ein ähnliches Problem! Hab das ein bisschen anders gelöst! Hoffe das hilft dir weiter!


int main(void)
{
FILE *fp;

char dateiname[30];
char datei[30];

printf("Bitte gewuenschten Dateinamen eingeben: ");
fflush(stdin);
scanf("%s",dateiname);

sprintf(datei, "C:\\%s.txt",dateiname);
fp=fopen(datei, "a");

if(fp==NULL){
printf("Datei konnte nicht geoeffnet werden!");
}



Bei mir hats so funktioniert! Hoffe ich geb dir da keinen Blödsinn!

Jack the Ripper
 
Danke für den Code, leider funzt er bei mir nicht. *g*
Ich hab auch nicht wirklich erfahrung mit der Funktion fflush() und diesem standardinput dingens. :B

Vielleicht liegt es auch einfach an dem sprintf, ich bin mir nicht ganz sicher.

Aber ich werde mich früher oder später eh nochmal damit beschäftigen müssen.


Dank TekOne hab ich aber schonmal eine andere Alternative zu der Funktion gets().
Nämlich das gute alte scanf(). :B

Das hat dann den Code von oben zunächst auch funktionsfähig gemacht, führte beim weiterschreiben dann aber zu einem neuen Problem.

Das Prog sieht jetzt so aus:

#include <stdio.h>
#include <string.h>

void neue_datei();

main()
{
int auswahl;

printf(" [1] neue Datei anlegen\t[2] bestehende Datei bearbeiten\
\n [3] Datei loeschen\t[4] Programm beenden\n>");

scanf("%i", &auswahl);
switch(auswahl)
{
case 1:
neue_datei();
break;
default:
printf("\n\nFALSCHE EINGABE!!");
}
}

void neue_datei()
{
FILE *datei;
char dateiname[70], zeileninhalt[80];
int auswahl_beschreiben;

printf("\nDateiname >");
scanf("%s", dateiname);
datei = fopen(dateiname, "w");
if(datei != NULL) fclose(datei);

printf("\nSoll die Datei gleich beschrieben werden?");
printf("\n [1] Ja\t [2] Nein\n>");
scanf("%i", &auswahl_beschreiben);

if(auswahl_beschreiben == 1)
{
datei = fopen(dateiname, "w");
printf("\n\nEine Leerzeile beendet das Programm.\n\n");

scanf("%s", zeileninhalt);
while(strlen(zeileninhalt) > 0)
{
fprintf(datei, "%s\n", zeileninhalt);
scanf("%s", zeileninhalt);
}
fclose(datei);
}
}

Jetzt liegt das Problem in der while Schleife.

Das Programm liest zwar die Zeilen ein und schreibt sie in die Datei, aber dabei macht es nach jedem Wort einen Zeilenumbruch.
Ich habe keine Ahnung, warum. :B


Das zweite Problem ist die Schleife selbst, sie bricht nämlich nicht ab. :B

Die Bedingung für das Fortsetzen der Schleife ist: strlen(zeileninhalt) > 0

Das bedeutet, solange die Stringlänge > 0 ist, wiederholt sich die Schleife und eine Leerzeile sollte sie beenden, da die binäre Null von der Funktion strlen() nicht mitgezählt wird.

Aber leider läuft das Programm immer weiter und weiter, und will sich nicht beenden lassen. :B

Was ist so falsch daran?
 
Zu Problem 1:

fprintf(datei, "%s ", zeileninhalt);

Dann wirst du zwar nie einen Zeilenumbruch in der Datei stehen haben, die einzelnen Wörter werden aber mit Leerstelle "getrennt", denn "\n" = Zeilenumbruch.

Zu Problem 2:
Das Problem ist, dass die Konsole nicht auf Leerzeichen und Leerzeilen reagiert, das verdeutlicht das, wenn du das hier einbaust (anstelle deiner while-Schleife):

// scanf("%s", zeileninhalt);
while(1)
{
printf("neues while\n");
scanf("%s", zeileninhalt);
if (strlen(zeileninhalt) > 0)
{
printf("schreibe in Datei\n");
fprintf(datei, "%s ", zeileninhalt);
}
else
{
break;
}
}
 
Marscel am 06.08.2005 14:21 schrieb:
Das Problem ist, dass die Konsole nicht auf Leerzeichen und Leerzeilen reagiert
Hm, also das folgende Programm zeigt aber, dass es trotzdem so funzen kann:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

main()
{
FILE *stream;
char zeile[81], dateiname[67];
int zeilen = 0;

printf("\n\t\tTextzeilen erfassen\n");
printf("\nSpeichern unter >");
gets(dateiname);

if((stream = fopen(dateiname, "w")) == NULL)
{
printf("\nFehler beim Oeffnen!");
exit(1);
}

printf("\nLeerzeile beendet das Programm.");
printf("\n-------------------------------\n");

gets(zeile);
while(strlen(zeile) > 0)
{
fprintf(stream, "%s\n", zeile);
zeilen++;
gets(zeile);
}
fclose(stream);

printf("\n%i Zeilen wurden geschrieben.\n", zeilen);
}

PS: das is aus nem Buch, mit dem ich lerne. *g*
Aber es zeigt ja, dass das eigentlich so funzen sollte, wie ich erhofft hab.

Heißt: Es nimmt wie erwartet eine komplette Zeile als kompletten String auf, schreibt diesen, so wie er ist in die Datei (ohne Zeilenumbüche nach jedem Wort :B ), setzt nach der Zeile nen Zeilenumbruch und schreibt den nächsten String in die Datei..usw.
Dabei funktioniert auch die Schleifenbedingung super - kommt ein Leerstring, wird sie unterbrochen.
Wunderbar also. :]

Und warum geht das bei mir nicht? :B

Zumal dort sogar dieses vermaledeite gets() genutzt wird.
Und es funzt!! :B


BTW, ich beschäftige mich jetzt doch schonmal vorzeitig mit C++, das soll ja ergiebiger sein. *g*
 
Zurück