opener Geschrieben 13. Juli 2006 Teilen Geschrieben 13. Juli 2006 Guten Morgen erst einmal so früh und schon ein problem. Also ich habe gerade meine ausbildung angefangen und bin da bei wie alle Anfänger ein Handscanner in C zu programieren Nun da ich haber eigendlich keine ahnung von c habe, stehe ich nun vor einem kleinen problem. Ich habe eine .txt Datei mit Kundendaten:12345 hopf große gasse 3 00000 entenhausen 03341235609 5 0 0 0 0 23456 maier hauptstr. 12a 12000 darkcity 0223486745 1 0 0 0 0 99999 hans gartenweg 23 00000 entenhausen 03341235490 0 0 0 0 0 [/PHP] Die Daten sind alle durch ein Tab gerent, der nächste Kunde steht halt in der Zeile drunter. Nun möchte ich gerne diese Datei durchsuchen und nach einem Kunden suchen um diesen aufrufen zu können. Es sollen aber nur Nummer und Name durchsucht werden! nach dem [PHP]Kunden_Datei = fopen( "D:kunden.txt", "a" ) ; hört es bei mir allerdings auf, da ich keine ahnung habe wie ich das ganze umsetzen muss. meine struktur sieht folgenermassen aus:struct s_Kunden { char nummer[50+1]; char nachname[50+1]; char adresse[10+1]; int tele; char rabat[5+1]; char flag1; char flag2; char flag3; char flag4; }s_KundenData;[/PHP] Es wäre nett wenn mir jemand behilflich sein könnte mfg opener Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Hakawamu Geschrieben 13. Juli 2006 Teilen Geschrieben 13. Juli 2006 Nachtrag: Arrrrgh, tut mir leid. Hab gerade gesehen dass ein Datensatz ja garnicht zweizeilig, sondern einzeilig ist. Ich antworte dann später nochmal neu. lasse den alten Text jedoch hier unten stehen Hatte mich total verguckt *g* ------------------------------- Guten Morgen opener, herzlich willkommen in der IT-Branche Dein Problem ist in C recht einfach zu lösen. Es gibt die Möglichkeit des formatierten Einlesens. Die Funktion der stdio dazu heisst fscanf. Wenn du nur die Nummer und den Namen benötigst vereinfachst dies auch noch das Problem. Vorweg solltest du wissen, dass es vielleicht besser ist die Datei nur mit "r" zu öffnen, d.h. nur zum Lesen, da du sie ja nicht verändern willst. fscanf(FILE *stream, const char *format, ...); so würdest du die datei wie folgt einlesen können: fscanf(fp, "%s %s \n", s_KundenData.nummer, s_KundenData.nachname); fscanf(fp, "%c %s %s %d\n", s_KundenData.flag1, &s_KundenData.rabat, s_KundenData.adresse, &s_KundenData.tele); [/PHP] Das würde jetzt die ersten beiden Zeilen einlesen. in einer Schleife könntest du das so fortsetzen, bis zum Ende der Datei. Wenn ich dir nicht helfen konnte, dir das Abbruchkriterium oder das Drumherum fehlt, dann frag nochmal. Viel Spaß beim Coden Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
opener Geschrieben 13. Juli 2006 Autor Teilen Geschrieben 13. Juli 2006 Hi, erst mal vielen dank für die schnelle Antwort! :uli Der Datensatz hat sogar 3 Zeilen ich hänge die txt mal an. Wenn du nur die Nummer und den Namen benötigst vereinfachst dies auch noch das Problem. Naja, das wird später so ein, das man die Nummer oder den Namen ein Scannen/Tippen kann und er halt den den Kunden über diese Nummer oder Namen heraussucht und die anderen Inforamtionen wie Tele, Rabat etc... anzeigt. mfg opener Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Hakawamu Geschrieben 13. Juli 2006 Teilen Geschrieben 13. Juli 2006 hm okay, also musste doch alles einlesen. ich kümmer mich mal später drum ^^ wenn du's dann noch nicht selbst gelöst hast. Hab leider voll den Müll verzapft gerade *g* also in der Textdatei seh ich 3 Datensätze. und ich dachte erst dass 1 Datensatz aus 2 Zeilen besteht. So dass du am ende 6 Zeilen gehabt hättest. Dem war dann aber noch nicht so. Hab ich leider zu spät gesehen. Das einzige Problem, welches die einfachste Löstung leider über den Haufen wirst ist, dass die straße auch aus 2 Strings bestehen kann *brumm* Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
opener Geschrieben 13. Juli 2006 Autor Teilen Geschrieben 13. Juli 2006 Hi, Ich habe die Strucktur erst mal geändert. So kann man die Adresse natürlich viel besser aufnehmen, ich weis nicht was mir oben mit char adresse geritten hat :bimei struct s_Kunden { int nummer; char nachname[30+1]; char strasse[30+1]; char ort[25+1] int plz; int tele; char rabat[5]; char flag1[1]; char flag2[1]; char flag3[1]; char flag4[1]; }s_KundenData;[/PHP] Also wie ich dich jetzt verstanden habe muss ich die komplete Datei einlessen mit fscanf() und dann die eingescandte Nummer mit den eingelessenen Daten abgleichen? mfg opener Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Hakawamu Geschrieben 13. Juli 2006 Teilen Geschrieben 13. Juli 2006 du kannst ja nach jeden eingelesenen datensatz prüfen ob es der richtige ist. wenn nicht, gehst du zum nächsten und so weiter. wenn du den Datensatz am ende nicht gefunden hast, dann gibts es ihn nicht (oder dein programm hat einen fehler) für den anfang solltest du auf jeden fall immer den Datensatz ausgeben, nachdem du ihn eingelesen hast. und das mit dem fscanf ist so ein Problem. da du die zeilen formatiert einliest. d.h. wenn du fscanf(fp, "%d %c %f %s %s", ...) benutzt erwartet fscanf z.b. folgendes: "8273 a 9800.12 hallo plopp". d.h. es liest immer den datentyp, der da angeben ist. und auch in der reihenfolge. und die elemente sind durch leerzeichen getrennt. Das Problem ist nun, dass eine Zeile in Element mehr hat. denn die "große gasse" besteht aus 2 strings. und nicht aus einem. der weiss ja nicht dass das eigentlich 1 string sein soll. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
opener Geschrieben 13. Juli 2006 Autor Teilen Geschrieben 13. Juli 2006 Hi, da bin ich wieder du kannst ja nach jeden eingelesenen datensatz prüfen ob es der richtige ist. wenn nicht, gehst du zum nächsten und so weiter. wenn du den Datensatz am ende nicht gefunden hast, dann gibts es ihn nicht (oder dein programm hat einen fehler) für den anfang solltest du auf jeden fall immer den Datensatz ausgeben, nachdem du ihn eingelesen hast. das müste ja mit fscanf() machbar sein, den er soll ja nur die Nummer oder den Namen suchen. Da gibt es ja keine Lehrzeichen. Darf ich dich auch fragen wie man das genau macht? in ner Schleife denke ich mal und wenn der Richtige Datensatz gefunden würde springt er raus. und das mit dem fscanf ist so ein Problem. da du die zeilen formatiert einliest....Das Problem ist nun, dass eine Zeile in Element mehr hat. denn die "große gasse" besteht aus 2 strings. und nicht aus einem. der weiss ja nicht dass das eigentlich 1 string sein soll. kann man den nicht irgent wie sagen das die strings nicht mit Lehrzeichen sondern Tabs getrent sind? mfg opener Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Hakawamu Geschrieben 13. Juli 2006 Teilen Geschrieben 13. Juli 2006 also ich habs gerade probiert, mit fscanf. ich habs nit hinbekommen... der trennt es immer an den leerzeichen _und_ tabs. ich würde mich auch nie auf tabs verlassen. können ja auch leerzeichen sein. und bei einigen editoren sind sie das auch Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
opener Geschrieben 13. Juli 2006 Autor Teilen Geschrieben 13. Juli 2006 mhh ok, aber ich meine es muss doch gehen eine Adresse auslesen zu könne?! Gibt es den in C eine möglichkeit den Gesamten Datensatz...also nur die eine Zeile (Formtiert) auszugeben? Denn so wichtig ist die Adresse ja nun nicht, man muss sie halt nur lesen können. Viel wichtiger ist das man nach der Kunden Nummer oder Name suchen kann! Ich weiß jetzt alerdings nicht genau ob man auch einfach nur s_KundenDaten.Nummer, s_KundenDaten.Name aufrufen kann und die anderen ignorieren? Im nächsten schrit könnte man dann den gefundenen Datensatz wie oben geschrieben mit der Adresse ausgeben. (wenn es halt eine möglickeit dazu gibt). mfg opener Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Hakawamu Geschrieben 13. Juli 2006 Teilen Geschrieben 13. Juli 2006 beim fscanf kannst du soweit ich weiss nicht auslassen, nein müsstest alles was müll ist in eine temporäre variable lesen. ich kann aber nur sagen was ich weiss, vielleicht gibt es auch andere möglichkeiten ... Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
opener Geschrieben 13. Juli 2006 Autor Teilen Geschrieben 13. Juli 2006 Hi, man muss sich ja nicht auf die Tabs oder Lehrzeichen konzentrieren. Es ist doch sicher möglich andere trenzeichen zu verwenden?! Vieleicht ein ";" oder ein "#". 12345;hopf;große gasse 3;00000;entenhausen;03341235609;5;0;0;0;0 23456;maier;hauptstr. 12a;12000;darkcity;0223486745;1;0;0;0;0 99999;hans;gartenweg 23;00000;entenhausen;03341235490;0;0;0;0;0 [/PHP] mfg opener Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 13. Juli 2006 Teilen Geschrieben 13. Juli 2006 Du kannst mit fgets ganze Zeilen einlesen und dann den String z.B. mit strtok aufteilen. Damit kannst de beliebige Trennzeichen verwenden. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
opener Geschrieben 13. Juli 2006 Autor Teilen Geschrieben 13. Juli 2006 Du kannst mit fgets ganze Zeilen einlesen und dann den String z.B. mit strtok aufteilen. Damit kannst de beliebige Trennzeichen verwenden. danke für den tip! habe gerade das hier gefunden, char tmp[ZEILEN_LAENGE] = ""; fgets(tmp, ZEILEN_LAENGE, fp); sscanf(tmp, "%[^\t]\t%[^\t]", string1, string2);[/PHP] das macht doch das selbe nur ohne strtok oder sehe ich das falsch? mfg opener Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 13. Juli 2006 Teilen Geschrieben 13. Juli 2006 sscanf arbeitet auf einem Puffer statt auf einem Eingabestream, ansonsten hat es dieselben Möglichkeiten und Einschränkungen wie scanf. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
opener Geschrieben 13. Juli 2006 Autor Teilen Geschrieben 13. Juli 2006 sscanf arbeitet auf einem Puffer statt auf einem Eingabestream, ansonsten hat es dieselben Möglichkeiten und Einschränkungen wie scanf. ok, und jetzt noch mal für mich damit ich das auch verstehe was ist der unterschied zwischen nem Puffer und einem Eingabestream? opener Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 13. Juli 2006 Teilen Geschrieben 13. Juli 2006 Ein Puffer ist einfach ein Bereich im Arbeitsspeicher. In deinem Beispiel das char-Array tmp. Ein Eingabestream ist etwas, aus dem du mit scanf oder fgets einlesen kannst, z.B. STDIN oder eine Datei, die du zum Lesen geöffnet hast. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Hakawamu Geschrieben 13. Juli 2006 Teilen Geschrieben 13. Juli 2006 fscanf liest aus einer datei. und sscanf aus einem string (der puffer) ansonsten verhalten sich die funktionen komplett identisch Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Hakawamu Geschrieben 13. Juli 2006 Teilen Geschrieben 13. Juli 2006 ich dachte eigentlich dass das format so bleiben muss ^^ wenn du alles mit Simikoli trenns, dann sollte das doch gar kein Problem sein =) Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
opener Geschrieben 13. Juli 2006 Autor Teilen Geschrieben 13. Juli 2006 Hi, danke euch beiden für die Erklärung ich dachte eigentlich dass das format so bleiben muss ^^ wenn du alles mit Simikoli trenns, dann sollte das doch gar kein Problem sein =) Das hätte ich vieleicht von anfang an sagen sollen das das Format egal ist:cool: Naja, ich werde das ganze dann Morgen erst mal testen und ausprobieren, mal schauen was draus wird. mfg opener Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Hakawamu Geschrieben 13. Juli 2006 Teilen Geschrieben 13. Juli 2006 das hättest du tun sollen *g* hier übrigens noch eine kleine information: NAME strtok, strtok_r - extract tokens from strings SYNOPSIS #include <string.h> char *strtok(char *s, const char *delim); char *strtok_r(char *s, const char *delim, char **ptrptr); DESCRIPTION A `token' is a nonempty string of characters not occurring in the string delim, followed by \0 or by a character occurring in delim. The strtok() function can be used to parse the string s into tokens. The first call to strtok() should have s as its first argument. Subse‐ quent calls should have the first argument set to NULL. Each call returns a pointer to the next token, or NULL when no more tokens are found. If a token ends with a delimiter, this delimiting character is over‐ written with a \0 and a pointer to the next character is saved for the next call to strtok(). The delimiter string delim may be different for each call. The strtok_r() function is a reentrant version of the strtok() func‐ tion, which instead of using its own static buffer, requires a pointer to a user allocated char*. This pointer, the ptrptr parameter, must be the same while parsing the same string. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Bubble Geschrieben 13. Juli 2006 Teilen Geschrieben 13. Juli 2006 Also ich habe gerade meine ausbildung angefangen und bin da bei wie alle Anfänger ein Handscanner in C zu programieren Ich habe aus Interesse drei Fragen: Hast Du keinen Unterricht in C bekommen, bei dem man Dir die für die Übungsaufgabe benötigten Funktionen erklärt hat? Hat man Dir eine Herangehensweise zur Lösung derartiger Aufgabenstallungen erklärt? Gibt es niemenden, den Du vor Ort ansprechen kannst und der Dir die benötigte Hilfestellung gibt? Die Funktion strtok sollte man nur verwenden, wenn man mögliche Seiteneffekte und Pufferüberläufe ausschließen kann. Da Du ein Trennzeichen verwendest und das verwendete Dateiformat recht einfach ist, kannst Du Dir auch relativ leicht einen eigenen Parser bauen. Du musst dabei immer die Daten bis zum nächten Tennzeichen zeichenweise einlesen und verarbeiten. Sobald Du ein Zeilenende erkennst, beginnt ein neuer Datensatz. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
opener Geschrieben 14. Juli 2006 Autor Teilen Geschrieben 14. Juli 2006 @Hakawamu Danke für die beschreibung! Ich habe aus Interesse drei Fragen: Hast Du keinen Unterricht in C bekommen, bei dem man Dir die für die Übungsaufgabe benötigten Funktionen erklärt hat? Hat man Dir eine Herangehensweise zur Lösung derartiger Aufgabenstallungen erklärt? Gibt es niemenden, den Du vor Ort ansprechen kannst und der Dir die benötigte Hilfestellung gibt? Nein habe ich nicht, da die schule erst im September los geht. Was man mir erklärt hat ist wie das program aussehen soll/was es können muss etc... Bei uns in der Firma kann keiner C, mein Chef ein bischien, der ist aber in Urlaub. Sobald Du ein Zeilenende erkennst, beginnt ein neuer Datensatz. muss ich um ein Zeilenende zu erkennen die Zeilemit einem anderem "Trenzeichen" beenden? Also als Trenzeichen wüde ich ";" nehmen und beim Zeilenende "#". mfg opener Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Hakawamu Geschrieben 14. Juli 2006 Teilen Geschrieben 14. Juli 2006 also ein zeilenende erkennst du daran, dass das letzte zeichen ein '\n' ist. du hast die möglichkeit in C eine datei zeichenweise einzulesen, mit der funktion fgetc(FILE *fp). diese funktion gibt dir immer das nächste zeichen. wenn du am ende einer zeile angekommen bist, gibt sie also '\n' zurück, bzw. 10, da das der dezimale ascii-wert von '\n' ist. du kannst also in einer schleife die datei wie folgt einlesen: fp = fopen("meinedatei.txt", "r"); char c; while(c != EOF) { c = fgetc(fp); if(c == ';') printf("Hier beginnt, bzw. endet (je nachdem wie du's siehst) eine spalte\n"); if(c == '\n') printf("Hier ist die Zeile zu ende und mit dem naechsten Zeichen beginnt die naechste Zeile\n"); } [/PHP] während du vom zeilenanfang bis zum nächsten semikolon "läufst" kannst die zeichen in einem string ablegen. z.b. so: [PHP] char mein_string[128]; int i=0; rewind(fp); // setzt den filepointer (fp) wieder auf den anfang der datei while(c != EOF) { c = fgetc(fp); if(c == ';') { printf("Hier endet die spalte\n"); mein_string[i] = '\0'; //dein string sollte immer mit dem zeichen '\0' abgeschlossen werden break; // du verlässt die while-Schleife } else { mein_string[i] = c; i++; } } so hast du vom anfang der datei, vom zeilenanfang bis zum ersten semilonon die zeichen in mein_string abgelegt. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
opener Geschrieben 14. Juli 2006 Autor Teilen Geschrieben 14. Juli 2006 @Hakawamu, 1000 danke das hat funktioniert! habe es nun ich den code mit eingebaut: void beleg() { char data[30]; short error_detected; short quit; char mein_string[128]; char c; int i = 0; FILE *ptr_Datei; ptr_Datei = fopen( "kunden.txt", "r" ); printf("hier"); scannen(data); /* BiosClrScr(NORMAL); BiosPutStrMove(0, 2, 13, "Kunde Weahlen", NORMAL); BiosPutStrMove(2, 0, 11, "Kunden Nr.:", NORMAL); BiosPutStrMove(4, 0, 12, "Kunden Name:", NORMAL); GetData(KEYS_ONLY, 2, 10, 12, data); scannen(KEYS_AND_LABELS, 2, 10, 12, data); GetData(KEYS_ONLY, 4, 10, 12, data); */ while(c != EOF) { c = fgetc(ptr_Datei); if(c == ';') // printf("Hier beginnt, bzw. endet (je nachdem wie man's siehst) eine spalte\n"); if(c == '\n') printf("Hier ist die Zeile zu ende und mit dem naechsten Zeichen beginnt die naechste Zeile\n"); } rewind(ptr_Datei); // setzt den filepointer (ptr_Datei) wieder auf den anfang der datei while(c != EOF) { c = fgetc(ptr_Datei); if(c == ';') { // printf("Hier endet die spalte\n"); mein_string[i] = '\0'; //ein string sollte immer mit dem zeichen '\0' abgeschlossen werden printf(mein_string); break; //verlässt die while-Schleife } else { mein_string[i] = c; i++; } } [/PHP] Was genau macht macht den char c? Es werden jetzt allso alle Zeilen eingelesen. Nun ist das Ziel schon um einiges näher! Wie kann ich den jetzt in dem String die Nummer/Name die/der eingeben wird Suchen? und dann den richtigen Datensatz mit allen Infos ausgeben? mfg opener Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
opener Geschrieben 14. Juli 2006 Autor Teilen Geschrieben 14. Juli 2006 Ich bin bei meiner suche auf diese Funktion gestoßen: strcmp() mit der man Strings Vergleichen kann, bin mir aber nicht sicher ob sich das damit umsätzen läst? Sorry für den doppel post aber hier gibt es keine Edit Funktion. opener Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.