Hallo,
ich möchte mit ANSi C eine Datei einlesen und die Daten dann
verarbeiten. In der Datei habe ich z.B. 18 Zahlen.
WIe kann ich die Anzahl der Zahlen dieser Datei mit ANSI C
herausfinden?
Wenn ich die Datei jetzt erweitern will, dann möchte ich immer die
Anzahl der Werte in der Datei automatisch feststellen.
Wie kann man so was in C realisieren?
scanf (...), ist aber nur ne Idee.
Alternativ einfach per Hand programmieren, dürfte ja keine Problem
sein, wenn die Zahlen in einer festgelegten Formatierung eingetragen
werden.
Wenn die Datei eine Textdatei ist, kann sie mit fgets zeilenweise
gelesen werden; angenommen, daß in jeder Zeile eine Zahl drinsteht,
lässt sich so durch einfaches Zählen deren Anzahl bestimmen.
Bevor man scanf auf irgendwelche Daten loslässt, sollte man gewisse
formelle Überprüfungen mit den Daten anstellen, hier wäre es
beispielsweise die Länge der eingelesenen Zeilen. Dann wendet man
beispielsweise sscanf auf den Zeilenpuffer an.
Oder, wenn wirklich nur Zahlen darinstehen, strtod verwenden, das
liefert im Gegensatz zu atof auch noch Fehlerinformationen.
Danke für Eure Hilfe.
Also meine TextDatei sieht so aus:
1 33 55 6 8 9
3 5 8 9 33 44
Ich weiss jetzt nicht wie ich das in C realisieren kann, dass ich die
Anzahl der Zahlen von dieser TextDatei festellen kann!
Ich möchte, dass dann Anzahl=12 erscheint.
Ich möchte aber nicht die Zeilenanzahl sow die Anzahl der Werte
vorgeben. Es soll so sein, dass die Anzahl der Elemente durch ein
Programm ermittelt werden kann.
Ja da einlesen funktioniert bei mir! Ich möchte nur feststellen wie
lange der Datensatz ist.
z.B. Textdatei mit diesen Werten: 22 66 44 33 --> Anzahl=4
Das Programm sollte dann die Zahl 4 auspucken. WIe könnte man so was in
C realisieren?
Ok, in einer while loop mit fgets die Zeilen lesen. Jetzt den
eingelesenen String solange mit strtok zerlegen bis das Ergebnis == 0
ist. Bei jedem strtok das != 0 ist den Zaehler erhoehen. Fertig ist di
Laube.
Hallo Dominik,
hast Du das Problem gelöst, falls nicht sendie ich Dir ein kleinen
c-Programm welches eine Datei öffnen kann, alle Zeichen Zählt und dann
die Datei wieder schließ. Die Zahl der Zeichen und Records (Zeilen)
wird auf dem Bildschirm angezeigt. Das Programm convertier dabei noch
Zeichen aus dem ISO-Zeichensatz in den IBM-Zeichensatz, die
überflüssigen Zeilen sind leicht zu erkennen und können gelöscht
werden.
Hallo DAZ,
ich weiss nun nicht wie ich dies umsetzten kann.
Ich brauche genau so etwas wie Walter beschrieben hat:
"ein kleinen c-Programm welches eine Datei öffnen kann, alle Zeichen
Zählt und dann die Datei wieder schließ. Die Zahl der Zeichen und
Records (Zeilen)
wird auf dem Bildschirm angezeigt."
Hi,
int readVek(int* vek1,int* vek2,int anz)
{
char name[] = "Vektor.txt";
int array[100];
int zaehler=0;
FILE *datei;
datei = fopen(name, "r");
if(datei == NULL)
{
printf("Datei konnte nicht geöffnet werden!");
return 0;
}
else
{
for(int i=0; i<(anz*2); i++)
{
fscanf(datei,"%i", &array[i]);
}
}
for(int i=0; i<(anz*2); i++)
{
if(i<anz)
vek1[i]=array[i];
else
vek2[-1*(anz-i)]=array[i];
}
fclose(datei);
return 0;
}
int writeVek(int* vek, int anz)
{
char name[] = "AusgabeVektor.txt";
FILE* datei;
datei = fopen(name,"w+");
for(int i=0; i<anz; i++)
{
printf("Element%2i:%i\n",i+1,*(vek+i));
fprintf(datei,"%i ",*(vek+i));
}
return 0;
}
So das hier sind meine beiden Funktionen.
Zum einen möchte ich meine readVek Funktion so umbauen, dass ich die
max. Anzahl der Zahlen feststellen kann. So mit writeVek möchte ich
dann die Werte in eine separate Datei abspeichern.
Was muss ich da tun, wenn ich diese Funktion mehrmals aufrufe, und die
Daten hinten dran angehängt werden soll?
@The Daz
while (!feof(datei))
sowas ist praktisch immer falsch. (Auch in Deinem Fall).
feof() liefert Dir erst dann true zurueck, wenn Du versucht hast,
ueber das Dateiende hinauszulesen. D.h. feof() wird benutzt um
festzustellen warum die vorhergehende Leseoperation einen Fehler
meldete und nicht um vorherzusagen, dass die naechste Leseoperation
schiefgehen wird. C (und auch C++) schauen nicht in die Zukunft.
In C (und auch C++) liefern alle Lese-Operationen einen Return-Wert,
der eine Aussage darueber erlaubt, ob die Leseoperation gut ging
oder nicht. D.h. man baut die Schleife immer auf diesem Return-Wert
auf und bricht ab, nachdem die Leseoperation einen Fehler gemeldet
hat.
Erst danach, ausserhab der Schleife, wird getestet, warum die
Operation
schief ging: war es wegen End-Of-File (feof benutzen), dann ist alles
ok, das File wurde korrekt und vollstaendig gelesen.
So eine
while( !feof( ... ) )
Schleife fuehrt normalerweise zu der Fragestellung:
"Warum wird meine letzte Eingabezeile (letztes Eingabewort, etc)
zweimal behandelt?"
Und die Antwort ist: Weil feof() nicht in die Zukunft schaut. foef()
liefert noch true, der nachste fgets() (in Deinem Fall) geht aber
schief. Das beruecksichtigst Du aber nicht, sondern tust so als ob
alles in Ordnung waere und verarbeitest die nicht eingelesenen Daten
ganz normal. Da fgets aber in so einem Fall den Buffer nicht loescht,
stehen da noch die Daten vom fgets() von davor drinnen. Erst der
naechste feof() liefert dann true.
Ausserdem: die while( feof( ... ) ) Schleife bricht nicht ab, wenn
ein anderes Problem vorliegt (Diskette fehlerhaft, Netzwerkverbindung
zusammengebrochen, etc..).
Eine
while( fgets( ... ) )
Schleife schon.
Ack. Daran habe ich noch nie gedacht und bin gluecklicherweise noch nie
drueber gestolpert. Werde ich aber in Zukunft in meiner Arbeit
beruecksichtigen. Danke ! :)
Entschuldigung für die Verspätung, aber ich habe auch schwierigkeiten
beim ausgeben.
Denn muss ich, anzahl von Positive-, Negative- und Nullhzahlen
ausgeben.
Was meinst Du jetzt damit.
Schildere mal genauer:
* was musst Du machen
* was kannst Du davon alleine realisieren
* wobei hast Du Schwierigkeiten
Du gehst ja auch nicht zum Arzt und sagst: Doc, es tut weh. Mach mal.
Erst mal SCHÖNES UND FRÖHES NEUES JAHR!!!!!!
Wie du ja bestimmt weißt,meine Aufgabe scheint ein bisschen so :
int readVek(int* vek1,int* vek2,int anz)
{
char name[] = "Vektor.txt";
int array[100];
int zaehler=0;
FILE *datei;
datei = fopen(name, "r");
if(datei == NULL)
{
printf("Datei konnte nicht geöffnet werden!");
return 0;
}
else
{
for(int i=0; i<(anz*2); i++)
{
fscanf(datei,"%i", &array[i]);
}
}
for(int i=0; i<(anz*2); i++)
{
if(i<anz)
vek1[i]=array[i];
else
vek2[-1*(anz-i)]=array[i];
}
fclose(datei);
return 0;
}
int writeVek(int* vek, int anz)
{
char name[] = "AusgabeVektor.txt";
FILE* datei;
datei = fopen(name,"w+");
for(int i=0; i<anz; i++)
{
printf("Element%2i:%i\n",i+1,*(vek+i));
fprintf(datei,"%i ",*(vek+i));
}
return 0;
}
aus.
Eigentlich muss ich auf einer Datei "valdo.dat" ganzen Zahlen in ein
Array einlesen und anschließend formatiert mit 7 Stück pro zeile und je
2 Blanks getrennt ausgeben.Vor allem muss ich auch beim einlesen
zählen.Dann wichtig dazu ist die Benutzung von
"fopen,fscanf,fclose".
Schließlich muss ich noch void prozeduren wie "void
ausgeben(Arrayname, Anzahl-der-werte); und void signs(Arrayname,
Anzahl-der-werte,Anzahl-positiven werte,Anzahl-Negative
werte,Anzahl-Null werte)" erstellen;
Das heißt, ich muss auch die positive, negative und die Null Werte
geben.
Konntes du mir Helfen!!
> Wie du ja bestimmt weißt,meine Aufgabe scheint ein bisschen so :
Nein das weiß ich nicht.
Der Thread wurde gestartet von einem gewissen
Dominik K.
Die letzte Anfrage kam jetzt von einem
Valere JEWOH
und Du meldest Dich mit
valdo
Woher soll ich wissen, das Du 3 Pseudonyme hast?
Zum Problem.
Wo hast Du jetzt Schwierigkeiten? Ich will ja nicht Deine
Hausuebung komplett loesen. Aber ich gebe Dir Tips oder
helfe Dir aus der Patsche wenn Du mir genau sagst, bei
welcher Aufgabenstellung Du konkret welche Schwierigkeiten hast.
> Das heißt, ich muss auch die positive, negative und die Null> Werte
Das kann ja doch kein grosses Problem sein
...
if( vek[i] < 0 )
gib eine -1 aus oder was auch immer bei negativen Zahlen
else if( vek[i] > 0 )
gib eine +1 aus oder was auch immer bei positiven Zahl
else
gib eine 0 aus oder was auch immer bei 0
...
Noch'n Hinweis:
Ich wuerde die Zeile mitlerweile nicht mehr mittels fgets einlesen
und dann mit strtok zerpfluecken. Ist ein ziemlicher Aufwand
wenn man es komplett richtig macht und das Ganze schaut mir
doch sehr nach Hausuebung aus. Die meisten Lehrer lieben
einfachen Code, den sie selbst auch noch verstehen. :-)
Ich wuerde einfach in einer Schleife mittels fscanf die Zahlen
einlesen. Schau Dir mal den Rueckgabewert von fscanf an. Der
ist in diesem Fall ganz hilfreich um die Schleife zu steuern.
Tja, und dann halt einfach mitzaehlen wie oft eine Zahl gelesen
werden konnte.
Mach du dich keine Sorge, ich der einzige!!
Allerdings will ich auch erwähnt, dass ich Serverproblem habe, deswegen
kann ich nicht sofort antworten!!
Jetzt werde ich sofort probieren, aber kommt diese Ifanweisung in void
ausgeben und in void signs!!
Die zahlen sollen in ein Array datei einlesen werden, das heißt: ZB
10 -2 6 -3 7 0 5
2 3 7 0 -6 -7 40
9 3 5 0 0 -1 -2
Und dann ausgegeben werden.bzw die anzahl pro zeile,von null, von
negative zeichen und von positive zeichen.
Hmm. Wenn Du Anzahl pro Zeile brauchst, dann must
Du auch zeilenweise lesen. Da fuehrt kein Weg
dran vorbei. (*)
'The Daz' hat weiter oben ja schon mal gezeigt, wie
man das macht. Eine Zeile komplett mittels fgets
lesen und danach mit strtok in einzelne Elemente
zerlegen und jedes Element mittels sscanf in eine
tatsaechliche Zahl verwandeln.
(*) Befremdlich ist nur, dass Du erst jetzt mit
dieser Information rausrueckst. Sowas musst Du am Anfang
bereits sagen, da das die Art und Weise wie man an die
Dinge herangeht beeinflusst.
Also: jetzt mal verbindlich. Wie sieht Dein Input aus?
Wie muss der dazugehoerige Output aussehen?
Bis jetzt habe ich nur fehlermelungen und weiße nicht genau, wo ich
diese ifanweisung hinlegen soll!!
Vielleicht ist der Fehler!!!
Sag mal wo ich, die if anweisung hinlegen soll .
Das Ergebnis soll so aussehen:
erste zeile: 1 -2 0...
anzahl der Null:...
anzahl der positive zahlen:...
anzahl der negative zahlen:...
zweite zeile: 3 -6 0
anzahl der Null:...
anzahl der positive zahlen:...
anzahl der negative zahlen:...
Da findest du die unterschiedliche fehlermeldungen, ich habe
genauso,aber mit einigen veränderungen, probiert aber läuft nicht
einfach.
Probier auch, vielleicht habe ich ein paar fehlern drin!!!
"Aufgabe1.c" 100 lines, 2316 characters
"Aufgabe1.c", line 22.27: 1506-046 (S) Syntax error.
"Aufgabe1.c", line 22.30: 1506-045 (S) Undeclared identifier
speichert.
"Aufgabe1.c", line 24.18: 1506-280 (W) Function argument assignment
between type
s "char*" and "struct {...}*" is not allowed.
"Aufgabe1.c", line 24.17: 1506-098 (E) Missing argument(s).
"Aufgabe1.c", line 24.28: 1506-046 (S) Syntax error.
"Aufgabe1.c", line 26.52: 1506-046 (S) Syntax error.
"Aufgabe1.c", line 29.44: 1506-046 (S) Syntax error.
-----------------------------------------
# include<stdlib.h>
# include <stdio.h>
int readVek(int* vek1,int* vek2,int anz)
{
char name[] = "Vektor.txt";
int *array = 0;
int zaehler=0;
FILE *datei;
datei = fopen(name, "r");
if(datei == NULL)
{
printf("Datei konnte nicht ge^Èffnet werden!");
return 0;
}
else
{
/* Ermittle die Anzahl der Vektorelemente */
char zeile[256]; // speichert eine Zeile
int i = 0;
while (!fgets(datei)) // sind wir schon am Dateiende ?
{
if (fgets(zeile, sizeof(zeile), datei) != 0) // Lies die n
aechste
Zeile
{
char *temp = strtok(zeile, " "); // Zerlege zeile in
einzelne Elemente (durch Leerzeichen getrennt)
// zerlege solange bis nicht mehr uebrig ist
while (temp != 0)
{
zaehler++;
temp = strtok(0, " ");
}
}
}
fseek(datei, 0, SEEK_SET); // Dateizeiger auf den Anfang
zurueckstellen
// reserviere speicher fuer den array
array = (int*) malloc(zaehler * sizeof(int));
// lese den Dateiinhalt in den array
while (!fgets(datei)) // sind wir schon am Dateiende ?
{
if (fgets(zeile, sizeof(zeile), datei) != 0) // Lies die n
aechste Zeile
else if( vek[i] < 0 )
gib eine -1 aus oder was auch immer bei negativen Zahlen
else if( vek[i] > 0 )
gib eine +1 aus oder was auch immer bei positiven Zahl
else
gib eine 0 aus oder was auch immer bei 0
{
char *temp = strtok(zeile, " "); // Zerlege zeile in
einzelne Elemente (durch Leerzeichen getrennt)
// zerlege solange bis nicht mehr uebrig ist
while ((temp != 0) && (i < zaehler)) // zur Sicherheit
{
// jeden Teilstring umwandeln un in array ablegen
sscanf(temp,"%i", &array[i]);
i++; // index erhoehen
temp = strtok(0, " ");
}
}
}
}
for(int i=0; (i<(anz*2))&&(i < zaehler); i++)
{
if(i<anz)
vek1[i]=array[i];
else
vek2[-1*(anz-i)]=array[i];
}
if (array != 0) free(array);
fclose(datei);
return 0;
}
int writeVek(int* vek, int anz)
{
char name[] = "AusgabeVektor.txt";
FILE* datei;
datei = fopen(name,"a+"); // append
for(int i=0; i<anz; i++)
{
printf("Element%2i:%i\n",i+1,*(vek+i));
fprintf(datei,"%i ",*(vek+i));
}
return 0;
}}
Verzeih mir, wenn ich mich jetzt winde.
Es ist wirklich schwer Dir zu helfen ohne das
Programm zu schreiben.
Offensichtlich musst Du folgendes machen:
datei oeffnen
solange eine Zeile gelesen werden kann {
Anzahl Zahlen = 0
Anzahl positiver Zahlen = 0
Anzahl negativer Zahlen = 0
Anzahl Null = 0
solange strtok ein Element extrahieren kann {
Element in Zahl umwandeln
Anzahl Zahlen ++
if( Zahl > 0 )
Anzahl positiver Zahlen ++
else if( Zahl < 0 )
Anzahl negativer Zahlen ++
else
Anzahl Null ++
}
/* an dieser Stelle ist die Zeile komplett verarbeitet
und die Statistik kann ausgegeben werden */
Zeile ausgeben
Anzahl Null ausgeben
Anzahl positiver Zahlen ausgeben
Anzahl negativer Zahlen ausgeben
}
Datei schliessen
Das ist der Plan. Du solltest immer mit so einem Plan starten.
Sonst verliert man sich gerne in irgendwelchen Details :-)
Der Plan wird dann ganz einfach zu Kommentaren, wenn Du den
Code fuer jeden Schritt schreibst.
Konkreter sieht dann das Ganze so aus
/* datei oeffnen */
Input = fopen( ... );
/* solange eine Zeile gelesen werden kann { */
while( fgets( Buffer, sizeof( Buffer ), Input ) ) {
/*
Anzahl Zahlen = 0
Anzahl positiver Zahlen = 0
Anzahl negativer Zahlen = 0
Anzahl Null = 0
*/
NrNumbers = 0;
NrPosNumbers = 0;
NrNegNumbers = 0;
NrZeroNumbers = 0;
/* solange strtok ein Element extrahieren kann { */
tmp = strtok( Buffer, " \t\n" );
while( tmp ) {
/* Element in Zahl umwandeln */
sscanf( tmp, "%d", &Number );
/* Anzahl Zahlen ++ */
/* if( Zahl > 0 )
Anzahl positiver Zahlen ++
else if( Zahl < 0 )
Anzahl negativer Zahlen ++
else
Anzahl Null ++
*/
NrNumbers++;
if( Number > 0 )
NrPosNumbers++;
else if( Number < 0 )
NrNegNumbers++;
else
NrZeroNumbers++;
tmp = strtok( 0, " \t\n" );
}
/* an dieser Stelle ist die Zeile komplett verarbeitet
und die Statistik kann ausgegeben werden */
printf( "%s\n", Buffer );
printf( "anzahl der Null: %d\n", NrZeroNumbers );
printf( "anzahl der positive zahlen: %d\n", NrPosNumbers );
printf( "anzahl der negative zahlen: %d\n", NrNegNumbers );
}
/* Datei schliessen */
fclose( Input );
Fehlen nur noch die Variablendeklarationen. Und jetzt hab
ich genau das getan, was ich eigentlich nicht tun wollte.
Ich habe den Code fuer Dich geschrieben. Studier ihn wenigstens,
sodass Du von allen Dingen genau weist warum ich das so gemacht habe.
Zb. Ist strtok eine interessante Funktion. Oder: Du solltest
beantworten koennen, warum da ein
while( fgets( .... ) )
vorkommt (schau Dir den Return Wert von fgets genauer in Deiner
Doku an).
Du hast vermütlich was vergessen!!
Mein programm soll zweiteilig aussehen!
Zum einen die void prozedur ausgeben und zum anderen die void prozedru
signs.
Die void ausgeben dient zur Ausgabe der eingelesenen (100)Zahlen, dann
void signs gibt die Anzahl der negativen, null und positiven Werte des
übergebenen Arrays zurück.
Als Befehle haben wir:
-FILE *datei;
-if((datei = fopen("werte.dat","r")) == NULL), dann
fehlerbearbeitung
-einlesen der werte mit Abfrage auf Dateiende(EOF)
-returncode = fscanf(datei, "%d", &Arrayelement);
-Nach dem Einlesen der Zahlen die Datei sofort schließen
zu benutzen.
Das heißt, ist die Bearbeitung von The daz schon korrekt, aber es fehlt
die Ausgabe der negativen,positiven,null werte.
Konntest du mir das machen
> Die void ausgeben dient zur Ausgabe der eingelesenen> (100)Zahlen, dann> void signs gibt die Anzahl der negativen, null und positiven Werte> des übergebenen Arrays zurück.
Was denn nun?
Vor ein paar Stunden hast Du noch folgenden Output gefordert
> erste zeile: 1 -2 0...> anzahl der Null:...> anzahl der positive zahlen:...> anzahl der negative zahlen:...>> zweite zeile: 3 -6 0> anzahl der Null:...> anzahl der positive zahlen:...> anzahl der negative zahlen:...
Also die jeweilige Anzahlen fuer jede einzelne Eingabezeile.
Wenn Du das tatsaechlich so brauchst, dann sehe ich schwarz.
Du brauchst dann eine voll dynamische 2 dimensionale Datenstruktur.
Und ganz ehrlich: Wenn ich mir Deine Fragen so anschaue, dann
kriegst Du die mit Deinem jetzigen Koennen und Wissen nicht hin.
Aber mal angenommen, dem ist nicht so:
Du brauchst die Ausgabe nicht fuer jede einzelne Eingabezeile,
sondern nur fuer alle Zahlen an sich. Was ist daran so schwierig
sich eine Funktino zu schreiben, die quer durch das Array diese
Anzahl feststellt.
void Count( int* Numbers, int NrNumbers,
int* NrPosNumbers, int* NrNegNumbers, int* NrZeroNumbers )
{
}
ganz ehrlich: Wenn Du diese Funktion nicht alleine schreiben
kannst, dann hab ich ein schlechtes Gewissen. Jemand der sich
an Files versucht, hat Probleme mit Arrays und einer simplen
Schleife?
Sorry. Aber ich klink mich aus. Irgendetwas ist da faul. Das
was Deine Aufgabe verlangt und das was Du an Faehigkeiten zeigst
steht in einem krassen Missverhaeltnis.