Zum Inhalt springen

[c]Datei Durchsuchen/Ausgeben


Empfohlene Beiträge

Geschrieben

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

Geschrieben

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 :D

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 :)

Geschrieben

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

Geschrieben

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*

Geschrieben

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

Geschrieben

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.

Geschrieben

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? :D 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

Geschrieben

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

Geschrieben

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

Geschrieben

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 ...

Geschrieben

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

Geschrieben
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

Geschrieben
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

Geschrieben

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.

Geschrieben

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

Geschrieben

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.

Geschrieben
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.

Geschrieben

@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

Geschrieben

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.

Geschrieben

@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

Geschrieben

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

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...