mit Feld aus txt datei weiterrechnen in C

studine

Mitglied
Hallo zusammen,

nachdem ich das ganze Internet durchforstet habe ohne eine Lösung zu finden, wende ich mich jetzt hilfesuchend an euch. Ich habe eine Textdatei mit 100 Werten untereinander:

5.46
4.98
3.78
2.99
3.59
......usw

Diese Datei muss ich in C einlesen und zwar in einer Unterfunktion, die Zahlen in einem Feld abspeichern und dieses Feld dann wieder an main zurückschicken um dann mit den Werten weiterzurechnen (z.B. Mittelwert ermitteln). Ich habe bist jetzt die Datei einlesen lassen und wollte sie gerne an den Monitor ausgeben um zu überprüfen, ob die werte richtig eingelesen wurden. aber da scheitere ich schon, denn mir wird immer nur entweder 0 oder 100 ausgegeben. Könnt ihr mir sagen, was ich falsch mache. Über ein bisschen Hilfe würd ich mich sehr freuen!

Hier das was ich bisher habe:
C++:
#include <stdio.h>

float Einlesen (float *);

int main()

{
    float weiten[100];
    int werte;
    werte=Einlesen(weiten);
    printf("weiten:\n%i",weiten[100]);

    return 0;
}

float Einlesen (float *weiten)
{
    FILE *datei;
    int i=0;
    datei=fopen("sprungweiten.txt","rt");
    if (datei==NULL)
    {
        printf ("Datei nicht gefunden");
    }
    for (i=0;i<100;i++)
    {
        fscanf(datei,"%f", &weiten[i]);
    }
    return i;
}
DANKE schon mal ****** Liebe Grüße
 
Zuletzt bearbeitet von einem Moderator:
Hi und Willkommen bei tutorials.de,

a) Warum gibt die Funktion float zurück (was sollte das sein)?
Außerdem sind es trotz "float" immer int, die zurzeit gar keinen Sinn machen.
Kann ruhig "void" werden, und alles bezüglich return usw. weg.

b) Du hast nirgends ein fclose.

c) Falls du mit "weiten[100]" eim printf die letzte eingegebene Zahl auslesen willst:
Das wäre weiten[99]

d) Das selbe printf: %i gibt keine Kommazahlen aus. %f wie beim fscanf unten ist richtig.

e) Bitte Codetags verwenden.
 
Danke für die schnelle Antwort.
Also ich bin absolute C Anfängerin und tu mich total schwer damit. Ich versuche mal die Fragen zu beantworten:

a: Die Funktion soll die Werte die in der Textdatei stehen an die main funktion zurückgeben um dann da mit den werten rechnen zu können. Float habe ich benutzt weil es Kommazahlen sind. Ich hab auch probiert float und int alles mal zu tauschen, aber ohne Erfolg. Void kann ich doch nicht benutzen, wenn ich die werte zurückgeben möchte oder?

warum kann ich return weg machen?

b: ist es zwingend notwendig die datei wieder zu schließen? Dann in main schließen?

c:ich würde gerne alle 100 Zahlen auslesen und an den Monitor ausgeben. Ich habe gerade mal weiten[99] eingegeben und das hat funktioniert. juhu :) schon mal ein kleiner Erfolg.

d: habe ich geändert. danke
e: tut mir Leid für die vllt blöde Frage, aber ich weiß nicht was Codetags sind.
 
a) Die Werte werden ja schon über den Parameter zurückgegeben. Deine Funktion wird immer 100 zurückgeben, daher ist diese Rückgabe recht sinnfrei. Wenn du die Funktion als void definierst, brauchst du kein return, da void (dt. "Leere") nichts ist.

b) Zwingend nötig: Nein. Das OS wird dir die Datei beim Beenden des Programms schliessen. Gewöhne dir aber schon jetzt an, Dateien immer zu schliessen. Ansonsten führt das (gerade in grösseren Projekten) zu ärgerlichen Fehlern. Das fclose() würde ich nicht in die main, sondern in "Einlesen" packen, da du die Datei dort auch öffnest.

c) Ausgeben:
C:
for(int i = 0;i<100;i++) printf("%f\n",weiten[i]);
e) schreibe im Forum vor dem Code ein [c ] (ohne Leerzeichen) und am Ende ein [/c ] (ohne Leerzeichen).

Gruss
cwriter
 
Danke cwriter! klappt jetzt endlich und ich kann weiterrechnen. SUPER!

Ich frage mich warum wir das so gelernt haben, das mit dem return i, wenn es doch nicht notwendig ist...aber ich habe es jetzt weggelassen und es geht doch :)
 
Zu a:
Im main machst du die Variable weiten mit 100 floats.
Beim Aufruf der Funktion üergibst du dieses Array der Funktion.
Weil der Parameter hier:
C++:
float Einlesen (float *weiten)
auch weiten heißt kannst auf das weiten vom main auch in der Funktion mit "weiten" zugreifen.

In der Funktion machst du unter anderem ein int i zum Zählen von 0 bis 100, ok.
Dann werden 100 floats aus der Datei hinein in die 100 floats von weiten eingelesen
und i dabei immer mitgezählt.
Also hier
C++:
for (i=0;i<100;i++)
{
    fscanf(datei,"%f", &weiten[i]);
}
Am Ende von dem gezeigten Codeteil sind alle 100 floats in weiten hinen gefüllt
und i steht auf 100. Wenn es jetzt wieder in main weitergehen würde hätte man
auch im weiten dort die 100 float-Werte dirn (weil das weiten hier und dort ja die selben Variablen sind. Das weiten hier ist ja nur das vom main als Parameter übergeben).

Was du aber machst: Das i, das nur zum Durchzählen gut war und zurzeit 100 ist
gibst du als Returnwert zu main zurück (und noch dazu als Kommazahl,
obwohl int reichen würde). Das ist das "Problem".
Hier hast du dann ein 101. float, das mit weiten gar nichts zu tun hat
(und sinnlos ist, weil man sowieso weiß, dass es immer 100 sein wird bei diesem Code).
Im main füllst du das 100 dann in eine Variable werte ab,
die nie wieder gebraucht wird. Wozu?

Mach aus dem:
C++:
float Einlesen (float *weiten)
das:
C++:
void Einlesen (float *weiten)
Entferne die Zeile mit return unten und entfern auch die werte-Sache in main.

Zu b:
Ja, zu jedem fopen (das gut gegangen ist) gehört zwingend auch ein fclose.
Da merk ich grad noch was:
Beim fopen prüfst du danach, ob die Datei geöffnet werden könnte
und gibst. ggf. eine Fehlermeldung aus.
Aber auch, wenn ein Fehler war, machst du die fscanf danach trotzdem.
Nicht gut. if-else...also nur wenn kein Fehler dann einlesen.
Und nach dem Einlesen (auch nur wenn kein Fehler war) dann das fclose.

Das ist dann übrigens eine sinnvollere Verwendung für den Returnwert
(statt void, wie oben vorgeschlagen).
Du könntest mit einem int 1 oder 0 zurückgeben, ob die Funktion was einlesen konnte oder nicht,
damit man im main weiß, ob man jetzt die Weiten aus der Datei im Array hat oder nicht.

Zu c:
Beim Anlegen eines Arrays steht die Anzahl der gewünschten Variablen in den eckigen Klammern.
Beim Verwenden der einzelnen Werte steht die Nummer drin,
die aber bei 0 beginnt.
Wenn du 4 floats in weiten haben willst machst du am Anfang ein
"float weiten[4];" und kannst die floats dann mit weiten[0], weiten[1], weiten[2]
und weiten[3] verwenden. Genau 4 Stück. weiten[4] ist nicht mehr vorhanden,
und die Verwendung davon macht schwer findbare Fehler.
Also, für ein weiten[100] gibts weiten[0] bis weiten[99].


Und Codetags sind das, was ich oben in deinen ersten Beitrag eingefügt habe,
damit der Code so angezeigt wird wie er jetzt ist.
Vor den Code (für C++) ein "[code=cpp]" (ohne "")
und nach den Code "[/code]".

Herrje, bin ich heut wieder langsam...:p
 
das sind ja ganz schön viele Informationen auf einmal :) Danke schön auch von dir sheel.

Wie kann ich denn float werte; einfach weglassen? das hat bei mir nicht funktioniert...
 
float werte brauchst du nicht, da du die Variable nur 1 Mal brauchst:
C:
werte=Einlesen(weiten);
Da werte sowieso immer 100 wäre, brauchst du die Variable nicht. Lösche in dieser Zeile "werte=" und in der oberen "int werte;".

Weshalb kannst du es nicht weglassen? Was funktioniert nicht?

Gruss
cwriter
 
ich habe vorher werte durch weiten ersetzt, weil ich dachte, dass vor der Funktion noch was stehen muss. aber so wie du es gesagt hast klappt es. danke
 
Das Raten geht weiter :)
Ich habe wieder die Datei von oben. Es handelt sich um 100 Werte vom Weitsprung in der Reihenfolge Mann Frau Mann Frau Mann Frau..... also insgesamt 50 Männer und 50 Frauen abwechselnd. Ich möchte gerne mit der Unterfunktion " float average_girls (int, float *)" berechnen wie weit die Frauen in Mittel gesprungen sind. Ich hab das Programm nun fertig, auch ohne Fehler, aber es kommt ein ganz komisches Ergebnis in der Ausgabe raus und ich weiß absolut nicht weiter...Könnt ihr mir helfen bitte?

Hier mein Programm:

C:
#include <stdio.h>
float average_girls (int, float *);

int main()
{

    int i;
    float weiten[50];
    float summe=0;
    float average;

    average_girls (i, weiten);
    for (i=1;i<100;i+=2)
    {
        summe=summe+weiten[i];
    }
    if (i>99)
    {
        average=summe/50;
        printf("Average Girls = %f\n", average);
    }


    return 0;
}

float average_girls (int i, float *weiten)

{
    FILE *datei;

    datei=fopen ("sprungweiten", "rt");
    for (i=0;i<100;i++)
    {
        fscanf(datei, "%f", weiten[i]);
    }


    fclose (datei);
}
 
Zurück