Anfänger auf der Suche nach Antworten - Fehlermeldung im Compiler bei einer Funktion



  • Hallo zusammen!
    Da ich neu hier bin und dies mein erster Beitrag ist möchte ich kurz zum besten geben was meine Absichten hier sind.
    Ich bin vor einiger Zeit über Microcontroller zur C Programmiererei gekommen - gänzlich ohne Vorahnung - und brauche jetzt eure Hilfe. Wie bereits erwähnt kann ich fast garnix 🙂

    Ich hab versucht eine Funktion zu schreiben die ich gerne in ein Programm einbauen will. Jedoch sagt mein Codeblocks beim Compilieren immer Fehler in der Zeile "bool Zahlenkontrolle(Feld[],FELDGROESSE){" error: initializer expression list treated as compound expression|. Was bedeutet das und warum passiert das? "error: expected ,' or;' before '{' token" kommt in der gleichen Zeile. Wo liegt der Fehler?

    Hab jetzt nur die Funktion geschrieben und den Rest des Programms noch nicht. Jedoch ist die angedachte Funktion das die Funktion einen wahr oder falsch Wert zurückliefern ob der String nur aus Zahlen besteht oder nicht.

    Könnt ihr mir bitte helfen?

    //Bibiotheken einbinden
    #include <stdlib.h>
    #include <ctype.h>
    #include <stdio.h>
    #define FELDGROESSE 8
    //Variablen und Felder
    char Feld[] = "123Welcome2C programming!";
    //Funktionen
    bool Zahlenkontrolle(Feld[],FELDGROESSE){
        int stellenOK = 0;
        bool Zahlencheck=false;
        for (int i = 0; i < 7; i++)
            {
                if (isdigit(eingabe[i])) {stellenOK++;}
            }
        if (stellenOK == FELDGROESSE)
            Zahlencheck=true;
        else
            Zahlencheck=false;
        return (Zahlencheck);
    }
    //Hauptprogramm
    main()
     {
    
     }
    


  • Weil dein Compiler den Typ bool nicht kennt.
    bool ist kein Basistyp, d.h. dem Compiler muss via include der ab C99 vorhandene Typ mitgeteilt werden.
    D.h. wenn du einen C99 konformen Compiler besitzt, dann

    #include <stdbool.h>
    

    wenn nicht, dann tut es auch

    typedef int bool;
    enum{false,true};
    


  • In der Argumentliste der Funktion solltest du schon den Typ der Variable mit angeben.
    Das Feld aus Zeile 7 hat mit dem Feld aus Zeile 9 nichts zu tun.
    Und FELDGROESSE wird vom Preprozessor durch die 8 ersetzt.
    Mit einer Konstanten in der Argumentenlist kann der Compiler auch nichts angangen.



  • also diese sachen mit bool usw. braucht man eigentlich nicht. ein einfacher int tuts auch.



  • Also ich habe jetzt den Code angepasst und mir auch Gedanken gemacht über das was Ihr mir gschrieben habt. Das was unten steht ist dabei herausgekommen. Eine Fehlermeldung gibt der Compiler nun auch nicht mehr aus.
    DirkB kannst du mir bitte erklären ws du damit meinst das die Felder nichts miteinander zutun haben? Wie übergebe ich den das Feld an die Funktion? Es ist doch richtig das ich wenn ich die Funktion aufrufe ich das Feld übergeben kann? Hab es jetzt mal umbenannt ist es so besser?

    //Bibiotheken einbinden
    #include <stdlib.h>
    #include <ctype.h>
    #include <stdio.h>
    //Variablen und Felder
    char Feld[] = "123Welcome2C programming!";
    //Funktionen
    bool Zahlenkontrolle(char Feldcheck[],int FELDGROESSE){
        int stellenOK = 0;
        bool Zahlencheck=false;
        for (int i = 0; i < FELDGROESSE; i++)
            {
                if (isdigit(Feldcheck[i])) {stellenOK++;}
            }
        if (stellenOK == FELDGROESSE)
            Zahlencheck=true;
        else
            Zahlencheck=false;
        return (Zahlencheck);
    }
    //Hauptprogramm
    main()
     {
    
     }
    


  • du musst die arrays als pointer auf das erste element übergeben. das klingt schwieriger als es ist.

    bool Zahlenkontrolle(char *Feldcheck /* <-- pointer! */ ,int FELDGROESSE){
    

    danach kannst du die funktion aufrufen:

    #include <string.h> // für strlen()
    
    char Feld[] = "123Welcome2C programming!";
    
    Zahlenkontrolle(Feld,strlen(Feld);
    

    die sache mit der feldgröße ist noch nicht so toll gelöst.
    eigentlich muss man die nicht wissen.

    und wie ich schon sagte, die ganzen bools verkomplizieren die sache einfach nur.



  • so würde ich deinen code schreiben:

    #include <stdlib.h>
    int Zahlenkontrolle(char *Feld){
        while(*Feld != '\0') {
               if(isdigit(*Feld)) return 1;
               Feld++;
        }
        return 0;
    }
    

    Hauptfunktion:

    #include <stdio.h>
    char Feld[] = "123Welcome2C programming!";
    
    int main()
    {
         if(Zahlenkontrolle(Feld)) {
               printf("Fehler: String enthaelt auch Nicht-zahlen!\n");
         }
         else {
               printf("String ist ok\n");
         }
         return 0;
    }
    


  • da ist mir wohl grad ein flüchtigkeitsfehler unterlaufen:

    #include <stdlib.h>
    int Zahlenkontrolle(char *Feld){
        while(*Feld != '\0') {
               if(!isdigit(*Feld)) return 1; // <-- ausrufezeichen!
               Feld++;
        }
        return 0;
    }
    

    funktioniert.



  • Danke für deine tolle Antwort BOOL.

    Je öfter ich mir deinen Code durchlese je mehr verstehe ich bzw. meine ich zu verstehen. Du übergibst also die Adresse vom Anfang des Strings in die Funktion und arbeitest damit. Kannst du mir bitte noch erklären wie du im Feld dann von Element zu Element springst? Machst du das mit "Feld++" und warum funktioniert das?



  • BOOL - nachtrag 2 schrieb:

    da ist mir wohl grad ein flüchtigkeitsfehler unterlaufen:

    #include <stdlib.h>
    
    // Rückgabewert (int) für alles okay = 0, ansonsten != 0
    // Parameter (char *), also ein Zeiger auf den Anfang eines char-Arrays
    int Zahlenkontrolle(char *Feld)
    {
        while(*Feld != '\0') // Solange die Nullterminierung, also das Ende nicht erreicht wurde
        {
               if(!isdigit(*Feld)) // Aktuelles Zeichen (*Feld) ist keine Zahl
                 return 1; // <-- ausrufezeichen!
    
               Feld++; // Erhöhung der Position im Zeiger, ruft nächstes Zeichen ab
        }
    
        return 0;
    }
    
    // Alternative Schreibweise, die aber langsamer ist, da erst die Länge bestimmt werden muss
    int Zahlenkontrolle(char *Feld)
    {
        int len = strlen(Feld);
        int i;
    
        for (i = 0; i < len; ++i)
        {
             if (!isdigit(Feld[i]))
               return 1;
        }
    
        return 0;
    }
    

    funktioniert.



  • DerSchlangen schrieb:

    Danke für deine tolle Antwort BOOL.

    Je öfter ich mir deinen Code durchlese je mehr verstehe ich bzw. meine ich zu verstehen. Du übergibst also die Adresse vom Anfang des Strings in die Funktion und arbeitest damit. Kannst du mir bitte noch erklären wie du im Feld dann von Element zu Element springst? Machst du das mit "Feld++" und warum funktioniert das?

    ja.
    das grundprinzip ist ja, dass man jedes zeichen des strings einzeln überprüft, ob es eine zahl ist oder nicht.

    nun ist es so, in c gibt es keine "strings" sondern nur arrays. das hast du ja auch schon selbst angewendet: char Feld[] = "123Welcome2C programming!";

    außerdem muss man wissen, dass strings in c mit einem "unsichtbaren" zeichen beendet werden, nämlich '\0' . Dieses Zeichen siehst du nicht, und du brauchst dich da auch nicht drum zu kümmern, das macht der kompiler.

    bei der ausführung des programms landet das array im arbeitsspeicher. jedes einzelne zeichen hat im arbeitsspeicher seine eigene adresse. du musst dir dabei vorstellen, dass der arbeitsspeicher aus vielen kleinen zellen besteht, die alle nur ein zeichen aufnehmen können. jede einzelne zelle hat ihre adresse, über die sie angesprochen werden kann.

    sagen wir jetzt mal: das erste zeichen des strings (ist '1') hat im arbeitsspeicher die adresse 1.
    dann hat das zweite zeichen die adresse 2, das dritte die adresse 3, das vierte die adresse 4 usw. das letzte zeichen des strings ist das '\0' -Zeichen, das ja automatisch hinzugefügt wird.

    nun übergibst du die adresse des ersten zeichens des arrays, das haben wir ja gerade festgelegt, die adresse ist 1.
    nun wird der inhalt der speicherzelle mit der adresse 1 angeschaut. in der speicherzelle mit der adresse 1 ist ja eine zahl, nämlich '1' . das wird an die funktion "isdigit()" weitergegeben, die jetzt überprüft, ob das gegebene zeichen eine zahl ist oder nicht.

    wenn das zeichen eine zahl ist (was hier der fall ist), dann gehts weiter mit
    Feld++;
    der "++" operator in c erhöht einfach "Feld" um 1. das bedeutet: die adresse der ersten speicherzelle (-> war 1) wird jetzt um 1 erhöht (-> 2).

    d.h. die neue adresse ist 2.
    wir erinnern uns: die zweite speicherzelle hatte ja das zweite zeichen aus dem array gespeichert.

    jetzt wird der inhalt der zweiten speicherzelle an die funktion "isdigit()" übergeben und geprüft.

    so geht das jetzt immer weiter, solange ein zeichen im array keine zahl ist (dann gibt die funktion 1 zurück) oder das ende des strings (-> das zeichen '\0') nicht erreicht wurde.

    wenn das ende des strings erreicht wurde, dann bedeutet das, dass im ganzen string kein "falsches" zeichen war.

    das prinzip, was ich hier versuche zu erklären, heißt "pointer". das ganze ist am anfang sehr schwer zu verstehen.

    am besten, du googelst mal "c pointer" oder so.

    der code in worten:

    Solange ( zeichenAusArray nicht '\0' ist)
          Prüfe, ob aktuelles Zeichen eine Zahl ist oder nicht
               wenn NEIN
                    gib 1 zurück (-> Fehler)
               wenn JA
                    gehe zu nächstem Zeichen, bzw. erhöhe die adresse um 1
    

    p.s.: vergiss bool als Datentyp. bool kam erst einem sehr späten standard zu c dazu, eigentlich ist es komplett überflüssig, weil man da auch einen einfachen int benutzen kann.

    nachfragen erlaubt 🙂



  • Nur mal zur Klarstellung:
    Zwischen

    bool Zahlenkontrolle(char *Feldcheck,
    

    und

    bool Zahlenkontrolle(char Feldcheck[],
    

    ist gar keinen Unterschied auch wenn es so aussehen mag.

    Das Problem war das

    int FELDGROESSE
    

    wenn FELDGROESSE ein Makro ist.
    Dann steht da letztendlich

    bool Zahlenkontrolle(char Feldcheck[], int 8) {
    

    Also, eine Variable mit Namen 8.
    Variablennamen dürfen in C nicht mit einer Ziffer anfangen.



  • Danke 🙂


Anmelden zum Antworten