Pointer-Einsatz in einer Funktion



  • char *markText(char *s, char sel) {
    	char *zeichenkette = s;
    	int slaenge = 0;
    	int anzahlsel = 0;
    	int groesse;
    
    	while(*s) {
    		slaenge++;
    		if(*s == sel) anzahlsel++;
    		s++;
    	}
    
    	s = zeichenkette;
    
    	groesse = slaenge+anzahlsel*2;
    	zeichenkette = malloc(groesse);
    
    	if(!zeichenkette) return 0;
    
    	while(*s) {
    		if(*s == sel) {
    			*zeichenkette++ = '_';
    			*zeichenkette++ = *s;
    			*zeichenkette++ = '_';
    		} else {
    			*zeichenkette++ = *s;
    		}
    		s++;
    	}
    
    	*zeichenkette = '\0';
    
    	return zeichenkette-groesse;
    }
    
    int main() {
    	char *text;
    
    	text = markText("Hello World!", 'l');
    	if(!text) return 1;
    	printf("%s\n", text);
    	free(text);
    
    	return 0;
    }
    


  • Irgendein Dorftrottel findet sich immer.



  • Wo wir doch die ganze ZEit über Nullterminierung gesprochen haben.
    groesse wird zu klein berechnet.

    int slaenge = 1;
    

    Und es ist auch keine Schande mehrere Zeiger zu verwenden.
    Wenn die nicht gleichzeitig gebraucht werden, richtet das der Compiler.



  • Okay, jetzt bin ich vollkommen überzeugt, die Punkte waren sehr plausibel! Danke 👍



  • DirkB schrieb:

    Wo wir doch die ganze ZEit über Nullterminierung gesprochen haben.
    groesse wird zu klein berechnet.

    int slaenge = 1;
    

    Und es ist auch keine Schande mehrere Zeiger zu verwenden.
    Wenn die nicht gleichzeitig gebraucht werden, richtet das der Compiler.

    Man könnte dann auch gleich noch auf zwei der drei int-Variablen und die Berechnung der Buffer-Größe im Anschluss an die erste Schleife verzichten, wenn man 'groesse' zu Beginn mit 1 für die Nullterminierung intialisiert und dann in der Schleife für jedes Zeichen um 1 erhöht und bei Auftreten von 'sel' zusätzlich um 2 erhöht.



  • ich habe nun etwas an meinem Code gearbeitet und mein Momentaner Stand zeigt mir weiterhin noch Fehler, aber verstehe diese noch nicht so Recht bzw kann diese nicht korrekt nachvollziehen und korrigieren.

    Mein momentaner Stand:

    #include <stdio.h>
    #include <string.h>
    
    char *markText(char *s, char sel) {
    
    char s = "Hello World!";
    sel = 'l';
    
    char ubergabe[17];   
    char s2[]= s;
    
    int i;
    int m;
    
        for(i=0,m=0; i<12; ++i,++m) {
    
            s2[i]; 
    
            if(s2[i]==sel) {
                ubergabe[m] = sel ;
                ++m;
                ubergabe[m] = s2[i];
                ++m;
                ubergabe[m] = sel ;
                printf("Ausgabe m gleich: %d \n", m);
            }
    
            if(s2[i]!=sel) {
                ubergabe[m] = s2[i];
                printf("Ausgabe m undgleich: %d \n", m);
    
            }
    
        }   
    
        s = ubergabe;
    
        return(s);
    }
    
    int main () {
    
    char ArrayA[] = "Tschüss";
    char zeichen = 'P';
    
    markText(ArrayA,zeichen);
    
    printf("\n\nAusgabe: %s \n\n", ArrayA);
    
    return 0;
    
    }
    


  • DirkB schrieb:

    Cobain schrieb:

    Es werden mir mehrere Fehler angezeigt.

    Mir nicht. (ich habe das aber auch nicht compiliert, daher weiß ich nicht welche Fehler du meinst)

    Damit war gemeint, dass du die Fehlermeldungen auch postest.

    Wo sind die Unterstriche denn jetzt wieder hin?

    Einem Array kannst du nicht durch Zuweisung ein anderes Array (oder Zeiger) zuweisen.

    Was sollen Zeile 6 und 7?

    Das funktioniert so nicht, da ubergabe nach Zeile 39 (da ist die Funktion zuende) aufhört zu existieren.
    Und wir haben hier schon mehrmals über Nullterminierung von C-Strings geschrieben. Die fehlt auch.

    Du sollst nicht rumraten, sondern vorher ein Konzept aufstellen, dass du dann umsetzt.
    Probier das Ganze mit Bleistift(en) und Papier aus. So ein Stift kannst du auch als Zeiger nehmen.
    BEobachte dich dabei, wann du welche Zeichen kopierst und wann du welche Zeiger weiter schiebst.



  • habe jetzt paar Fehler beheben können. Der Code läuft, aber die bearbeitete Version von Hello World! wird nicht wieder in der main ausgegeben.
    In der Main habe ich zwei char variablen deklariert mit falschen "werten", mir ging es nur darum eine basis zu haben die dann in der Funktion umgeändert wird. Der Grund für dieses Denken war, dass in der Aufgabenstellung nur nach einer Funktion gefragt war und eine Funktion alleine lässt sich nicht einfach compilieren und ausführen.

    #include <stdio.h>
    #include <string.h>
    
    char *markText(char *s, char sel) {
    
    s = "Hello World!";
    sel = 'l';
    
    char ubergabe[17];   
    
    int i;
    int m;
    
        for(i=0,m=0; i<12; ++i,++m) {
    
            //s2[i]; 
    
            if(s[i]==sel) {
                ubergabe[m] = '_' ;
                ++m;
                ubergabe[m] = s[i];
                ++m;
                ubergabe[m] = '_' ;
                printf("Ausgabe m gleich: %d \n", m);
            }
    
            if(s[i]!=sel) {
                ubergabe[m] = s[i];
                printf("Ausgabe m undgleich: %d \n", m);
    
            }
    
        }   
    
        s = ubergabe;
    
        return(*s);
    }
    
    int main () {
    
    char ArrayA[] = "Tschüss";
    char zeichen = 'P';
    
    markText(&ArrayA,zeichen);
    
    printf("\n\nAusgabe: %s \n\n", ArrayA);
    
    return 0;
    
    }
    


  • In der Funktion wird der Text Hello World! korrekt bearbeitet aber nicht wieder in die Main eingeführt.



  • Das ist nun der Code der ausführbar ist, jedoch nicht in die Main zurückgegeben wird.

    #include <stdio.h>
    #include <string.h>
    
    char *markText(char *s, char sel) {
    
    s = "Hello World!";
    sel = 'l';
    
    char ubergabe[17];   
    
    int i;
    int m;
    
        for(i=0,m=0; i<12; ++i,++m) {
    
            if(s[i]==sel) {
                ubergabe[m] = '_' ;
                ++m;
                ubergabe[m] = s[i];
                ++m;
                ubergabe[m] = '_' ;
                printf("Ausgabe m gleich: %d \n", m);
            }
    
            if(s[i]!=sel) {
                ubergabe[m] = s[i];
                printf("Ausgabe m ungleich: %d \n", m);
    
            }
    
        }   
    
        s = ubergabe;
        printf("\n\nAusgabe: %s \n\n", s);
    
        return(s);
    }
    
    int main () {
    
    char ArrayA[] = "Tschüss";
    char zeichen = 'P';
    
    markText(ArrayA,zeichen);
    
    printf("\n\nAusgabe: %s \n\n", ArrayA);
    
    return 0;
    
    }
    

  • Mod

    Wie würdest du denn überhaupt irgendetwas aus einer Funktion zurück geben? Mach mal an einem einfacheren Beispiel vor!



  • funktionsaufruf (&blabla)

    dann call by reference

    und dann am ende der Funktion return (*blabla2)

    Ich habe es nach diesem Schema versucht, jedoch werden mir dann aufeinmal mehrere Fehler angezeigt, sprich falscher Funktionsaufruf etc



  • Du nutzt den Rückgabewert von markText in main nicht.

    Die Adresse von ArrayA wird in deiner Funktion im Zeiger s als Kopie gespeichert.

    In Zeile 6 zeigt dann dieser Zeiger auf "Hello World!". Der Zeiger zeigt woanders hin. Da wird keine Zeichenkette kopiert! GRUNDLAGEN

    Damit geht schon mal jeder Bezug zu ArrayA verloren.

    Ab Zeile 35 zeigt s dann auf ubergabe
    Du gibst demnach in Zeile 39 die Anfangsadresse von ubergabe zurück.
    Aber danach ist der Speicherbereich von ubergabe ungültig. Du darfst ihn nicht mehr benutzen.



  • Cobain schrieb:

    funktionsaufruf (&blabla)

    dann call by reference

    und dann am ende der Funktion return (*blabla2)

    Ich habe es nach diesem Schema versucht, jedoch werden mir dann aufeinmal mehrere Fehler angezeigt, sprich falscher Funktionsaufruf etc

    Und wie sieht es bei call by value mit Rückgabewerte aus?

    Vergiss das Schema mal, das ist Schrott wie du selber merkst.
    Wann beim Funktionsaufruf und beim rerturn ein & oder * hinkommt, hängt von den Typen der Variablen und Argumente ab.
    Vor allem hat "call by reference" nichts mit return zu tun.


  • Mod

    Cobain schrieb:

    funktionsaufruf (&blabla)

    dann call by reference

    und dann am ende der Funktion return (*blabla2)

    Eben nicht. Du wirfst alles durcheinander.

    Schreib mal wirklich zwei kleine Programme, welche demonstrieren:
    a) Funktion gibt einen Wert zurück (z.B. 5), dieser wird irgendwie weiter benutzt (z.B. ausgegeben).
    b) Funktion verändert den Wert einer Variablen (z.B. auf 5), diese Variable wird irgendwie weiter benutzt (z.B. ausgegeben).



  • void zahlenausgabe(int n) {
    printf("Ausgabe: %d",n);
    }

    int main () {
    int zahl = 5;
    return 0;
    }

    void zahlenausgabe(int *n) {
    *n = 10;
    }

    int main () {
    int zahl = 5;
    zahlenaendern(&zahl);
    printf("Ausgabe: %d",zahl);
    return 0;
    }



  • Wutz schrieb:

    Irgendein Dorftrottel findet sich immer.

    Was du mit deinen Beiträgen immer wieder bestätigst!
    🙂



  • Deppen wie du sollen die Klappe halten, weil sie weder Ahnung von C noch von Wissenvermittlung an Anfänger haben.


  • Mod

    Bitte Codetags benutzen!

    Cobain schrieb:

    void zahlenausgabe(int n) {
    printf("Ausgabe: %d",n);
    }

    int main () {
    int zahl = 5;
    return 0;
    }

    Hast du dies mal ausprobiert? Es ist wichtig, dass du auch prüfst, ob deine Programme funktionieren. Einfach irgendetwas hinklatschen, das ein paar Elemente von dem enthält, was du für relevant hältst, ist nicht ausreichend. Besonders da du offensichtlich noch Anfänger bist und das Feedback brauchst.

    void zahlenausgabe(int *n) {
    *n = 10;
    }

    int main () {
    int zahl = 5;
    zahlenaendern(&zahl);
    printf("Ausgabe: %d",zahl);
    return 0;
    }

    Jetzt vergleiche das mal mit dem, was du in deinem anderen Programm gemacht hast. Dort heißt der Parameter innerhalb der Funktion s statt n . Du veränderst s . Guck mal, was du hier veränderst. Du veränderst nicht n . Du veränderst *n . Ein wichtiger Unterschied.



  • Ich habe das nun mal verändert, aber es werden mir nun mehrere Fehler angezeigt worauf Bezug auf den Pointer genommen wird.

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    char *markText(char *s, char sel) {
    
    char ubergabe[17];   
    
    int i;
    int m;
    
        for(i=0,m=0; i<12; ++i,++m) {
    
            if(s[i]==sel) {
                ubergabe[m] = '_' ;
                ++m;
                ubergabe[m] = s[i];
                ++m;
                ubergabe[m] = '_' ;
                printf("Ausgabe m gleich: %d \n", m);
            }
    
            if(s[i]!=sel) {
                ubergabe[m] = s[i];
                printf("Ausgabe m ungleich: %d \n", m);
    
            }
    
        }   
    
        *s = ubergabe;
    
        printf("\n\nAusgabe: %s \n\n", ubergabe);
    
    }
    
    int main () {
    
    char ArrayA[] = "Hello World!";
    char zeichen = 'l';
    
    *markText(&ArrayA,zeichen);
    
    printf("\n\nAusgabe: %s \n\n", ArrayA);
    
    return 0;
    
    }
    

    Die Fehlermedlung :

    main.c: In function 'markText':
    main.c:33:8: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
    *s = ubergabe;
    ^
    main.c: In function 'main':
    main.c:48:11: warning: passing argument 1 of 'markText' from incompatible pointer type [-Wincompatible-pointer-types]
    *markText(&ArrayA,zeichen);
    ^
    main.c:5:7: note: expected 'char ' but argument is of type 'char ()[13]'
    char *markText(char *s, char sel) {


Anmelden zum Antworten