C Konsoleneingabe stört bei fopen

raven16

Lieutenant
Registriert
Nov. 2008
Beiträge
580
Hallo

Programmablauf:
1. Benutzer gibt Namen der Datei ein
2. Dateipfad und Dateiname werden mit strcat verknüpft
3. Datei wird mit fopen geöffnet

Code:
void readFileLines(char* datei)
{
	char pfad[] = "D:\\Programme\\eclipse\\workspace\\Praktikum4\\src\\";
	FILE *d;

	datei = strcat(pfad,datei);
	printf("Folgende Datei wird eingelesen: %s",datei);
	if((d = fopen(datei,"r")) == NULL) puts("Error: Datei nicht gefunden.");
	else
	{
		//Zeilenausgabe
		puts("Die Datei wurde gefunden.");
	}
}

Problem, was ich habe:
Öffne ich die Stringverknüfpung mit fopen, so steht am Ende des Strings wahrscheinlich noch \r\n aus der Benutzereingabe. Wenn ich den Pfad direkt mit dem Dateinamen ohne Benutzereingabe in fopen Eintrage, dann funktionierts.

Ich habe auch mal einfach fopen(datei-3,"r") probiert, aber das klappt leider auch nicht.

Kann mir jemand nen Tipp geben?
 
Da Strings mit 0 terminiert werden würde ich in einer Schleife einfach von hinten alle Zeichen nullen, bis du das erste siehst welches du behalten willst.
 
Hast du denn genug Speicher für datei reserviert, dass es beim Konkatenieren nicht überläuft?
 
Freezedevil schrieb:
Hab gerade nochmal kurz gegooglet http://home.fhtw-berlin.de/~junghans/cref/MAN/strcat.htm

Wichtig ist also, dass pfad groß genug ist um beide Werte aufzunehmen. Das ist bei dir jedoch nicht der Fall.

Hmmm okay habe die strcat Funktion jetzt auch verstanden.
pfad ist dann ja echt zu klein.

Bin das aus anderen Programmiersprachen noch so gewohnt gewesen, dass der einfach den ersten String und 2. String verknüpft und als "neuen" String zurück liefert.
 
Zuletzt bearbeitet:
raven16 schrieb:
Bin das aus anderen Programmiersprachen noch so gewohnt gewesen, dass der einfach den ersten String und 2. String verknüpft und als "neuen" String zurück liefert.

Das heißt dann "C++" und ist Teil der Standardbibliothek. Bei C geht das nicht einfach so.
 
Jetzt hab ich aber nen Effekt den ich gar nicht verstehe. Ich möchte das \r\n weg haben und hab dann deshalb datei-3 in strcat gemacht. Laut Referenz würde er dann ja das \r\n\0 am Ende von datei Wegmachen und nach dem Verheiraten von Pfad und Datei ein \0 wieder anhängen

Leider gibt der jetzt egal was ich eingebe aus, dass der die Datei gefunden hat...
Code:
void readFileLines(char* datei)
{
	char pfad[BUFFER] = "D:\\Programme\\eclipse\\workspace\\Praktikum4\\src\\";
	datei = strcat(pfad,datei-3);
	FILE *d;

	if((d = fopen(datei,"r") == NULL))
	{
		puts("Error: Datei nicht gefunden.");
	}
	else
	{
		puts("Die Datei wurde gefunden.");
		puts("");

		//Datei schließen
		fclose(d);
	}
}
btw BUFFER hat den Wert 255
 
raven16 schrieb:
Code:
void readFileLines(char* datei)
{
	char pfad[BUFFER] = "D:\\Programme\\eclipse\\workspace\\Praktikum4\\src\\";
	[B]datei = strcat(pfad,datei-3);[/B]
	FILE *d;
[/QUOTE]

Was soll das bringen? Was soll das Programm machen? Was glaubst Du, was diese Anweisung macht?
 
datei-3 zieht von der Adresse "datei"
Ich glaub das ist nicht was du willst
 
blöderidiot schrieb:
Was soll das bringen? Was soll das Programm machen? Was glaubst Du, was diese Anweisung macht?
Ach mist stimmt, der kürzt jetzt einfach datei (wenn ich in der Aussage richtig liege) um 3 Zeichen. Aber da Datei ja sowieso viel größer als die Eingabe z.B. Datei.txt ist, bleibt trotzdem noch \r\n\0 dahinter :(

Oh man ich hasse langsam C ...

Langsam gehen mir Ideen aus :D
 
Zuletzt bearbeitet:
Freezedevil schrieb:
Ich hab doch in meinem ersten Post schon geschrieben was du machen kannst.

Da Strings mit 0 terminiert werden würde ich in einer Schleife einfach von hinten alle Zeichen nullen, bis du das erste siehst welches du behalten willst.

Meinst du das?
Wie und wo soll ich das denn machen? Ich müsste ja, bevor ich vom Benutzer den Namen der Datei eingeben lasse, schon datei komplett nullen, und dann (ich weiß nicht wie) -2 beim \n rechnen.
 
Nachdem du die beiden Strings konkateniert hast fängst du von hinten an an jede Stelle eine 0 zu schreiben die \r oder \n oder sonstige Steuerzeichen enthält.

Ich hab aber gerade nochmal selbst was getestet und es geht auch einfacher (Edit: dafür aber unflexibler). Für deinen Ansatz datei = strcat(pfad,datei-3); gibt es auch die passende funktion strncat. Ich würde es daher wahrscheinlich so ungefähr machen

Code:
void readFileLines(char* datei) {
	char* pfad = "/home/pi/src/";
	char full[strlen(pfad) + strlen(datei)];
	strcpy(full, pfad);
	datei = strncat(full, datei, strlen(datei)-2);
	...
}
 
Zuletzt bearbeitet:
raven16 schrieb:
Oh man ich hasse langsam C ...
Langsam gehen mir Ideen aus :D

Ich denke, Du solltest mal systematisch den "kanonischen" (guten, richtigen) Weg der Stringbearbeitung in C begeben. Hier ist mal ein Beispiel für sowas:
Code:
 int main(int argc, char *argv[])
{
 char pfad[] = "D:\\Programme\\eclipse\\workspace\\Praktikum4\\src\\";
 char dateiname[128];
 char dateipfad[256];

 printf("Dateinamen eingeben:");
 fflush(stdout);
 fgets(dateiname, 128, stdin);
 dateiname[strlen(dateiname) - 1] = '\0';
 strcpy(dateipfad, pfad);
 strcat(dateipfad, dateiname);
 
 ReadFileLines(dateipfad);

 return 0;
}

Deine Aufgabe: in obigem Quelltext jede Zeile kommentieren. Dranschreiben, was die macht und warum.

Wenn Du fertig bist, üben wir den "kanonischen Weg" des zeilenweisen Einlesens ;-)
 
blöderidiot schrieb:
Ich denke, Du solltest mal systematisch den "kanonischen" (guten, richtigen) Weg der Stringbearbeitung in C begeben. Hier ist mal ein Beispiel für sowas…
Nicht ganz ;-) Bei allen String-Funktionen *immer* die Version benutzen, die die Größe des Buffers bekommt. Hier also strncpy und strncat.

Beim Einlesen passieren auch noch lustige Dinge, wenn die Eingabe >127 Zeichen ist oder stdin direkt EOF ist. Schon klar, dass du es für die Übersichtlichkeit weggelassen hast, aber das sollte man immer dazu sagen. :)
 
Damit konnte ich das Problem \r\n bei Konsoleneingabe lösen:
Code:
//Zusammenfügen von Pfad und Datei
datei[strlen(datei)-2] = '\0'; //schreibt '\0' bei '\r'
strcat(dest,datei);
1. Ich schreibe einfach \0 an die Stelle, wo normalerweise \r durch die Konsoleneingabe steht
2. mit strcat hänge ich den Namen der Datei an den Pfad (dest) an
 
raven16 schrieb:
Damit konnte ich das Problem \r\n bei Konsoleneingabe lösen:
Code:
//Zusammenfügen von Pfad und Datei
datei[strlen(datei)-2] = '\0'; //schreibt '\0' bei '\r'
strcat(dest,datei);

Hast Du mal kontrolliert, was da rauskommt?

1. Ich schreibe einfach \0 an die Stelle, wo normalerweise \r durch die Konsoleneingabe steht

Es gibt kein '\r' im Programm. Nur '\n'. Das '\r' gibt es nur auf der Festplatte.

Noch ein Tipp: die Variablen so nennen, daß der Name dem entspricht, was der Inhalt bedeutet.
 
Lass dir doch einfach mal ausgeben was in deiner "char datei" drin is.
So versuch ich immer an die Problemlösung ran zu gehen einfach ein

printf("%s",datei);

hinter das zusammenbauen und schon siehst du was deine datei wirklich mit dem pfad macht.
hat mir schon oft die augen geöfnet und dabei lernt man was die Befehle wirklich machen
 
Zurück
Oben