ISO C++ forbids comparison between pointer and integer|



  • Hallo,
    will folgendes Programm schreiben:

    "C-Programm, das einen Satz anfordert, einliest und
    den Bereich zwischen dem ersten und dem letzten Gedankenstrich ("-") ausgibt, wobei Leerzeichen am Anfang und Ende des Bereichs vor demAusgeben entfernt werden
    sollen. Falls der Satz nur einen oder keinen Strichenthält, soll eine entsprechende Fehlermeldung ausgegeben werden.
    Hinweis: Der einzulesende Satz hat maximal 1000 Zeichen.
    Beispiel:
    "Ein Wort - erst recht Doppel-Wort -sagt mehr als 1000 Bilder."
    Ausgabe: "erst recht Doppel-Wort

    #include <stdio.h>
    
    int main(){
    
        char text[1002],newtext[1002];
        int x=0, f=0,l=0,y=0,out=0;
    
        printf("Text: ");
        fgets(text,1002,stdin);
        while(text[x] != '\0' || out == 0){
            if(text[x] == "-"){
                out = 1;
            }
            x++;
        }
        f=x;
        while(text[x]){
            if(text[x] == "-"){
                l=x;
            }
        }
        if(out == 1 &&l==0){
            printf("Nur 1 - vorhanden");
        }else if (out == 0){
            printf("Kein - gefunden");
        } else if(out == 1){
            int vl = l-1;
            for(x=f;x<l;x++){
                if(x == f && text[x]==" "){printf("1.Zeichen leer");}
                else if(x=vl&&text[x]==" "){printf("letzes Zeichen leer");}
                else{
                    newtext[y] = text[x];
                    y++;
                }
            }
            printf("%s",newtext);
        }else {printf("FAIL");}
    }
    


  • ...



  • Das Stringliteral (Zeichenkettenliteral) wird wie ein char-Array behandelt.
    Allerdings kannst du es nicht verändern.
    Der Fehler bezieht sich also auf das "-".

    Deine while-Schleife ab Zeile 17 ist eine Endlosschleife.



  • Was mir gerade noch aufgefallen ist: "ISO C++ forbids ..."

    Wenn du C-Programme schreiben sollst, dann stell deinen Compiler auch auf C um.



  • Danke, das mit den '-' ist mir gerade selber aufgefallen^^
    Leerzeichen habe ich jetzt durch 32 ersetzt (ASCII) geht auch.

    Ich programmiere mit codeblocks und da ist das scheinbar so eingestellt 😕 Hat bisher aber auch alles geklappt eig 😉



  • Es ist fast immer besser die Zeichen (' ') statt des Codes (32) zu nehmen.

    In der while-Schleife wird das x nicht weiter gezählt.
    Wenn es durchläuft, dann hat die erste while-Schleife schon bis zum Ende gezählt.

    Aber wahrscheinlich meinst du in der while-Schleif in Zeile 10 auch ein && (statt ||).



  • DirkB schrieb:

    Es ist fast immer besser die Zeichen (' ') statt des Codes (32) zu nehmen.

    In der while-Schleife wird das x nicht weiter gezählt.
    Wenn es durchläuft, dann hat die erste while-Schleife schon bis zum Ende gezählt.

    Aber wahrscheinlich meinst du in der while-Schleif in Zeile 10 auch ein && (statt ||).

    Zeile 15 steht noch ein f--;

    Jep Zeile 10 habe ich schon ausgebessert.
    Zeile 17 hattest Recht ist doch ne Endlosschleife x++ vergessen OMG



  • LukeStriker schrieb:

    Zeile 17 hattest Recht ist doch ne Endlosschleife, kannst du mir verraten wieso?

    DirkB schrieb:

    In der while-Schleife wird das x nicht weiter gezählt.



  • Ein letztes:

    siehst du wieso die letzte for schleife nicht funktioniert? Habe sie jetzt durch ne while ersetzt aber wohl Tomaten auf den Augen

    while(x<l){
                if(x == f && text[x]==' '){
                    printf("1.Zeichen leer\n");
                } //asccii 32
                else if(x==vl && text[x]==' '){
                    printf("letzes Zeichen leer\n");
                }
                else{
                    newtext[y] = text[x];
                    y++;
                }
                x++;
            }
    


  • Was funktioniert denn nicht?

    Du vergisst du abschließende '\0' in newtext.



  • Ne die while funktioniert ja, ich hatte erst ein abschließend '\0' aber es funktioniert auch ohne (frag mich nicht wieso)...
    der Teil funktioniert allerdings nicht:

    for(x=f;x<l;x++){
                if(x == f && text[x]==" "){printf("1.Zeichen leer");}
                else if(x=vl&&text[x]==" "){printf("letzes Zeichen leer");}
                else{
                    newtext[y] = text[x];
                    y++;
                }
            }
    


  • DirkB schrieb:

    Was funktioniert denn nicht?

    Was soll passieren und was passiert.

    Du brauchst die abschließende '\0' in newtext.
    Es kann sein das zufällig schon eine '\0' in newtext drin steht.
    Aber du kannst nicht davon ausgehen, das dies immer so ist.



  • DirkB schrieb:

    DirkB schrieb:

    Was funktioniert denn nicht?

    Was soll passieren und was passiert.

    Du brauchst die abschließende '\0' in newtext.
    Es kann sein das zufällig schon eine '\0' in newtext drin steht.

    Hat mich auch gewundert aber hat bisher immer funktioniert, aus sicher packe ich es ab jetzt rein 😉

    Was soll passieren und was passiert.

    die forschleife bleibt in einer Endlosscheife hängen. Naja solls drum 😉



  • Welchen Wert haben denn x und l vor der Schleife?



  • l = last -> daher Feld des letzten '-'
    x = zähler -> daher last + 1
    Wird aber am Schleifenanfang auf f = first daher das erste Feld eines '-' gesetzt

    Zufällig ne Ahnung was in Zeile 12, 20, 31 falsch ist? Irgendwie übergebe ich das Array falsch: "invalid types `char[int]' for array subscript|" bzw. die Initalisierung in der Funktion

    #include <stdio.h>
    
    void hebrae (char *m, char *satz[100],int ze, int s){
    
        int x=0,y=0,z=0;
    
        if (sizeof(satz)>(ze*s)){
            printf("Matrix zu klein");
        } else {
            while(x<z &&(satz[z] != '\0')){
                while(y < s && (satz[z] != '\0')){
                    m[x][y] = satz[z];
                    y++;
                }
                x++;
            }
            if((z*s) > ze){
                while(x<z){
                    while(y<s){
                        m[x][y]= ' ';
                    }
                }
            }
        }
    }
    
    void ausgabe(char* m,int z, int s){
        int x=0, y=0;
        while(y<s){
            while(x<z){
                printf("%c",m[x][y]);
                x++;
            }
            y++;
        }
    }
    
    main(){
    
        char text[100];
        char m[10][10];
        gets(text);
        printf("%s",text);
    
        hebrae(m,text,10,10);
        ausgabe(m,10,10);
    }
    

    Zeile 45,46
    "cannot convert `char ()[10]' to `char' for argument `1' to `void hebrae(char*, char**, int, int)'|"

    Ich hasse es meinen eigenen Code zu korregien 😞 Kostet unglaublich viel Zeit und man kommt kaum einen Schritt vorwärts



  • LukeStriker schrieb:

    l = last -> daher Feld des letzten '-'
    x = zähler -> daher last + 1
    Wird aber am Schleifenanfang auf f = first daher das erste Feld eines '-' gesetzt

    Und welche Werte stehen aktuell vor der Schleife in den Variablen drin (zur Laufzeit)
    (printf oder Debugger nutzen)
    Sind die evtl. sogar gleich?

    Zeile 31: Woher soll die Funktion denn die zweite Dimension von m kennen?

    Zeile 45 und 46 geben bei mir (Code::Blocks) nur "Warnungen"

    Allerdings bekomme ich in Zeile 12 und 20 auch noch Fehler.

    Ein char[10][10] ist kein *char[10] oder char**
    Ein char[100] ist kein *char[100]

    Ein char[10][10] ergibt zwar ein char* aber siehe Kommentar zu Zeile 31.



  • DirkB schrieb:

    Zeile 31: Woher soll die Funktion denn die zweite Dimension von m kennen?
    Zeile 45 und 46 geben bei mir (Code::Blocks) nur "Warnungen"
    Allerdings bekomme ich in Zeile 12 und 20 auch noch Fehler.
    Ein char[10][10] ist kein *char[10] oder char**
    Ein char[100] ist kein char[100]
    Ein char[10][10] ergibt zwar ein char
    aber siehe Kommentar zu Zeile 31.

    Wie gehts richtig? 😕 Ich kenne noch das man m[][10] oder so als Parameter gibt allerdings ist das dann Call by value und nicht reference?
    void ausgabe(char m[][10],int z, int s) Und so richtig dynamisch ist das ja auch nicht da hier die spalten fix sind?

    Wenn ich "void hebrae(char *m" durch hebrae(char **m" ersetze daher ** sterne statt eins bekomme ich nur noch in Zeile 12 Fehler, wobei mir der Unterschied nicht ganz bewusst wird da es doch egal ist ob ich ein char (satz[z]) oder '' in m[x][y] schreibe?

    Wie ist der Aufbau korrekt?
    - von der main übergebe ich einen Zeiger auf das erste Feld des 2-dimen. Arrays und die z/s damit ich später keinen speicherüberlauf verursache
    - als parameter initialisiere ich den Zeiger und zeige das im Speicher hinter der "ersten Zeile" noch eine weitere Zeile kommt. Und hier muss ich dann die Größe mit initialisieren damit der Compilier weiß wieviele da hintereinander kommen?

    sry das ich gerade so schwer von begriff bin

    Zeile 45 und 46: error: cannot convert `char (*)[10]' to `char**' for argument `1' to `void hebrae(char**, char**, int, int)'|



  • LukeStriker schrieb:

    void hebrae (char *m, char *satz[100],int ze, int s){
     
        int x=0,y=0,z=0;
     
        if (sizeof(satz)>(ze*s)){
            printf("Matrix zu klein");
    ...
    }
    
    main(){
     
        char text[100];
        char m[10][10];
    
        hebrae(m,text,10,10);
    

    Arrays zerfallen bei der Übergabe an Funktionen in einen Pointer auf ihre Anfangsadresse.
    Das sizeof innerhalb der Funktion bezieht sich dann auf die Größe vom Zeiger und nicht auf das Array (Zeile 5).

    char *satz[100] ist eine Array von 100 Zeigern auf char. Das geht als char **satz durch (Doppelzeiger).
    text ist ein char-Array. Das geht als char* durch (Einfachzeiger).

    m ist ein echtes 2D-Array und das geht auch als char* durch.

    Du darfst ein char *feld[] nicht mit einem char feld[][] verwechseln.

    Das rumgerate mit den * nützt dir nichts. Du musst schon wissen was du tust.
    GRUNDLAGEN

    void hebrae (char m[][10], char *satz, int ze, int s){
    

    passt zu dem Aufruf von hebrae in main.
    Aber das mit dem sizeof haut nicht hin.

    LukeStriker schrieb:

    int x=0,y=0,z=0;
    ... 
          while(x<z &&(satz[z] != '\0')){
    

    Das while wird gar nicht erst durchlaufen, da schon das x<z fehlschlägt.

    Was soll das eigentlich machen?



  • DirkB schrieb:

    Arrays zerfallen bei der Übergabe an Funktionen in einen Pointer auf ihre Anfangsadresse.
    Das sizeof innerhalb der Funktion bezieht sich dann auf die Größe vom Zeiger und nicht auf das Array (Zeile 5).

    Bekannt, aber durch die ganzen Zeiger etc bin ich durcheinander gekommen. Habe das geändert in

    while(satz[sizesatz]){
            sizesatz++;
        }
    
        if (sizesatz>(ze*s)){
            printf("Matrix zu klein");
    

    Geht das noch einfacher?
    Am Ende einer Matrixzeile gibt es kein '\0' soweit ich weiß oder? Daher kein +/-1.

    DirkB schrieb:

    char *satz[100] ist eine Array von 100 Zeigern auf char. Das geht als char **satz durch (Doppelzeiger).
    text ist ein char-Array. Das geht als char* durch (Einfachzeiger).

    Wieder falsch geschaltet, ich hatte irgendwie gedacht ich kann damit die größe des Feldes beschränken was ziemlich humbug ist da dies ja schon in der main() passiert.

    also 100 Zeiger auf jeweils ein char Feld??
    Wenn ich in der main nur einen String deklariere z.B. char feld[100]; und übergebe die erste Adreses des feldes mit funktion(feld) oder funktion(&feld[0]). Was initialisiere ich dann mit funktion(char *feld[100])?

    DirkB schrieb:

    m ist ein echtes 2D-Array und das geht auch als char* durch.

    Du darfst ein char *feld[] nicht mit einem char feld[][] verwechseln.

    Was heißt echt? In der Main als Feld und nicht als Zeiger bzw. dynamisch mit malloc generiert?

    Meine Interpretation war so:
    char *feld[] -> call by reference daher ich verändere das ursprüngliche Array der main was ja später wieder in der funktion ausgabe verwendet wird
    char feld[][] -> call by value daher wäre es nach Funktionsabschluss weggewesen.

    Für was steht jetzt was? Ich tu mich da echt schwer durchzublicken bei Array/String Array.

    -> Ich übergebe also nur die Adresse des 2D Feldes und als Initialisierung char m[][] und arbeite im Endeffekt mit dem ursprünglichen Array aus der Main.
    Und das hier: *feld[] hat gar nichts mit mehrdimensionalen Arrays zu tun sondern wird eher verwendet wenn man Pointer auf irgendwas setzen möchte.

    DirkB schrieb:

    Das rumgerate mit den * nützt dir nichts. Du musst schon wissen was du tust.
    GRUNDLAGEN

    Du tust ja so als ob ich das mit Absicht mache^^ Ich kannte bisher nur Perl und da funktioniert das alles automatisch, da muss man für ein dynamisches Feld nicht ewig lang Sachen mit malloc rumschnitzeln oder großartig differenzieren bei Funktionsübergaben. Bin für ein gutes Tutorium immer offen, versuch mir das schon irgendwie mit Büchern etc reinzuwürgen aber bisher ist das mehr Rätzel raten^^
    Daher versuche ich learning by doing durch Aufgaben was eig m.M.n. bei Programmiersprachen am besten klappt- viel Zeit raubt und manchmal zum verzweifeln ist^^ Und zu meiner Verteidigung, ich habe alles aufs Blatt programmiert und dann abgetippt. Die normalen "Zwischen-checks" wie beim normalen Programmieren um Flüchtigkeitsfehler zu beheben sind also weggefallen...

    DirkB schrieb:

    void hebrae (char m[][10], char *satz, int ze, int s){
    

    passt zu dem Aufruf von hebrae in main.

    LukeStriker schrieb:

    int x=0,y=0,z=0;
    ... 
          while(x<z &&(satz[z] != '\0')){
    

    Das while wird gar nicht erst durchlaufen, da schon das x<z fehlschlägt.

    Was soll das eigentlich machen?

    while(x<ze &&(satz[z] != '\0')){
    

    -> ze statt z ist richtig; habs übersehen zu ändern da ich ausversehen z zu einer Laufvariable gemacht hatte und z als Parameter initialisiert hatte. Dann hab ich den Parameter von z auf ze geändert...

    Also:
    a) Erstellen Sie für diese sog. hebräische Verschlüsselungsmethode eine Prozedur hebrae, der eine Matrix mit einer maximalen Zeilen- und Spaltenlänge von 10, die zu verschlüsselnde Nachricht (Satz mit max. 100 Zeichen) sowie eine Zeilen- und Spaltenzahl für die Eintragung des zu verschlüsselndes Satzes übergeben wird. Prüfen Sie vorab, ob die Matrix genügend Platz für die Verschlüsselung der Nachricht bietet und geben Sie ggf. eine entsprechende Fehlermeldung aus. Ist der zu verschlüsselnde Satz kürzer als der vorhandene Speicherplatz der Matrix, sind nicht ausgefüllte Matrixelemente mit Leerzeichen aufzufüllen.
    b) Schreiben Sie eine Prozedur ausgabe, die die verschlüsselte Nachricht spaltenweise am Bildschirm ausgibt.

    UPDATE: Sehe gerade was ich da eig für'n Mist gemacht habe. Hatte das zurücksetzten der Zeilen/Spalten verplant. Jetzt funktioniert das schonmal einwandfrei.

    #include <stdio.h>
    
    void hebrae (char m[][10], char *satz,int ze, int s){
    
        int x=0,y=0,z=0,sizesatz = 0;
    
        while(satz[sizesatz]){
            sizesatz++;
        }
    
        if (sizesatz>(ze*s)){
            printf("Matrix zu klein");
        } else {
            while(x<ze){
                y=0;
                while(y < s){
                    if (satz[z] != '\0'){
                        printf("x: %d y:%d Buchstabe: %c\n",x,y,satz[z]);
                        m[x][y] = satz[z++];
                    } else {
                        m[x][y]= ' ';
                    }
                    y++;
                }
                x++;
            }
        }
    
    }
    
    void ausgabe(char m[][10],int z, int s){
        int x=0, y=0;
        while(y<s){
            x=0;
            while(x<z){
                printf("%c",m[x][y]);
    
                x++;
            }
            y++;
        }
    }
    
    main(){
    
        char text[100];
        char m[10][10];
        gets(text);
    
        hebrae(m,text,2,2);
        ausgabe(m,2,2);
    }
    


  • LukeStriker schrieb:

    Was heißt echt? In der Main als Feld und nicht als Zeiger bzw. dynamisch mit malloc generiert?

    Ein Array ist kein Zeiger, ein Zeiger ist kein Array.
    Ein Array ist nicht "dynamisch", das gilt auch für mehrdimensionale Arrays.
    Manche begreifen das nie.

    LukeStriker schrieb:

    Meine Interpretation war so:
    char *feld[] -> call by reference daher ich verändere das ursprüngliche Array der main was ja später wieder in der funktion ausgabe verwendet wird
    char feld[][] -> call by value daher wäre es nach Funktionsabschluss weggewesen.

    Nix mit call by reference. In C gibt es kein call by reference, ausschließlich call by value. Manche begreifen das nie.

    LukeStriker schrieb:

    Für was steht jetzt was? Ich tu mich da echt schwer durchzublicken bei Array/String Array.

    Ja das merkt man. Das Verständnis hierfür ist für C aber essentiell. Manche begreifen das nie.
    Und deswegen ist dein "learning by doing" für C eine schlechte Wahl, es gibt hier wenig, was "automatisch" passiert.


Anmelden zum Antworten