Fehlermeldung in C

Hallo Community,
das ist mein erster Beitrag.

Ich sitze vor einer Programmieraufgabe in C.
Aufgabenstellung:
Deklarieren Sie ein struct namens intArray, welches einen Zeiger auf ein Integer-Array sowie die Länge des entsprechenden Arrays speichern kann.

Schreiben sie eine Funktion intArray* readFromFile(char* filename), welche ganze
Zahlen aus einer Datei einliest und diese über ein intArray zurückgibt. Die einzelnen Zahlen sind in der Datei durch Zeilenumbrüche (newline) getrennt.




Also ich hab meiner Ansicht nach alles getan, was da steht und ich bekomme trotzdem Fehlermeldungen, die ich nicht verstehe und da wollte ich Fragen ,ob ich von Euch eine kleine Hilfe bekommen könnte.
Ich muss dazu sagen, dass ich ein totaler Neuling in C bin.


Mein Ansatz:




Code:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>



intArray* readFromFile(char* filename){

    FILE *datei;
    if ( (datei = fopen("filename", "r")) == NULL){
          return errno;
    }

        int a=0;
        int zahl;
        intArray zahlen;
        
        zahlen.n=1000000;
        zahlen.array=malloc(sizeof(int)*n);

    while (fscanf (datei, "%i", &zahl) == 1) {
        
        
          zahlen.array[a];
        a++;
    }

    for (int i = 0; i < a; ++i ) {
          printf ("%i ", zahlen.array[i]);
    }
    puts ();

    return zahlen;

}










int main(int argc, char* argv[]){

    typedef struct{
        int n;
        int* array[];
    }intArray;
    


    readFromFile(argv[1]);


    return 0;
}
 
Zuletzt bearbeitet von einem Moderator:
Fehlermeldungen an sich sind sind ja schön und gut, man müsste halt nur wissen welche :wink:. Compiler-, Linker- oder Fehler beim Ausführen?
Auf den ersten Blick sieht aber folgender Block recht interessant aus:
Code:
while (fscanf (datei, "%i", &zahl) == 1)
{
        zahlen.array[a];
        a++;
}
Der macht nämlich nicht nicht wirklich was, da die "zahl" nirgends gespeichert wird. Sollte wohl eher so aussehen:
Code:
while (fscanf (datei, "%i", &zahl) == 1)
{
        zahlen.array[a] = zahl;
        a++;
}
Außerdem gibst du den reservierten Speicher nirgends frei, was mal ein schönes Speicherleck bedeutet.

mfg benediktibk
 
Code:
if ( (datei = fopen("filename", "r")) == NULL)

Hier sind die Anführungszeichen zu viel. So versucht er immer die Datei mit dem Namen filename zu öffnen. Du übergibst der Funktion aber ja den Namen der Datei als Argument.

Das return errno funktioniert auch nicht, weil dein Rückgabetyp nunmal intArray* ist und nicht int.

Außerdem setzt du die Zahl der Elemente "von Hand" auf 1000000. Ist das gewollt? Ich hätte die Aufgabe so verstanden, dass du diese Zahl dynamisch bestimmen sollst - eben je nachdem wie viele Zahlen in der Datei stehen. Um entsprechend Speicher zu allokieren könntest du dann realloc verwenden.

Code:
zahlen.array=malloc(sizeof(int)*n);

Die Variable n wurde vorher nirgendwo deklariert und initialisiert (zahl wurde übrigens auch nicht initialisiert, das sollte man sich aber so früh wie möglich angewöhnen tun).

malloc() gibt dir einen void* zurück, den kannst du nicht ohne cast einem int* zuweisen.

Weiterhin ist das puts(); da einwenig fehl am Platze. Da fehlt ein Argument, was denn ausgegeben werden soll.

Zum Schluss gibst du zahlen zurück. Das ist ein intArray. Deklariert hast du den Rückgabewert aber als intArray*. Für eines von beiden musst du dich schon entscheiden ;)

In der main() wird deine Funktion mit dem zweiten Argument aufgerufen. Ist das so gewollt?

Der typedef hat in der main eigentlich nichts verloren. setz den mal ganz an den Anfang direkt nach den includes. Sonst kennt deine Funktion auch gar nicht ihren Rückgabetypen.
 
Ich hab jetz die Tipss von euch befolgt,aber das mit dem Rückgabewert von intArray* verstehe ich irgendiwe nicht was ich da jetz zurückeben soll, laut aufgabenstellung soll die Funktion ja ein intArray* zurückgeben,hhmm...

und zu der main()funktion, ja ich wollte die Datei die durchsucht werden soll als Parameter eingeben, geht das so nicht?


Code:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

typedef struct{
        int n;
        int* array;
    }intArray;

intArray* readFromFile ( char* filename){

    FILE *datei;
    datei = fopen(filename, "r");
         
    

        int a=1;
        int zahl=0;
        intArray zahlen;
        zahlen.n = a;
        
        
        

    while (fscanf (datei, "%i", &zahl) == 1) {
        
        zahlen.array = (int*) realloc (zahlen.array, zahlen.n * sizeof(int));
          zahlen.array[a] = zahl;
        
        a++;
    }
    int i;
    for (i = 0; i <= a; ++i ) {
          printf ("%i ", zahlen.array[i]);
    }
    free(zahlen.array);

    return zahlen;

}










int main(int argc, char* argv[]){

    
    


    readFromFile(argv[1]);


    return 0;
}
 
Zuletzt bearbeitet:
und zu der main()funktion, ja ich wollte die Datei die durchsucht werden soll als Parameter eingeben, geht das so nicht?

Doch, sry, mein Fehler. So sollte es funktionieren.

Zu dem Rückgabetypen:

Du deklarierst den Rückgabetypen deiner Funktion als intArray*. Also als Zeiger auf ein intArray struct. Du versuchst aber ein intArray, also das struct selbst, zurück zu geben. Das sind zwei unterschiedliche Datentypen und deshalb funktioniert das so nicht. Wenn du laut Aufgabenstellung einen Zeiger auf dein struct zurück geben sollst, dann musst du mit return auch einen entsprechenden Zeiger zurück geben.
Dabei solltest du dann aber darauf achten, das das struct auch nach ende der Funktion noch existiert.

Wenn du noch Anfänger bist, dann würde ich dir empfehlen dich nochmal genauer mit Zeigern zu beschäftigen. Das Thema sorgt eigentlich bei jedem C/C++ Anfänger zu Beginn für etwas Verwirrung. Aber wenn man das Prinzip einmal kapiert hat kann man damit schöne Dinge anstellen ;)
 
Den Wert für n setzt du einmal, der ändert sich im Laufe der Schleife nicht. Deswegen ist das realloc im Moment auch noch ziemlich sinnlos, da der Wert ebenfalls inkrementiert werden muss.
Das free ist einmal keine schlechte Idee, nur solltest du dir überlegen, ob es wirklich dort angebracht ist, wo du es einsetzt. Weil damit gibst du den Speicher für die mühsam ausgelesenen Zahlen bereits innerhalb der Funktion wieder frei, und kannst danach nicht mehr darauf zugreifen. Damit ist irgendwie der Sinn der Funktion nicht ganz erfüllt? :wink:
Das intArray* bedeutet, dass die Funktion einen Zeiger auf eben ein intArray zurück geben soll. Du versuchst aber im Moment einen Variable vom Datentyp intArray zurück zu geben.
Code:
intArray* readFromFile ( char* filename)
{
     intArray *zahlen;

     // Speicher für das Zahlen-Array reservieren
     zahlen = (intArray*) malloc(sizeof(intArray));

     // do some stuff

     return zahlen;
}

int main(int argc, char* argv[])
{
     intArray *zahlen;

     zahlen = readFromFile(...

     // Reservierten Speicher für das Array an sich frei geben
     free(zahlen->array);

     // Reservierten Speicher für die Struktur frei geben
     free(zahlen);

     return 0;
}

mfg benediktibk

Edit: Zu langsam. Warum muss ich aber auch so ausführliche Erklärungen schreiben ...
 
Zurück
Oben