Datei mit verschiedenen Datenformaten einlesen
-
Technikerin schrieb:
an SeppJ: verstehe ich nicht, ich arbeite in c++ 2008. Aber du weißt das bestimmt besser, also vielen dank
Auch wenn ein C++-Compiler es übersetzen kann, ist es dennoch lupenreines C. Im C++-forum würdest du nur eine tolle Streamlösung bekommen und eine komplette Umschreibung deines Programmes auf C++, was dir wahrscheinlich überhaupt nicht weiter hilft.
an DirkB: über fgets() bin ich heute schonmal gestolpert. Aber ich vermute, ich verstehe die Funktion nicht, muss ich nicht schon im code angeben, wie viele zeilen er auslesen soll? Habe mich auf der Seite informiert.
http://www.cplusplus.com/reference/clibrary/cstdio/fgets/Endlich mal jemand, der mitdenkt
. Mit fgets kannst du erst einmal deine Datei in einzelne Zeilen trennen. fgets liest, wie die Beschreibung klarmachen sollte, entweder eine ganze Zeile oder bis die angegebene maximale Zeichenzahl erreicht ist.
Wie kann ich suchen, ob Text in meiner Datei ist?
Du liest eine Zeile ein. Dann kannst du versuchen diese Zeile durch sscanf als Zahl interpretieren zu lassen. Gelingt dies (Rückgabewert betrachten!), dann war es wohl eine Zahl, ansonsten wohl nicht
.
und zu sscanf(): da muss ich doch auch angeben, welches Format meine Datei hat, oder?
Du musst das Format deiner Zeilen kennen, sofern sie Zahlen enthalten, ja. Weißt du überhaupt irgendetwas über die Datei? Ich hatte bisher den Eindruck, dass es so etwas wäre:
Kommentar Kommentar 1234 4565 7854 Kommentar 3434 4654 6465 Kommentar
Ist diese Annahme korrekt?
-
Technikerin schrieb:
- wie kann auf die Zeilen zugreifen, ohne das Dateiformat zu wissen
Indem du jede Dateizeile als String einliest/betrachtest und mit sscanf analysierst.
damit ich dann mit Hilfe von If anweisungen sortieren kann, ob die Daten (Text) einfach übernehmen werden sollen, oder ob ich die Daten skaliere und dann abspeichere (also die Zeilen mit den Zahlen)
Ägypten?
//Datei: Scalierung.cpp
Wieder mal erwischt. Möchtegern C++, nimmt aber doch dann lieber C.
#include <conio.h>
Schrott. Nichtstandard und somit nichtportabel.
- wie kann Dateinamen eingeben um die nicht ständig in "test" umbennen zu müssen?
char dateiname[100]; fgets(dateiname,100,stdin);
- wie kann ich den Namen der Datei so verändern, dass er Quellname_Skalierungsfaktor enthält?
char dateiname[100], *quelldatei="blafasel"; double sf=123.456; sprintf(dateiname,"%s_%lu",quelldatei,(unsigned long)sf);
-
vielen dank, aber bis ich da komplett durchgestiegen bin, dauert jetzt erstmal. programmiere ja nicht oft^^
meld mich dann morgen nochmal, ob es mit den Tipps geklappt hat
an SeppJ: deine Annahme ist korrekt, am Anfang 12 Zeilen Text, dann ~50.000
Zeilen mit Zahlen (jeweils 7 Spalten) und dann eine Zeile Text
-
Technikerin schrieb:
an SeppJ: deine Annahme ist korrekt, am Anfang 12 Zeilen Text, dann ~50.000
Zeilen mit Zahlen (jeweils 7 Spalten) und dann eine Zeile Text
Moment mal! Was ist denn dann überhaupt noch unbekannt an dem Format? Uberlies doch einfach 12 Zeilen und dann lies so lange Zahlen ein bis es schief geht.
-
Technikerin schrieb:
vielen dank, aber bis ich da komplett durchgestiegen bin, dauert jetzt erstmal. programmiere ja nicht oft^^
meld mich dann morgen nochmal, ob es mit den Tipps geklappt hat
an SeppJ: deine Annahme ist korrekt, am Anfang 12 Zeilen Text, dann ~50.000
Zeilen mit Zahlen (jeweils 7 Spalten) und dann eine Zeile Text
Ich habe immer noch nicht verstanden, wo genau das Problem liegt...
Wenn Du die 12 Kopfzeilen und die letzte Fußzeile überspringen willst, kannst Du einfach in einer simplen Schleife 12 mal fgets(...) aufrufen - dann steht der Dateizeiger in der 13. Zeile, die laut Deiner Angaben die erste Zeile mit den zu verarbeitenden Daten ist.
Ansonsten kannst Du natürlich "zur Sicherheit" Zeile für Zeile mit fgets(...) einlesen, dann den String überprüfen, der die Zeile beinhaltet, ob die Zeile das von Dir erwartete Datenformat hat (wenn nicht - continue, damit die nächste Zeile eingelesen wird).
Somit wird auch die Fußzeile "ignoriert" und nicht verarbeitet.
Anstatt fscanf zu verwenden, kannst Du also - wie bereits oben zu lesen - fgets verwenden und dann sscanf analog zu fscanf einsetzen.Den String, der den Namen der zu öffnenden Datei beinhaltet kannst Du wie von Wutz beschrieben ändern.
-
Enthält der Kopf der Datei, die du auslesen willst, immer den gleichen Text oder die gleiche Anzahl Zeichen?
MfG f.-th.
-
f.-th. schrieb:
Enthält der Kopf der Datei, die du auslesen willst, immer den gleichen Text oder die gleiche Anzahl Zeichen?
MfG f.-th.
Reicht doch, zu wissen, welches Format die Daten haben - entspricht irgendeine Zeile nicht diesem Format, ist sie zu ignorieren. Das schließt Kopfzeilen, Fußzeilen, Zwischenkommentare und nicht verwertbare bzw. invalide Datensätze mit ein...
-
int main() { FILE *quelle, *ergebnis; int x,zeilenanzahl=0; double a,b,c,d,e,f,g; char zeile[1000]; printf ("Bitte geben sie den Scalierungsfaktor ein:"); scanf("%i",&x);while( getchar()!='\n' ); quelle=fopen("test.txt","rt"); ergebnis=fopen("Scaliert.txt", "wt"); while( fgets(zeile,1000,quelle) ) if( 7==sscanf(zeile,"%lf%lf%lf%lf%lf%lf%lf", &a,&b,&c,&d,&e,&f,&g) ) ++zeilenanzahl,fprintf(ergebnis,"%f %f %f %f %f %f %f\n", a*x,b*x,c*x,d*x,e*x,f*x,g*x); fclose(quelle); fclose(ergebnis); printf ("%d Zeilen wurden in der Quelldatei und %d Zeilen wurden in der Ergebnisdatei gelesen.\n", zeilenanzahl, zeilenanzahl); return 0; }
-
vielen Dank bin nun schon viel weiter gekommen
Probleme:
1)Ich verstehe noch nicht, wie ich auf die Datei mit dem eingegebenen Dateinamen zugreifen kannchar dateiname[100]; printf("Bitte den Dateinamen eingeben:\n"); fgets (dateiname,100,stdin); if((quelle=fopen("test.txt","r"))== NULL) {printf("Datei konnte nicht geoeffnet werden!\n");}
wie verbinde ich jetzt "test" mit dem Dateinamen?
2)Jetzt denk ich, ich hab fgets verstanden. Jetzt fehlt mir nur noch eine Sache. Wie bekomme ich raus, wie viele Zeilen meine Datei hat?
(ich weiß, dass geht bestimmt ganz simpel)char text[200]; int zeilenanzahl=0; do { fgets (text,200,quelle); ++zeilenanzahl; } while (text=="lt_endoffile");
so mein Versuch (lt_endoffile) ist immer die letzte Zeile in meiner Datei. Dabei zählt er aber leider nicht, bringt aber auch keine Fehlermeldung
dankeschön...
-
Habe leider grade erst die zweite Seite entdeckt. Die Frage 2 hat sich somit natürlich erledigt
-
Ersetzte einfach "test.txt" durch dateiname.
-
Technikerin schrieb:
1)Ich verstehe noch nicht, wie ich auf die Datei mit dem eingegebenen Dateinamen zugreifen kann
if((quelle=fopen("test.txt","r"))== NULL) stattdessen -> if((quelle=fopen (dateiname, "r")) == NULL)
2)Jetzt denk ich, ich hab fgets verstanden. Jetzt fehlt mir nur noch eine Sache. Wie bekomme ich raus, wie viele Zeilen meine Datei hat?
(ich weiß, dass geht bestimmt ganz simpel)char text[200]; int zeilenanzahl=0; do { fgets (text,200,quelle); ++zeilenanzahl; } while (text=="lt_endoffile");
text ist ein char-Array (behinhaltet einen String) - text zeigt auf das erste Element dieses Arrays - und du vergleichst mit (text =="lt_endoffile") bestenfalls, ob dieses erste Element ein "l" ist...
Stringvergleiche macht man in C mit "strcmp(text, vergleich)" und erhält als Rückgabewert 0 bei Gleichheit und sonst -1 oder 1.
so mein Versuch (lt_endoffile) ist immer die letzte Zeile in meiner Datei. Dabei zählt er aber leider nicht, bringt aber auch keine Fehlermeldung
[/quote]char text[200], endoffile[] = "lt_endoffile"; int zeilenanzahl; for (zeilenanzahl = 0; fgets (text, strlen (endoffile), quelle) ; zeilenanzahl++) { if (strcmp (text, endoffile) == 0) break; }
so oder so ähnlich...
-
char dateiname[100]; printf("Bitte den Dateinamen eingeben:\n"); fgets (dateiname,100,stdin); if(strchr(dateiname,'\n'))*strchr(dateiname,'\n')=0; if( quelle=fopen(dateiname,"r") ) { /* datei erfolgreich geöffnet, hier gehört die Verarbeitung hin */ fclose(quelle); } else perror(dateiname);
Alternativ geht auch:
char dateiname[100]; printf("Bitte den Dateinamen eingeben:\n"); scanf("%99s",dateiname);while(getchar()!='\n'); if( quelle=fopen(dateiname,"r") ) { /* datei erfolgreich geöffnet, hier gehört die Verarbeitung hin */ fclose(quelle); } else perror(dateiname);
-
Ein großes Dankeschön. Ich wollt zwischendurch schon fast aufgeben. Für alle die es interessiert hier noch der Quellcode, den ich jetzt habe. Funktioniert alles.
Obwohl es bestimmt noch einfacher oder schöner aufgebaut funktionieren würde...//Datei: Scalierung.cpp #include <stdio.h> #include <conio.h> #include <string.h> int main () { int x,y; FILE *quelle, *ergebnis; int zeilenanzahl=0, zeilenanzahl2=0, zeilenanzahl3=0,taste; double a,b,c,d,e,f,g,h; char text[200]; char dateiname[100],datei[100]; //Dateiname der Quelldatei einlesen (ohne .txt) printf("Bitte den Dateinamen eingeben:\n"); fgets (datei,100,stdin); if(strchr(datei,'\n'))*strchr(datei,'\n')=0; //(entfernen des Zeilenumbruch sprintf (dateiname, "%s.txt", datei); //Hinzufügen des .txt printf ("Bitte geben sie den Skalierungsfaktor ein:\n");//Definition des Skalierungsfaktors scanf_s("%i",&x); char dateiname2[100]; //Dateiname der Ausgabedatei sprintf(dateiname2,"%s_sf%i.txt",datei,x); if((quelle=fopen(dateiname,"r"))== NULL) //Kontrolle ob, die Dateien richtig funktionieren { printf("Datei konnte nicht geoeffnet werden!\n"); } if((ergebnis=fopen(dateiname2, "wt"))==NULL) { printf("Datei konnte nicht erzeugt werden!\n"); } while( fgets(text,1000,quelle) ) //Zählen der Zeilen für spätere Verwendung ++zeilenanzahl3; zeilenanzahl3=zeilenanzahl3-1; //Korrekturschritt ergab sich fclose(quelle); //Zurücketzen des Zeigers auf den Anfang quelle=fopen(dateiname,"r"); for (int k=0;k<=zeilenanzahl3;++k) //Abschnitt der Berechnung { fgets (text,200,quelle); //Lesen der Quelle ++ zeilenanzahl; if (zeilenanzahl <13) //ersten Zeilen einfach kopieren {fprintf (ergebnis,"%s",text);} if(zeilenanzahl >12) { if(zeilenanzahl=zeilenanzahl3) //letzte Zeile kopieren fprintf (ergebnis,"%s",text); if (zeilenanzahl<zeilenanzahl3) //Zahlen einlesen, verrechnen und ausgeben { sscanf (text, "%lf%lf%lf%lf%lf%lf%lf", &a,&b,&c,&d,&e,&f,&g); a=a*x; b=b*x; c=c*x; fprintf(ergebnis,"%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf", a,b,c,d,e,f,g); } } } fclose(quelle); fclose(ergebnis); printf("Die Daten wurden unter %s gespeichert.\nDie Berechnung ist abgeschlossen, Programm mit Tastendruck beenden.",dateiname2); taste=_getch(); }