Mit C .txt zeilenweise einlesen

MrMorpheus

Grünschnabel
Hi Zusammen,
erstmal ja, ich hab die bereits die Suchfunktion benutzt, jedoch leider nichts gefunden.
Kurtzgesagt geht es um folgendes. Ich würde gerne eine Textdatei (.txt) zeilenweise auslesen und den Inhalt in eine Variable speichern. In der Datei befinden sich in jeder Zeile nur eine E-Mail Adresse. Diese will ich später manipulieren und wieder in eine Textdatei speichern.

Bisher habe ich folgendes: (mit "Pelles C für Windows")
Code:
#include <stdio.h>
#include <string.h>

int main (void)
{
  FILE *datei;
  char line;

  datei = fopen ("test.txt", "r");
  if (datei != NULL)
    {
	for(int i = 0; i < 5;i++) {
 		fseek(datei, i ,SEEK_SET);
		fread(&line,sizeof(char) ,1,datei);
		printf ("%i) %s\n",i,&line);
	}
	fclose (datei);
    }
  return 0;
}
Ausgegeben wird aber leider nur Käse, zerhackte Strings mit Sonderzeichen.
Bsp:
0) ??
1) ?@?
2) @
3)
4) 1

Wie ihr seht, bin ich noch blutiger Anfänger und hoffe auf euer Hilfe =)

Danke euer MrMorpheus
 
Hi also du hast ein paar Fehler gemacht also....(siehe quellcode)

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

int main (void)
{
  FILE *datei;
  char line;
	int i; // du darfst i nicht in der for-Schleife deklarieren wenn der Compiler nicht meckert ist er auf C++ eingestellt dort geht das..... 
  datei = fopen ("test.txt", "r");
  if (datei != NULL)
    {	
	
	for(i = 0; i < 5;i++) {
 		

		//fseek(datei, i ,SEEK_SET);	//fseek kannst du dir eigentlich sparen da der "curser" immer um eines weiter geschoben wird
		fread(&line,sizeof(char) ,1,datei); //hier stimmt alles wobei ich dir raten würde Highlevel funktionen zu benutzen aber können sollte man beides (also lern)..
		printf ("%i) %c\n",i,line); //hier war der eigentliche Fehler also "printf ("%i) %s\n",i,&line);"  %s ist für Strings da und erwartet eine Adresse wie du auch mit dem & machen wolltest allerdings endet jeder String mit einem '\0' was eine einzelen Variable wie in deinem Fall nicht tut......
	}
	fclose (datei);
    }
  return 0;
}

Also das ganze war jetzt nur mal so im schnell durchlauf.

Solltest du ein gutes Buch suchen kann ich dir C von A bis Z empfehlen von Jürgen Wolf kann man auch Online gratis lesen..... http://www.pronix.de/pronix-4.html

Dort werden Files genau durchbesprochen......



mfg mike4004
 
Hi mike4004,
erst einmal danke für die Korrekturen. Sehe nun zumindest keine Sonderzeichen mehr. =)Danke auch für den Tipp (eBook), das werde ich mir die Tage mal zu Gemüte führen.

Nun habe ich nur noch das Problem, dass ich immer nur ein "g" für den Inhalt jeder Zeile erhalte.
Mit folgendem Code:
Code:
int main (void)
{
  FILE *datei;
  char line;
   int i ;
  datei = fopen ("test.txt", "r");
  if (datei != NULL)
    {
	for(i = 0; i < 10;i++) {
 		//fseek(datei, i ,SEEK_SET);
		fread(&line,sizeof(char),1,datei);
		printf ("%i) %c\n",i ,&line);
	}
	fclose (datei);
    }

  return 0;
}
Das Ergebnis ist dann folgendes:
Code:
0) g
1) g
2) g
3) g
4) g
5) g
6) g
7) g
8) g
9) g
Hättest du evt. noch einen Tipp woran es liegen könnte?
PS: Welche Umgebung ist für einen Anfänger zu empfehlen?

euer MrMorpheus ;-)
 
Hi

bei
C:
printf ("%i) %c\n",i ,line);
line muss das & weg! sonst übergibst du die Adresse der Variable und nicht den Wert und dafür ist %c nicht ausgelegt....


Hi also soltest du unter Windows programmieren nim DevC++ (einfach googlen) Das ist ne super IDE und gratis und meiner Meinung nach sogar besser als Visual Studio.

Naja und wenn du unter linux programmierst würde ich die empfehlen mit make und natürlich gcc zu arbeiten und irgent einem Texteditior (mein Tipp Gedit) und erst später ne IDE wie zb Anjuta zu benutzen......

Habe gerade gelesen das du zeilenweise lesen willst aller dings war der Quellcode schon immer auf zeichen weise aus gelegt. Frage was willst du den?


mfg mike4004
 
Zuletzt bearbeitet:
Hi

habe es jetzt so verändert das es zeilen weiße ließt...

C:
#include <stdio.h>
#define LAENGE 100 //länger der einzelnen Zeilen
#define ANZAHL 10 //Anzahl der Zeilen


int main (void)
{
  FILE *datei;
  char line[ANZAHL][LAENGE];
   int i ;
  datei = fopen ("test.txt", "r");
  if (datei != NULL)
    {
	for(i = 0; i < ANZAHL;i++) {
 		//fseek(datei, i ,SEEK_SET);
		fgets(line[i],LAENGE,datei);  //zeilen weise lesen mit fgets...
		printf ("%i) %s\n",i ,line[i]);
	}
	fclose (datei);
    }

  return 0;
}

mfg mike4004
 
Hi mike34004,
danke für deine Hilfe!
Da Tutorials.de einigezeit down war hab ich mir mal den Link von dir näher angesehn und bin dabei auf eine sehr elegante Weise (wie ich meine) gestoßen um mein Problem zu lösen.

mit folgendem Code:
Code:
#include <stdio.h>
#include <stdlib.h>

int main(void) {
	FILE *fh;
	char name[30], addr[30], top[3];
	
	fh = fopen("user.txt", "r");

	while((fscanf(fh,"%s@%s.%s\n",&name,&addr,&top)) != EOF )
	fprintf(stdout,"Name: %s\nAdresse: %s\nTopLevel: %s\n",name,top);

	return EXIT_SUCCESS;
}
Vorab: habe bei fscanf es bereits mit und ohne & probiert, im Ergebniss war kein Unterschied festzustellen.
Problem hier ist, dass der komplette Inhalt, in dem Fall die E-Mail Adresse, sich in name befindet. Das ganze sieht dann so aus:
Code:
Name: 345@asd.de
Adresse: xR?
TopLevel:
Name: 456@ert.ru
Adresse: xR?
TopLevel:
Name: 123@rtz.df
Adresse: xR?
TopLevel:
Name: 234@sdf.as
Adresse: xR?
TopLevel:

Wäre nett wenn du vieleicht noch einen Tipp hättest.

lg MrMorpheus

PS: Hab DevC++ bereits ausprobiert, jedoch erhalte ich immer folgenden Fehler:
PFAD\workspace\Makefile.win [Build Error] [main.o] Error 1
 
Hi.
Vorab: habe bei fscanf es bereits mit und ohne & probiert, im Ergebniss war kein Unterschied festzustellen.
Das liegt daran, das es bei statischen Arrays keinen Unterschied gibt. Eine Arrayvariable ist lediglich ein Zeiger der auf die Anfangs-Adresse des Arrays zeigt. Bei statischen Arrays gilt: array == &array (also die Adresse der Arrayvariablen ist gleich dem Wert der Arrayvariablen)

Bei allen anderen Variablen muß man bei scanf immer mit dem Adressoperator die Adresse übergeben - bei printf jedoch nicht.
Problem hier ist, dass der komplette Inhalt, in dem Fall die E-Mail Adresse, sich in name befindet. Das ganze sieht dann so aus:
Code:
Name: 345@asd.de
Adresse: xR?
TopLevel:
Name: 456@ert.ru
Adresse: xR?
TopLevel:
Name: 123@rtz.df
Adresse: xR?
TopLevel:
Name: 234@sdf.as
Adresse: xR?
TopLevel:
Am besten ist es wenn du wirklich erstmal zeilenweise die Daten aus der Datei liest (das geht eben mit fgets) und danach z.B. mit sscanf die Daten weiterverarbeitest.

PS: Hab DevC++ bereits ausprobiert, jedoch erhalte ich immer folgenden Fehler:
PFAD\workspace\Makefile.win [Build Error] [main.o] Error 1
Du hast vermutlich die Version ohne Compiler installiert - und das ist beim Compilieren natürlich ein Problem. Wahrscheinlich steht auch noch irgendwo im Log-Fenster irgendwas von Programm nicht gefunden o.ä.

Gruß
 
PS: Nachdem ich etwas mit dem Code experimentiert habe, stellte ich fest, dass das Problem evt. im Suchmuster von "fscanf" liegt. Sobald ich "name" als Integer deklariere und mit %d versuche zu lesen, funktioniert es. (E-Mail adressen wurden dementsprechend angepasst).

Daher vermute ich, dass das erste "%s" gleich auf die ganze E-Mail adresse matched und die restlichen Variablen leer bleiben.

Aber eigentlich kann man doch eine E-Mail Adresse nur mit "%s@%s.%s"zerlegen, oder?
 
PS: Nachdem ich etwas mit dem Code experimentiert habe, stellte ich fest, dass das Problem evt. im Suchmuster von "fscanf" liegt. Sobald ich "name" als Integer deklariere und mit %d versuche zu lesen, funktioniert es. (E-Mail adressen wurden dementsprechend angepasst).

Daher vermute ich, dass das erste "%s" gleich auf die ganze E-Mail adresse matched und die restlichen Variablen leer bleiben.

Aber eigentlich kann man doch eine E-Mail Adresse nur mit "%s@%s.%s"zerlegen, oder?
Ja, das %s matcht bereits den ganzen String. Das läßt sich auch leicht in den entsprechenden Handbüchern nachlesen :google: Ein %s liest ein "Wort" - d.h. es überliest am Anfang alle Leerzeichen (wie Tabs, Zeilenschaltungen und dergleichen), und liest dann alles außer Leerzeichen solange bis wieder ein Leerzeichen kommt.

Du könntest z.B. die Funktion strchr verwenden um in der Zeile nach dem ersten '@' zu suchen. Oder du versuchst es so:
C:
char zeile[80], name[40], server[40];

/* Zeile von Datei in Variable "zeile" einlesen */
/* ... */

if (sscanf(zeile, " %[^@]@%s", name, server) == 2) { /* Einlesen erfolgreich: */
  ...
} else { /* Einlesen hat nicht geklappt: */
  perror("zeile");
}
Beachte die erste Leerstelle im Formatstring - der bewirkt das vorher alle Leerzeichen überlesen werden.

Gruß
 
Zuletzt bearbeitet:
Hi deepthroat,
Danke dir, und mike4004 ! hab es jetzt so wie ich es benötige.
Ist vieleicht nicht die eleganteste Lösung aber für's erste funktionierts =)

C:
#include <stdio.h>
#include <stdlib.h>

int main(void) {
	FILE *fh;
	char line[80];
	char name[40], server[40];

	fh = fopen("user.txt", "r");

	while((fscanf(fh,"%s\n",&line)) != EOF ) {
		//fprintf(stdout,"-> %s\n",line);
		if (sscanf(line, " %[^@]@%s", name, server) == 2) { 
			printf("[Found] Name: %s \t Server: %s\n",name,server);
		} else { 
			perror("line");
			} 
	}
	return EXIT_SUCCESS;
}

Gruß MrMorpheus :)
 
Zurück