fscanf auslese Problem
-
Hallo zusammen
Ich hab ein Problem mit dem einlesen aus einer .txt Datei. Ich weis auch schon wo die Fehler liegen müssten kenn mich wohl aber zu wenig aus.
Jetzt aber mal zu meinem Programm.
Ich erstelle eine Datei in einer Funktion mit dem Befehl fprintf. Den ich dazu mehrmals verwende.
Danach mache ich eine Statusabfrage an den Benutzer ob er die Datei angepasst hat. Dies mache ich mit einem scanf und noch einem um den Tastaturpuffer zu leeren.
Jetzt möchte ich die Datei auslesen.
Das mache ich mit diesem fscanf und mit dem fangen die Probleme an.
fscanf(fptest, "%[0-9.]", strline);
ich möchte zahlen aus der Datei auslesen sowie punkte. In der Formulierung des fscanf vermute ich schon meinen ersten Fehler da ich mich mit dem Befehl nicht gut auskenne.Das eingelesene (strline) gebe ich im Fenster sofort aus damit ich fscanf kontrollieren kann. Der Inhalt von strline passt aber überhaupt nicht! ->
- fscanf gibt mir nicht nur zahlen und punkte aus
- er übergeht Zeilenumbrüche und gibt diese auch aus
- er gibt die letzten Zeichen der Datei aus (außer der letzten Zeile) egal was für welche und je nach dem wie groß strline ist -!NICHT proportional!- mehr oder weniger aber immer vom Schluss der Datei
- am ende von dem ausgegebenem string sind noch komische Zeichen die nicht in der Datei sind(nirgends) z.b das Zeichen „drei-viertel“ und „Pfeil nach oben“.
- wenn ich eine andere Datei -> „test“ scanne anstatt der am Anfang mit fprintf erstellten bringt er mir trotzdem den text wie im oberen punkt beschrieben aus der anderen Datei!? (auch anderer Filepointer)
- wenn ich die Statusabfrage weglasse werden wie oben beschrieben die letzten Zeichen ausgegeben bloß mit der letzten Zeile und anderen Zeichen ganz am Schluss die nicht in der Datei -> “test“ stehen (eigentlich nur mit fprintf in eine andere geschrieben wurden)
- wenn ich jetzt die Erstellung der Datei weglasse (diese ist aber von den vorherigen Starts des Programms noch vorhanden. auch meine „test“ Datei die eigentlich angesprochen wird) wird macht fscanf nichts mehr der string den er beschreibt ist komplett leer!Ich hoffe ihr könnt mir irgendwie weiterhelfen!
-
Ich glaube für diesen Fall wäre es besser für eine Hilfestellung neben 20 Zeilen Prosa auch 2 Zeilen Code nebst Dateiinhalt mit anzugeben und sich zunächst auf einen konkreten Fehlerfall zu beschränken.
-
Ok mach ich.
Mit der Funktion erstelle ich meine Datei die der Benutzer abändern soll sprich sein zu lösendes Sudoku eintragen soll.
void createFile(FILE *fpSE, char *SudokuEntry) { fpSE = fopen(SudokuEntry, "w"); fprintf(fpSE, "\t- Sudoku knacker v1.0 -\n"); fprintf(fpSE, "\t ungeloestes Sudoku\n\n\n"); fprintf(fpSE, "-------------------------\n"); fprintf(fpSE, "\t123 456 789\n\n"); fprintf(fpSE, "1.\t590 030 061\n"); fprintf(fpSE, "2.\t700 000 002\n"); fprintf(fpSE, "3.\t000 126 000\n"); fprintf(fpSE, "4.\t009 387 600\n"); fprintf(fpSE, "5.\t601 204 508\n"); fprintf(fpSE, "6.\t008 615 900\n"); fprintf(fpSE, "7.\t000 873 000\n"); fprintf(fpSE, "8.\t800 000 007\n"); fprintf(fpSE, "9.\t920 060 035\n"); fprintf(fpSE, "-------------------------\n\n"); fprintf(fpSE, "!Wichtig!\n\n"); fprintf(fpSE, "Achten Sie darauf das innerhalb der gestrichelten Linien,\n"); fprintf(fpSE, "die Formatierung gleich bleibt und sie nur Ihre Zahlen ersetzen!\n\n"); fprintf(fpSE, "Leerstehende Felder werden durch eine Null dargestellt!\n\n"); fprintf(fpSE, "by -BP42-"); fclose(fpSE); }
Das ist die Funktion für die Statusabfrage
void statusRequest(char *SudokuEntry) { char temp=0, muell=0; int ok=0; printf("\nDie Datei wurde erstellt und nennt sich:\n\t%s\n", SudokuEntry); printf("\nWenn Sie Ihr Sudoku erfolgreich eingegeben haben geben Sie J ein: "); do { scanf("%c", &temp); scanf("%c", &muell); if(temp == 'j' || temp == 'J') { ok++; printf("\n"); } else { printf("\nDie Eingabe war Falsch. Wiederholen Sie bitte Ihre Eingabe: "); } }while(ok == 0); }
Mit dieser vorläufigen Funktion lese ich ursprünglich die gerade erstellte Datei aus habe dies aber momentan wie gesagt auf die “test” Datei abgeändert.
void readFile(FILE *fpSE, char *SudokuEntry) { char test[] = "-test.txt"; FILE *fptest; int iner; char strline[110], temp; fptest = fopen(test, "r"); fscanf(fptest, "%[0-9.]", strline); //fscanf(fpSE, "\n", temp); printf("\n---%s---\n", strline); fclose(fptest); }
In der „test“ Datei befindet sich nur das Sudoku aus der erstellten datei. ->
-------------------------
123 456 7891. 590 030 061
2. 700 000 002
3. 000 126 000
4. 009 387 600
5. 601 204 508
6. 008 615 900
7. 000 873 000
8. 800 000 007
9. 920 060 035
-------------------------Ausgeben tut er jetzt
„---dargestellt!
***---“
Anstatt der drei *e gibt er 3 komische Symbole aus die ich nicht kenne.Sas steht in dieser Datei aber nicht drin!?
-
Hast du auch daran gedacht, daß die eingelesene Datei auch die Kopf- und Fußzeilen enthalten sind, die du in Zeile 5..7 und 18..23 der createFile()-Funktion reingeschrieben hast? Die sind nicht kompatibel zu deinem Format-String, also liest du auch nicht ein - und siehst anschließend den Datenmül, den die letzte aufgerufene Funktion dort liegengelassen hat, wo nun strline liegt.
PS: Ist es eigentlich Absicht, daß du die Datei "-test.txt" genannt hast?
-
void createFile(FILE *fpSE, char *SudokuEntry) { fpSE = fopen(SudokuEntry, "w"); /* ... */ fclose(fpSE); }
Wieso übergibst du fpSE als Parameter? Es macht absolut keinen Sinn.
-
Die Datei habe ich mit Absicht mit Bindestrich davor benannt.
Oh man klar. Ich Initialisiere jetzt strline mit Null, das war dumm von mir.
Das stimmt den Filepointer könnte ich neu machen, wurde auch geändert.
Vielen dank für die schnelle Hilfe!!!
Ich hatte mir das ursprünglich so überlegt das mir der fscanf die Zeile durchsucht auf Zahlen und Punkte dann speichere ich wenn er was gefunden hat ab. Danach sucht der 2te fscanf den Zeilenumbruch heraus damit ich mit dem wieder nächsten fscanf die nächste Zeile auslesen kann.
void readFile(char *SudokuEntry) { char test[] = "-test.txt"; FILE *fptest; int iner; char strline[110]={0}, temp; fptest = fopen(test, "r"); fscanf(fptest, "%[0-9.]", strline); fscanf(fptest, "\n", temp); printf("\n---%s---\n", strline); printf("\n===%c===\n",temp); fscanf(fptest, "%[0-9.]", strline); fscanf(fptest, "\n", temp); printf("\n---%s---\n", strline); printf("\n===%c===\n",temp); fclose(fptest); }
Wenn ich das so Löse gibt er mir aber das aus:
"------
===2===
------
===2==="Das sieht so aus als ob das mit dem Zeilenumbruch herauslesen nicht funktioniert. Wie kann ich den das richtig lösen?
-
fscanf() schreibt ja auch nur dann etwas in die weiteren Parameter, wenn du eine Format-Kennung %.. in deinem Formatstring hast (für dich wäre wohl "%c" das richtige Format). Außerdem solltest du dort nicht den Wert von temp übergeben, sondern seine Adresse - sonst bekommst du einen SegFault, wenn du den Formatstring korrigierst.
PS: Und den Hauptpunkt aus meinem letzten Beitrag hast du auch nicht berücksichtigt: Wenn deine Datei tatsächlich in den Format is, das createFile() erzeug, dann kann das erste fscanf nichts verwertbares finden.
-
Wenn der doch aber in der Zeile wo er dann liest nichts findet ist der Filepointer dann nicht am Ende der Zeile? Oder nur wenn er irgendwas gefunden hat.
Ich hab mir halt gedacht dass es sogar besser ist wenn das Sudoku in der Mitte der Datei steht da ich dann sowieso erst die relevanten Daten suchen muss. Damit der Benutzer "versehentlich" Zeilen vor dem Sudoku dazu schreiben kann und mein Programm trotzdem später das Sudoku findet.
Ok das mit dem fehlendem % hab ich verstanden. Der Fehler mit dem fehlenden & habe ich auch korrigiert.
Die Lösung Funktioniert auch nicht da bringt er mir auch nur ne 2. Das sollte so aber doch möglich sein!?
fscanf(fptest, "%[\n]", &temp);
Und bei der Lösung liest er mir andauernd nur einen Bindestrich aus u kommt nicht zum Zeilenumbruch.
do { fscanf(fptest, "%c", &temp); printf("\n___%c___\n",temp); }while(temp != '10');
Oder geh ich da ganz falsch ran und ich sollte mein Problem mit irgendwie anders angehen!?
-
bleipumpe schrieb:
Wenn der doch aber in der Zeile wo er dann liest nichts findet ist der Filepointer dann nicht am Ende der Zeile? Oder nur wenn er irgendwas gefunden hat.
scanf bleibt bei dem Zeichen stehen, das nicht zur Eingabe passt.
Wenn du nur Ziffer und Punkt lesen willst, wird bis zu dem Zeichen gelesen das nicht mehr Ziffer oder Punkt ist.scanf sucht nicht.
-
Sry wegen der späten Antwort!!
Aah ok dh ich werde die ganze Zeile auslesen müssen und danach das eingelesene komplett auswerten müssen.
ich habe das jetzt mal so gelöst und ausprobiert.
for(iner=0;iner<13;iner++) { fscanf(fptest, "%[]\[a-zA-Z0-9!-/:-@^-'{-~\t ]", strline); fscanf(fptest, "%[\n]", &temp); //<-- printf("\n---|%s|---\n", &strline); printf("\n===%c===\n", temp); }
Da liest er mit dem ersten fscanf die erste Zeile ein und gibt diese auch aus ("-----------") mit dem zweiten gibt er auch einen Zeilenumbruch aus. Aber wenn sich das ganze Wiederholt gibt der erste fscanf immer nur die erste Zeile aus, der zweite fscanf aber trotzdem immer wieder einen Zeilenumbruch. Woran liegt das?
Wenn ich denn zweiten fscanf so abändere:fscanf(fptest, "\n", &temp);
Gibt mir dieser fscanf zwar mittels temp keinen Zeilenumbruch mehr aus (sondern ein Leerzeichen). Aber der erste fscanf gibt jeweils die nächste Zeile aus. Dh der zweite fscanf liest zwar irgendwie den Zeilenumbruch ein aber speichert in nicht in der temp ab.
Mir ist zwar klar warum beim ersten Beispiel der Zeilenumbruch richtig in temp transferiert wird und im zweiten nicht, aber wieso rutscht der filepointer nur beim 2ten Beispiel weiter u nicht beim ersten?
Gibt es nicht auch eine einfachere Methode mittels fscanf eine komplette Zeile mit allen Zeichen auszulesen. Oder so viel einzulesen bis der Speicher des angegebenen Strings voll ist?
-
Lerne mal C Programmieren! Und schau Dir mal die Docus zu den STD Funktionen an. Und informiere Dich wie sie funktionieren, was sie machen und was nicht!
Dann wird sich Deine Frage von selbst lösen!
-
Es gibt zum einlesen nicht nur fscanf. Das f hinten steht da für formatiert.
Das vordere f steht für File.Da du aber die ganze 1. Zeile einlesen willst nimmst du eine andere Funktion. (steht auch in der stdio.h)
Es gibt auch sscanf. Mit s vorne für String. Damit kannst du aus einem String die Daten einlesen.
Daher erst komplette Zeile einlesen und dann auswerten.
-
Meinung! schrieb:
Lerne mal C Programmieren! Und schau Dir mal die Docus zu den STD Funktionen an. Und informiere Dich wie sie funktionieren, was sie machen und was nicht!
Dann wird sich Deine Frage von selbst lösen!Wow!
Das ist mir eine Nominierung zum "Schund des Monats" wert! Herzlichen Glückwunsch!
-
Pretty schrieb:
Meinung! schrieb:
Lerne mal C Programmieren! Und schau Dir mal die Docus zu den STD Funktionen an. Und informiere Dich wie sie funktionieren, was sie machen und was nicht!
Dann wird sich Deine Frage von selbst lösen!Wow!
Das ist mir eine Nominierung zum "Schund des Monats" wert! Herzlichen Glückwunsch!
Warum? Nichs als die Wahrheit!
-
Meinung2 schrieb:
Warum? Nichs als die Wahrheit!
Auch die vermeintliche Wahrheit (die sich nach näherer Betrachtung mitunter als simple Meinung eines Individuums und nicht als generelles Faktum herausstellen könnte) ist manchmal bei sich selbst besser aufgehoben.
Nichtsdestotrotz ist dem Fragensteller wahrscheinlich soweit klar, dass er sich in einem Lernprozess befindet (wie fast alle hier) und gerade deshalb wendet er sich (sinnvollerweise) an (zumeist) fachkundige (und größtenteils freundliche) Artgenossen, um den ein oder anderen Tipp zu erhaschen.
Wenn Du schon zum RTFM'en ermahnst, poste wenigstens einen adäquaten Link dazu!
-
Pretty schrieb:
Wenn Du schon zum RTFM'en ermahnst, poste wenigstens einen adäquaten Link dazu!
Bevor das hier ausartet, hier mal ein Link:
-
Jab bin grad beim C lernen und zwar mit Hilfe dieser Seite.
http://www.c-howto.de/tutorial-dateiverarbeitung-formatiertes-lesen-schreiben.html
Und dort wird der fscanf nicht so ausführlich erklärt.Was ich zum Zeilenweisen auslesen mit fscanf in Google gefunden hab hatte mir nicht sehr viel weitergeholfen aber jetzt weis ich auch wieso ich kaum was gefunden habe…
Vielen Dank für die Hilfe, von euch allen! Auch für den Link, werde mich mal an diese Funktion setzen. Und jetzt habe ich auch denn hier gefunden und werde da mal das "c von a bis z" ausprobieren, wenn das empfohlen wird.
http://www.c-plusplus.net/forum/134691
-
bleipumpe schrieb:
Und jetzt habe ich auch denn hier gefunden und werde da mal das "c von a bis z" ausprobieren, wenn das empfohlen wird.
Nein! Bücher und sonstiger Pfusch vom Autor JW wird hier ausdrücklich NICHT empfohlen aufgrund nachgewiesener Inkompetenz und schlichtweg Vermittlung von falschem Wissen.
-
Ääähm das steht direkt als erstes unter „Linkliste für Neulinge“
http://www.c-plusplus.net/forum/f10
und da steht "nur":"Edit by TactX: Das Buch "C von A bis Z" ist hier schon öfters wegen diverser Fehler aufgefallen. Dies sollte man im Hinterkopf haben wenn man das Buch liest und entsprechend kritisch hinterfragen (gilt natürlich für jede Veröffentlichung)."
Was sich aber längst nicht so eindeutig wie deine Aussage anhört.
Das sollte wohl dann eher gelöscht werden, anstatt vorsichtig daraufhin gewiesen.Gibt’s da nicht ein Buch wo ziemlich gut ist einfach aber vor allem ausführlich!? unter dem "Linkliste für Neulinge" sind nur immer wieder Bücher und links eingeworfen und teils sofort wieder kritisiert oder Dead-links etz.
Besonders hilfreich finde ich diesen "thread" nicht!
-
Tue was du nicht lassen kannst.
Ich gebe dir aber auf deinen Erfahrungstrip mit, dass nicht immer die Top-Google-Treffer die besten sind.
Hier im Forum gibt es genügend Beiträge zum Suchen nach brauchbaren Links und meist auch eine Bewertung dazu.
-
Das hast du wohl falsch verstanden ich habe nicht dich gemeint sondern ausschließlich diesen „Linkliste für Neulinge“ Thread.
Hat mir jemand ein Vorschlag für ein Tutorial o.ä.