char



  • Frank Erdorf schrieb:

    schreib so etwas doch in c Forum,
    da wird dir bestimmt geholfen ...

    Die werden sich fragen, was cout ist und warum es um y++ geshiftet werden soll ...



  • char x[5]="Test";

    ich dachte mal x ist auch ein zeiger 😞



  • blurry333 schrieb:

    ich dachte mal x ist auch ein zeiger 😞

    x kann (implizit) in einen Zeiger konvertiert werden, ist aber ein Array.



  • Eigentlich ist x ein zeiger auf x[0], oder?

    lg, freakC++



  • Und zum Beispiel mit dem Affen:

    #include <iostream>
    using namespace std;
    
    int main()
    {
    	char x[5]="Affe"; 
    	char* y = x;
    
    	cout << *(y+1);
    
    	return 0; // ;)
    }
    

    Da hast Du dein "f".
    lg, freakC++



  • freakC++ schrieb:

    Eigentlich ist x ein zeiger auf x[0], oder?

    lg, freakC++

    liest du auch manchmal antworten?



  • Eigentlich schon? Hab ich was überlesen 😃 :D?

    lg, freakC++

    PS.: Ich lese sie besser nochmal!

    edit: Meinst Du die Antwort von drakon? Ich wollte hervorheben, dass es ein Zeiger auf x[0] ist!?! Nunja, ich möchte nicht unangenehm auffallen 🙄 - sry



  • freakC++ schrieb:

    Eigentlich schon? Hab ich was überlesen 😃 :D?

    lg, freakC++

    PS.: Ich lese sie besser nochmal!

    edit: Meinst Du die Antwort von drakon? Ich wollte hervorheben, dass es ein Zeiger auf x[0] ist!?! Nunja, ich möchte nicht unangenehm auffallen 🙄 - sry

    x lässt sich in einen Zeiger auf x[0] konvertieren ja, aber er ist es nicht von Anfang an. Das siehst du am unterschiedlichen Verhalten, wenn du einen Zeiger inkrementierst und wenn du versuchst ein Array zu inkrementieren. Du wirst einen grossen Unterschied feststellen und dir beweisen, dass es nicht das gleiche ist.



  • blurry333 schrieb:

    char x[5]="Test";

    ich dachte mal x ist auch ein zeiger 😞

    Mal ein paar basics:

    type *x;
    

    Das deklariert einen Zeiger. Der Inhalt der Variable ist eine Adresse.

    type x[10];
    

    Das deklariert ein Array mit 10 Elementen. x alleine ist kein Zeiger sondern eine Adresse.

    type x( type *ptr ];
    

    Hiermnit deklariert Du eine Funktion, die als einzigen Parameter eine Adresse haben will. ptr ist dann eine lokale Zeigervariable, die beijm Aufruf der Funktion die übergebene Adresse zum Inhalt hat.

    Aufgerufen werden kann sie so, indem Du ihr eine Adresse oder den Inhalt einer Zeigervariable übergibst:

    type array[19];
      type *pointer = array;
    
      x( array );     // übergabe einer adresse
      x( pointer );   // übergabe des Inhalts eines Zeigers
    

    Das ist der Grund weshalb viele meinen array und pointer sei das gleiche, Falsch!!!!!

    mfg Martin



  • @drakon: Zitat aus dem Buch "C++ lernen und professionell anwenden".

    char stadt[] = "München";
    

    "Dann ist stadt ein char-Zeiger auf stadt[0]..."

    Vielleicht verstehe ich das falsch oder mein Buch hat einen Fehler. Deine Antwort ist aber eigentlich einleuchtend.

    edit:
    Ich habe jetzt auch gerade mal eine Frage:

    char* x = "Affe";
    cout << x << endl;
    

    x ist ein Zeiger, der laut meines Buches auf das erste Element eines Arrays zeigt und somit auf "A" zeigen müsste. Wenn ich jedoch x ausgebe, dann wird "Affe" ausgegeben und nicht "A". Warum? Das wurde zwar schon teilweise besprochen, doch das ist mir auch nicht klar.

    Könnt ihr mir da helfen?

    Dankeschön!

    lg, freakC++



  • Das ist ein Fehler in Buch.

    stadt ist ein Array von char 's.



  • Ok! Das beantwortet dann doch auch eigentlich meine nachträglich gestellte Frage?!

    lg, freakC++



  • freakC++ schrieb:

    edit:
    Ich habe jetzt auch gerade mal eine Frage:

    char* x = "Affe";
    cout << x << endl;
    

    x ist ein Zeiger, der laut meines Buches auf das erste Element eines Arrays zeigt und somit auf "A" zeigen müsste. Wenn ich jedoch x ausgebe, dann wird "Affe" ausgegeben und nicht "A". Warum? Das wurde zwar schon teilweise besprochen, doch das ist mir auch nicht klar.

    Der überladene operator<< für const char* gibt halt nicht nur das Zeichen aus, auf das x zeigt, sondern den nullterminierten String, der bei x beginnt, und das ist halt "Affe". Wenn du nur das A ausgeben willst, musst du

    cout << *x;
    

    schreiben.



  • Das stand vorher noch nicht da. 😉

    Nein das liegt daran, dass es eine Überladung für C-Strings gibt und somit der ganze string ausgegeben wird (bis zur 0 Terminierung).

    Wenn es das nicht machen würde, dann würde es dir sowieso nicht den hinter dem Zeiger gespeichertem Wert, sondern den Zeiger selbst ausgeben. Probier mal das hier:

    int n = 2;
     int* pn = &n;
     std::cout << pn;
    

    Ist also eher spezielles Verhalten eben weil man da weiss, dass es ein C-String sein soll.



  • Ahh..überladener Operator! Das sagt alles 😉

    Verstanden!

    Vielen Dank
    lg, freakC++



  • #include <iostream>
    #include <malloc.h>
    using namespace std;
    
    char* strstr(char str[],char substr[]) 
    {
    
    	int i=0,j=0;char tmp[100]={};
             int var=0,k=0,m=0;
    
         while(str[k])  
    	 {
    
    			if(str[k]==substr[j])
    			{
    
    		    for(j=0;substr[j] && (str[k+j]==substr[j]);j++);
    
    			if(!substr[j]) k+=strlen(substr);
    			j=0;
    
    			}
    
          tmp[m]=str[k];m++;k++;
    
    	 }
    
    	 tmp[m]=0;
    
    	 return tmp;
    
    }
    
    int main() 
    { 
    
    char* y="hallo du alter , alt sein ist gut"; 
    
    char* x="alt"; 
    
    cout<<strstr(y,x);  //Ausgabe stimmt noch nicht
    
    }
    

    also meine Funktion schneidet jetzt das Wort "alt" aus dem STring raus.
    Nur leider klappt die Ausgabe nicht?



  • Wie schon gesagt,

    das ist ein ansi c thema,
    mit c++ löst man soetwas anders.
    Nur weil cout verwendet wird ist das noch lange kein c++.
    Zumindest sehe ich das so.

    Wobei sich mir der Sinn des Auscheidens und Zurückgeben nicht wirklich erschließt.
    Die Funktion strstr gibt es schon, funktioniert aber leicht anders ...
    http://www.cplusplus.com/reference/clibrary/cstring/strstr/

    Wie auch immer eine (unnötige) temporäre Variable auf den Stack zu legen
    und dann zu returnen, wobei ja gerade der Stack abgeräumt wird
    ist keine gute Idee. Die Ausgabe ist undefiniert.

    Alternativ (aber wozu?):

    char* stringFind (char* str, char substr)
    {
        return strstr(str, substr) ? substr : "";
    }
    

    Gruß Frank



  • Hallo,
    ich verstehe deinen Satz nicht. Was soll den dabei rauskommen? Das Problem hat Frank Erdorf schon angesprochen. Da Du einen Zeiger auf tmp zurückgibst, muss dieses Array static sein. Sonst funktioniert nichts:

    char* strstr(char str[],char substr[]) 
    { 
    
        int i, j, var, k, m;
    	i = j = var = k = m = 0; 
    	static char tmp[100]={}; //Da du einen Zeiger zurückgibst, ist das static hier Pflicht!
        //...
    }
    

    lg, freakC++


  • Mod

    freakC++ schrieb:

    Hallo,
    ich verstehe deinen Satz nicht. Was soll den dabei rauskommen? Das Problem hat Frank Erdorf schon angesprochen. Da Du einen Zeiger auf tmp zurückgibst, muss dieses Array static sein. Sonst funktioniert nichts:

    Das Problem durch static zu lösen, verschiebt das Problem nur. Dadurch folgt eine ganze Kaskade weiterer Fehlerquellen, weil man hier eine Funktion mit extremen Nebeneffekten baut.

    Besser wäre es, es so zu machen wie die C Standardbibliothek es für C-Strings vormacht: Übergabe eines Zielarrays über die Parameterliste in welches dann geschrieben wird und für welches der Nutzer Sorge zu tragen hat:
    char* strstr(char str[],char substr[], char destination[])
    Hierbei wird als Returnwert destination benutzt. Wobei dies nur Geschmackssache ist, die ich aus Konsistenzgründen zur C-Standardbibliothek beibehalten habe. Auf diese Weise kann sich der Benutzer entscheiden, ob er lieber den Stil per Rückgabewert mag oder lieber den Stil mit Call by Reference.



  • Die von SeppJ angesprochenenden Mängel stimmen schon. Doch das ist hier der Grund, warum das gepostete Programm nicht funktioniert. Es gibt jedoch tatsächlich noch bessere Lösungen, auch da so leicht Speichermüll entstehen kann, wenn der Zeiger auf das static Objekt mal verloren gehen sollte.

    lg, freakC++


Anmelden zum Antworten