Speicheradressen von Großbuchstaben - gelöst



  • silent_max schrieb:

    Was ist denn jetzt eigentlich Sache?? Die vergangenen Tage hieß es, ich soll so viel wie möglich std::string benutzen und jetzt heißt es, dass ich char nehmen soll...

    Das glaube ich nicht. Es gibt einige Unterschide zwischen char[20] , std::string , char* und char . Tut mir leid, wir konnen dir nur Dinge sagen, das Verstehen koennen wir dir nicht abnehmen. Das musst du selbst, in erster Linie durch Denken. Aber nicht im Sinne von Ausdenken sondern von Nachdenken (schon wieder ein Unterschied). Woruber nachdenken? Ueber Dinge die da sind, z.B. ueber Typen wie int, char, float. Und wenn in isupper als Parameter ein char verlangt wird, aber std::string benutzt werden soll, stellt sich die Frage: Ist ein char ein std::string bzw. kann dieser automatisch umgewandelt werden. Die Antwort hierauf ist: Nein! Also kann isupper nicht direkt mit std::string benutzt werden. Trotzdem kann dein Problem geloest werden. Wie? Frage bitte nochmal, wenn du die Grundlagen verstanden hast.

    PS: Ist dieser Beitrag gemein oder arrogant? Vielleicht. Aber Gemeinheiten oder Hochnaesigkeit war nicht meine Absicht.



  • Sorry, aber wir nehmen im Fach Datenverarbeitungstechnik die Programmiersprache C++ durch.

    Wir hatten im ersten Jahr der Technikerschule die Programmiersprache C.

    Vielleicht will der Lehrer, dass wir die Programmiersprache C nicht ganz vergessen. Ich weiß jedoch nicht genau, warum unser Lehrer uns die Aufgabe gegeben hat.

    Ich versuche nur, die Aufgabe in C++ zu machen, mehr nicht.



  • knivil schrieb:

    PS: Ist dieser Beitrag gemein oder arrogant? Vielleicht. Aber Gemeinheiten oder Hochnaesigkeit war nicht meine Absicht.

    Ich finde Deinen Beitrag weder gemein, arrogant noch hochnäsig. Du wirst wahrscheinlich das geschrieben haben, was Du Dir gedacht hast.

    Dennoch hätte ich noch eine Frage.

    Ich habe folgenden Code geschrieben:

    #include <iostream>
    #include <string>
    #include <local>
    #include <ctype.h>
    #include <stdio.h>
    using namespace std;
    
    int main()
    {
    	char Text[500000]="";
    	char *pText = &Text[500000];
    	char c;
    	char *p = &c;
    	int i=0;
    
    	cout << "Geben Sie einen Text ein!\n";
    	gets(Text);
    	cout << "\n";
    	cout << "Das haben Sie eingegeben:\n";
    	cout << Text;
    	cout << "\n";
    	cout << "Speicheradresse des Strings: " << &Text << "\n";
    	cout << "\n";
    
    	while(Text[i])
    	{
    		c=Text[i];
    		if(isupper(c)) c = tolower(c);
    		putchar(c);
    		i++;
    	}
    
    	cout << c << "\n";
    	cout << &c << "\n";
    	return 0;
    }
    

    Dabei ist mir in der Ausgabe folgendes aufgefallen:
    Aus "Hallo" macht er mir "hallo" und bei der ausgabe der Speicheradresse bekomme ich nur kryptische Zeichen.

    Woran liegt das? Ich dachte, ich hätte das Codebeispiel von http://www.cplusplus.com/reference/cctype/isupper/ auf mein Problem richtig angewendet.

    Hättet ihr vielleicht einen Tipp, wie ich die Speicheradresse der Großbuchstaben auslesen kann?



  • silent_max schrieb:

    Ich weiß jedoch nicht genau, warum unser Lehrer uns die Aufgabe gegeben hat.

    Da du sehr große Probleme hast die Aufgabe umzusetzen, ist sie sicher nicht verkehrt.

    Fehlermeldungen haben meist auch eien Angabe über die Zeile (und manche auch Spalte), wo der Fehler auftritt. Da sollte man mal nachsehen.

    Du weißt immer noch nicht was das bedeutet:

    char Text[]="";
        char *pText = &Text;
    

    Aber zumindest ist es Mist.
    Arrays haben eine feste Länge, die ist bei dir durch den Leerstring auf 1 (eins) festgesetzt.
    Der Name des Arrays steht schon für deie Anfangsadresse. Darum kommt da auch kein & mehr hin.

    Wo kommt das i auf einmal her?

    Und was hat der Codde mit der Frage aus dem Titel zu tun?
    Der gibt (wenn er läuft) den Text in Kleinbuchstaben aus.



  • DirkB schrieb:

    Arrays haben eine feste Länge, die ist bei dir durch den Leerstring auf 1 (eins) festgesetzt.
    Der Name des Arrays steht schon für deie Anfangsadresse. Darum kommt da auch kein & mehr hin.

    Warum auf 1??

    Ich wollte durch

    char Text[500000] = "";
    

    eigentlich bezwecken, dass man einen beliebig langen Text eingeben kann.



  • silent_max schrieb:

    Aus "Hallo" macht er mir "hallo"

    Joa, is ja richtig.

    silent_max schrieb:

    und bei der ausgabe der Speicheradresse bekomme ich nur kryptische Zeichen.

    Ja, da ist der Ausgabeoperator ein bisschen doof. Weil an dieser Stelle ein char liegt, denkt er da kommt nun eine Zeichenkette. Mach mal cout << reinterpret_cast<void*>(&c)



  • Ok, war eine zeitliche Überschneidung.

    500000 ist etwas übertrieben.
    Das Element mit dem Index Text[500000] existiert nicht. Also ist die Adresse davon auch nicht gültig. Aber die benutzt du ja auch nicht weiter.

    In Zeile 34 bekommt cout einen Zeiger auf char. Der wird als Nullterminierte Zeichenkette aufgefasst.
    Ist es aber nicht, da du nur ein einzelnes Zeichen hast.



  • out schrieb:

    Ja, da ist der Ausgabeoperator ein bisschen doof. Weil an dieser Stelle ein char liegt, denkt er da kommt nun eine Zeichenkette. Mach mal cout << reinterpret_cast<void*>(&c)

    Jetzt gibt es nur noch einen Schönheitsfehler:

    Wenn ich jetzt meinen Vornamen, Maximilian, eingebe, wird mir folgendes Ausgegeben:

    004A5C2F
    M004A5C2F
    a004A5C2F
    x004A5C2F
    i004A5C2F
    m004A5C2F
    i004A5C2F
    l004A5C2F
    i004A5C2F
    a004A5C2F
    n

    Wie kann ich denn das so verändern, dass mir für das letzt n die Speicheradresse ausgelesen wird?

    Hier der Code, um den es geht:

    while(Text[i])
    	{
    		c=Text[i];
    		if(isupper(Text[i]));
    		cout << reinterpret_cast<void*>(&c) << "\n";
    		putchar(c);
    		i++;
    	}
    


  • Jetzt bekomme ich komischerweise folgende Fehlermeldung:

    fatal error LNK1168: "D:\Sebastian\eigene Dokumente\Visual Studio 2010\Projects\CPP Programmierung\Debug\Eigene Übung 088 - Pointer auf Großbuchstaben.exe" kann nicht zum Schreiben geöffnet werden.
    

    Hier nochmal der ganze Code:

    #include <iostream>
    #include <string>
    #include <ctype.h>
    #include <stdio.h>
    #include <locale>
    using namespace std;
    
    int main()
    {
    	char Text[500000]="";
    	char *pText = &Text[500000];
    	char c;
    	char *p = &c;
    	int i=0;
    
    	cout << "Geben Sie einen Text ein!\n";
    	gets(Text);
    	cout << "\n";
    	cout << "Das haben Sie eingegeben:\n";
    	cout << Text;
    	cout << "\n";
    	cout << "Speicheradresse des Strings: " << &Text << "\n";
    	cout << "\n";
    
    	while(Text[i])
    	{
    		c=Text[i];
    		if(isupper(Text[i]));
    		cout << reinterpret_cast<void*>(&c) << "\n";
    		putchar(c);
    		i++;
    	}
    
    	cout << c << "\n";
    	return 0;
    }
    


  • silent_max schrieb:

    Wie kann ich denn das so verändern, dass mir für das letzt n die Speicheradresse ausgelesen wird?

    Die steht doch da.

    Allerdings hast du

    cout << reinterpret_cast<void*>(&c) << "\n";  // Adresse und Newline ausgeben
            putchar(c);  // Zeichen ausgeben
    

    Wo steht jetzt die Adresse für dein Zeichen?

    Was soll eigentlich das ; in Zeile 4 ?



  • silent_max schrieb:

    Jetzt bekomme ich komischerweise folgende Fehlermeldung:

    fatal error LNK1168: "D:\Sebastian\eigene Dokumente\Visual Studio 2010\Projects\CPP Programmierung\Debug\Eigene Übung 088 - Pointer auf Großbuchstaben.exe" kann nicht zum Schreiben geöffnet werden.
    

    Dann beende doch erst mal den vorhergehenden Testlauf.

    Der Compiler/Linker kann deine Exe nicht überschreiben, da sie noch ausgeführt wird.



  • Warum wird jetzt die Speicheradresse vom letzten Buchstaben ausgegeben, wenn ich die Speicheradresse vom ersten Buchstaben will?



  • silent_max schrieb:

    Warum wird jetzt die Speicheradresse vom letzten Buchstaben ausgegeben, wenn ich die Speicheradresse vom ersten Buchstaben will?

    Dann hast du das so programmiert.
    Der Compiler macht das, was du schreibst und nicht das was du willst.

    Nochmal:
    Das if in Zeile 28 hat keinen Effekt weil:

    DirkB schrieb:

    Was soll eigentlich das ; in Zeile 4 (jetzt 28)?



  • silent_max schrieb:

    Warum wird jetzt die Speicheradresse vom letzten Buchstaben ausgegeben, wenn ich die Speicheradresse vom ersten Buchstaben will?

    lass mich raten: mit dem Wörtchen "Debugger" kannst du immer noch nichts anfangen?



  • Ich habe es gerade mit´m Debugger angeschaut.

    Wenn ich das Wort "Hallo" eingebe, dann ist ja das "o" das letzte Zeichen, das die while-Schleife ausgibt.

    Also muss ich doch die While Schleife raushauen oder wie seht ihr das?



  • Sehr schlaue Idee ihm einzutrichtern so ein dummes char array anstatt std::string zu verwenden .... nicht.

    std::strings iterierst du am allereinfachsten so:

    std::string s = "HansWurst";
    for(std::size_t i = 0; i < s.length(); ++i)
    {
        char& c = s[i];
    
        ....
    }
    


  • Dabei braucht man nicht einmal eine while Schleife.

    Siehe hier:

    #include <iostream>
    #include <string>
    #include <ctype.h>
    #include <stdio.h>
    #include <locale>
    using namespace std;
    
    int main()
    {
    	char Text[20]="";
    	char *pText = &Text[20];
    	char c;
    	char *p = &c;
    	int i=0;
    
    	cout << "Geben Sie einen Text ein!\n";
    	gets(Text);
    	cout << "\n";
    	cout << "Das haben Sie eingegeben:\n";
    	cout << Text;
    	cout << "\n";
    	cout << "Speicheradresse des Strings: " << &Text << "\n";
    	cout << "\n";
    
    	c=Text[i];
    	if(isupper(Text[i]))
    	{
    		cout << "Erstes Zeichen von Hallo ist ein Grossbuchstabe\n";
    		cout << "Speicheradresse des ersten Buchstaben:" << reinterpret_cast<void*>(&c) << c <<  "\n";
    	}
    	return 0;
    }
    


  • Wenn dich nur das erste Zeichen interessiert brauchst du keine Schleife.
    Ansonsten brauchst du eine Schleife um den String zu iterieren und jedes Zeichen einzeln anzusehen, wie zb in meinem Post skizziert.



  • silent_max schrieb:

    Ich habe folgende Aufgabe zu lösen:

    Schreiben Sie folgendes Programm so um, dass die Speicheradresse des Textes und die Speicheradresse der jeweiligen Grossbuchstaben ausgegeben wird.

    Das ist echt nicht schön fomuliert. Großbuchstaben haben keine Adressen. Die Speicherstellen, in denen du z.B. Großbuchstaben in Form von char-Werten ablegen kannst, haben Adressen.

    silent_max schrieb:

    Siehe hier:

    #include <iostream>
    #include <string>
    #include <ctype.h>
    #include <stdio.h>
    #include <locale>
    using namespace std;
    
    int main()
    {
    	char Text[20]="";
    	char *pText = &Text[20];
    	char c;
    	char *p = &c;
    	int i=0;
    
    	cout << "Geben Sie einen Text ein!\n";
    	gets(Text);
    	cout << "\n";
    	cout << "Das haben Sie eingegeben:\n";
    	cout << Text;
    	cout << "\n";
    	cout << "Speicheradresse des Strings: " << &Text << "\n";
    	cout << "\n";
    
    	c=Text[i];
    	if(isupper(Text[i]))
    	{
    		cout << "Erstes Zeichen von Hallo ist ein Grossbuchstabe\n";
    		cout << "Speicheradresse des ersten Buchstaben:" << reinterpret_cast<void*>(&c) << c <<  "\n";
    	}
    	return 0;
    }
    

    Ich hoffe du weißt, dass gets so in Verbindung mit char-Arrays unsicher ist. Unsicher in dem Sinne, dass der Benutzer eine längere Zeichenkette eingeben kann und damit über das Ende des char-Arrays hinausgeschrieben werden kann. Das nennt man Buffer Overflow und so etwas darf einfach nicht sein, in einem Programm. Ob es nur eine kleine Übung oder ein "ernstes" Programm ist. Das hat einfach in keinem Programm etwas zu suchen, egal wie klein; denn so lernst du es ja nicht richtig.

    Warum verwendest du nicht std::string für Text? Dann hast du das Buffer Overflow Problem nämlich nicht mehr.

    Was ist der Sinn von pText? Das verwendest Du ja nirgens.

    du gibts hier die Adresse von c aus, keine Adresse eines Elements des "Strings". Ich glaube nicht, dass das Sinn der Sache ist.



  • Auch falsch.
    Du gibst du die Adresse der Variablen c aus. Und die liegt nicht innerhalb von Text.

    Du brauchst die Schleife.

    Denn es sollen ja die Adressen (der Speicherstellen 🙄 ) von allen Großbuchstaben ausgegeben werden.
    Und wenn du jetzt "van Andern" eingibst, ......

    Weißt du jetzt wofür du das Semikolon da eingbaut hast?
    Nein? Dann lass es doch mal weg.


Anmelden zum Antworten