fscanf...
-
Hallo
Ich will eine zeile von einem File mit fscanf einlesen. Das File hat den folgenden aufbau:
Frage \t Antwort1 \t A2 \t A3 \t A4 \t A5 \t Lösung\n
Das geht noch. Doch wenn Antworten 4 und 5 optional sind, steht zwischen den Tabs nichts, und damit hab ich meine liebe müh. Ich bin mir auch nicht ganz sicher was er da dann macht, jedenfalls kommen die Zeilen durcheinander...
Alle Felder sind strings bis auf das letzte, lösung ist int. Einlesen tu ich etwa so:
fscanf (myFile, "%[^\t]\t%[....
Er soll bis tab lesen, dann den tab entsorgen. Stimmt doch, oder?
Mach ich was falsch oder geht das nicht?gruss stephan
-
Die von scanf zur Verfügung gestellten »regulären Ausdrücke« sind nicht mächtig genug, um Fallunterscheidungen beschreiben zu können. Das ist nicht unbedingt schlecht: Man will *scanf sowieso (von sscanf abgesehen) nicht benutzen, weil man damit üblicherweise (a) Bufferoverflows produziert (b) unleserlichen Code schreibt. Ein 'richtiger' Parser kann das besser.
-
Also liest man ein File wie ich es hab nicht mit fscanf ein. Was ist denn ein richtger Parser? Und was bedeutet bufferoverflow? Und wie lese ich denn nun meine Zeile richtig ein, damit ich alles da habe wo ich will?
-
Man könnte die ganze File mit fread einlesen oder mit fgetc. Trenn doch deine Antworten mit einem komma ab also ','
dann liest du so weit ein bis ein komma kommt und speicherst es in ein string dann machst du weiter und speicherst wieder in ein string. ZUm Beispiel:{ FILE *stream; char puffer[200]; int iZeichen, i; stream = fopen("C:\\test.txt", "r"); if(stream != NULL) { for(i = 0; iZeichen != ','; i++)//Bis ein ',' kommt einlesen { iZeichen = fgetc(stream); //Zeichen einlesen puffer[i] = iZeichen;//Zeichen in Puffer schreiben } puffer[i]= '\0';//den string abschliesen fclose(stream); } }
der Code liest alle Zeichen ein bis ein ',' kannst natürlich auch was anderes nehemen das sollte dir das Prinzip klar machen. Ich habe es aber nicht getestet!!!
PS: Ein Bufferoverlow ist wenn du zum Bsp. ein char buffer[5] hast und ihn einen String von 11 Zeichen zum Beispiel "Hallo du da" übergibst dann "überläufst" du den buffer über dem was er kann (5) hinaus und greifst auf Speicher zu wo du nicht zugreifen darfst.
-
Vielen Dank, es hat geklappt. Das Ding macht jetzt was ich von ihm verlange.
gute gruesse stephan
-
iZeichen = fgetc(stream); //Zeichen einlesen
puffer[i] = iZeichen;//Zeichen in Puffer schreibenwarum nicht
puffer[i]=fgetc(stream) ??
-
iZeichen = fgetc(stream); //Zeichen einlesen
puffer[i] = iZeichen;//Zeichen in Puffer schreibenwarum nicht
puffer[i]=fgetc(stream) ??Hab ich mir zuerst auch ueberlegt. Doch wenn ich weiter unten pruefen will ob der Datensatz fertig ist (\n), kann ich das einfach mit iZeichen pruefen. in puffer[i] hab ich dann das letzte eingelesene Zeichen schon geloescht.
Das ganze sieht etwa so ausvoid fileauf () { FILE *myFile; char puffer[200]; int iZeichen, i, zSpalten, datensatz = 0; myFile = fopen("testfile.txt", "r"); zSpalten = 1; do //mach bis fileende { i = 0; //index fuer puffer do //mach solang bis an ein tab, ein zeilenumbruch oder bis fileende { iZeichen = fgetc(myFile); //Einzelnes Zeichen einlesen, in int var speichern puffer[i] = iZeichen; //und dieses Zeichen in einen char buffer schreiben i++; } while (iZeichen != '\t' && iZeichen != '\n' && iZeichen != EOF); puffer[i - 1]= '\0'; //den string abschliesen switch (zSpalten) //zaheler fuer Filespalten { case 1: strcpy (eingabe[datensatz].frage, puffer); break; case 2: strcpy (eingabe[datensatz].Antwort1, puffer); break; case 3: strcpy (eingabe[datensatz].Antwort2, puffer); break; case 4: strcpy (eingabe[datensatz].Antwort3, puffer); break; case 5: strcpy (eingabe[datensatz].Antwort4, puffer); break; case 6: strcpy (eingabe[datensatz].Antwort5, puffer); break; case 7: //puffer[0] liefert ASCII Zeichen switch (puffer[0]) { case 49: eingabe[datensatz].loesung = 1; break; case 50: eingabe[datensatz].loesung = 2; break; case 51: eingabe[datensatz].loesung = 3; break; case 52: eingabe[datensatz].loesung = 4; break; case 53: eingabe[datensatz].loesung = 5; break; } break; } zSpalten++; if (iZeichen == '\n') // '\n' gleich Datensatzende { datensatz++; //naechster Datensatz zSpalten = 1; //Spaltenzaehler auf eins setzen } } while (!feof (myFile)); fclose(myFile); ausgabe (datensatz); //Funktionsaufruf }
Geht es eigentlich auch anders wenn man einer int Variablen einen Wert von einer char Variablen zuweisen will. Ich hab hier switch genommen und es aufgeteilt. Nicht sehr optimal finde ich, aber es lauft.