Hilfe in c++



  • Also ich habe gestern angefangen ein bisschen mit c++ zu programmieren und bin so weit gut gekommen... nur habe ich jetzt ein problem:

    main.cpp:

    #include <iostream>
    #include "windows.h"
    #include <stdlib.h>
    #include "stdlib.h"
    #include "Player.hpp"
    
    using namespace std;
    
    int main()
    {
    	Player player;
    
    	player.run();
    
    	return 0;
    }
    

    Player.hpp:

    #ifndef PLAYER_HPP
    #define PLAYER_HPP
    
    class Player
    {
    
    public:
    	Player();
    	~Player();
    
    	void run();
    
    private:
    
    	char *pMap[11][15];
    	void getKey();
    	void map();
    
    	bool game_running;
    
    	int x;
    	int y;
    
    	void sp(int choosecolor);
    	void clearscreen();
    	void s();
    
    };
    
    #endif
    

    Player.cpp:

    #include "Player.hpp"
    #include <iostream>
    #include "windows.h"
    #include <stdlib.h>
    #include "stdlib.h"
    
    Player::Player()
    {
    	game_running = true;
    
    	y = 8;
    	x = 4;
    
    	pMap[11][15] =
    
    	"ÉÍÍÍÍÍ»",
    	"º     º",
    	"º     º",
    	"º     º",
    	"º     º",
    	"º     º",
    	"º     º",
    	"º     º",
    	"º  @  º",
    	"ÈÍÍÍÍͼ";
    
    }
    
    Player::~Player()
    {
    
    }
    
    void Player::run()
    {
    	while(game_running == true)
    	{
    		clearscreen();
    		map();
    		getKey();
    
    	}
    }
    
    void Player::map()
    {
    	for(int i = 0; i < 10; i++)
    		{
    			sp(697);
    			std::cout << pMap[i] << std::endl;
    			s();
    		}
    	system("pause>nul");
    }
    
    void Player::getKey()
    {
    	if(GetAsyncKeyState(VK_LEFT))
    		{
    			if( *pMap[y][x-1] == ' ')
    			{
    				*pMap[y][x] = ' ';
    				x--;
    				*pMap[y][x] = '@';
    			}
    		}
    	if(GetAsyncKeyState(VK_RIGHT))
    		{
    			if( *pMap[y][x+1] == ' ')
    			{
    				*pMap[y][x] = ' ';
    				x++;
    				*pMap[y][x] = '@';
    			}
    		}
    	if(GetAsyncKeyState(VK_ESCAPE))
    	{
    		game_running = false;
    
    		exit;
    	}
    
    }
    
    void Player::sp(int choosecolor)
    {
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), choosecolor);
    }
    
    void Player::clearscreen()
    {
        HANDLE hOut;
        COORD Position;
    
        hOut = GetStdHandle(STD_OUTPUT_HANDLE);
    
        Position.X = 0;
        Position.Y = 0;
        SetConsoleCursorPosition(hOut, Position);
    }
    
    void Player::s()
    {
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
    }
    

    Wenn ich das compiliere dann kommt nicht die "map" raus die ich vorgesehen hatte sondern eifnach so buchstaben mit zahlen... und die ändern sich bei jedem start des programms.. kann mir da einer helfen ? bin eig noch ziemlich am anfang bzw bin neuling in c++ .. könnte ja mal einer versuchen zu kompilen und schauen ob es vllt an meinem pc liegt... weil error meldungen bekomme ich keine... naja hoffe mir kann da einer helfen 🙂

    und nebenbei .. ich kann im moment leider keine youtube videos/tutorials anschauen da ich im moment kein internet habe weil wir da grad neue leitungen bekommen.. ka.. ich schreib das hier grad über mein handy internet/hotspot 🙂



  • Nun die Tutorials/Videos die du verwendet hast sind scheinbar nicht so toll.
    Denn sonst wüsstest du, dass du ein Stringliteral nicht verändern kannst, was du aber in getKey tust. Da sollte auch sogar eine Warnung kommen, dreh mal dein Warnlevel höher.



  • Nathan schrieb:

    Nun die Tutorials/Videos die du verwendet hast sind scheinbar nicht so toll.
    Denn sonst wüsstest du, dass du ein Stringliteral nicht verändern kannst, was du aber in getKey tust. Da sollte auch sogar eine Warnung kommen, dreh mal dein Warnlevel höher.

    Was ist denn ich "Stringliteral" und wieso kann ich den nicht verändern ? Der fehler liegt beim anzeigen der "map" .. nicht beim "GetKey" denn das hat funktioniert ... kannst du ja auch mal testen 😃 Zumindestens denk ich das 🙂



  • abratar schrieb:

    Nathan schrieb:

    Nun die Tutorials/Videos die du verwendet hast sind scheinbar nicht so toll.
    Denn sonst wüsstest du, dass du ein Stringliteral nicht verändern kannst, was du aber in getKey tust. Da sollte auch sogar eine Warnung kommen, dreh mal dein Warnlevel höher.

    Was ist denn ich "Stringliteral" und wieso kann ich den nicht verändern ? Der fehler liegt beim anzeigen der "map" .. nicht beim "GetKey" denn das hat funktioniert ... kannst du ja auch mal testen 😃 Zumindestens denk ich das 🙂

    Oh, stimmt, dein Code ist viel falscher als ich dachte.
    Dein Tutorial ist definitiv grottig.
    Zeile 14: Was machst du da? Tipp: Es ist undefined behavior.
    Und daraus resultierend: Auf welchen Speicher greifst in getKey zu? Tipp: Es ist wieder undefined behavior.
    Dass du überhaupt was siehst, ist ein sehr glücklicher Zufall.



  • Nathan schrieb:

    Oh, stimmt, dein Code ist viel falscher als ich dachte.
    Dein Tutorial ist definitiv grottig.
    Zeile 14: Was machst du da? Tipp: Es ist undefined behavior.
    Und daraus resultierend: Auf welchen Speicher greifst in getKey zu? Tipp: Es ist wieder undefined behavior.
    Dass du überhaupt was siehst, ist ein sehr glücklicher Zufall.

    Kannst du mir denn nicht sagen was da falsch ist ? und wie ich es verbessern kann .. weil "undefined behavior hilft mir nicht viel 😕 Meinst du zeile 14 in main.cpp ?



  • Es bezieht sich auf die Player.cpp.
    Beschreib bitte ganz genau, was du da machst und wieso du das so machst, wie du es machst.
    Das ist nämlich wieder ein typischer Fall von irgendetwas dranklatschen bis es funktioniert.



  • Dein Hauptproblem scheint *char pMap[11][15]; zu sein. Du scheinst zu meinen es würde einen Zeiger auf ein char [11][15] sein, ist es aber nicht. Stattdesses ist es ein Array von Arrays von char *. Vielleicht wolltest du auch nur den Compiler ruhig stellen, man kann in C++ so ziemlich alles mit ein paar Sternchen zum kompilieren kriegen, das macht es aber nicht richtig. pMap[0] gibt dir ein uninitialisiertes char *Array und

    pMap[11][15] =
    
        "ÉÍÍÍÍÍ»",
        "º     º",
        "º     º",
        "º     º",
        "º     º",
        "º     º",
        "º     º",
        "º     º",
        "º  @  º",
        "ÈÍÍÍÍͼ";.
    

    greift auf den nicht existenten char * pMap[11][15] zu und überschreibt ihn was dir irgendwas kaputt macht.

    Eine Möglichkeit das zu reparieren ist das * aus *char pMap[11][15]; zu entfernen und direkt zu initialisieren:

    char pMap[11][15] = {
    		"ÉÍÍÍÍÍ»",
    		"º     º",
    		"º     º",
    		"º     º",
    		"º     º",
    		"º     º",
    		"º     º",
    		"º     º",
    		"º  @  º",
    		"ÈÍÍÍÍͼ"
    	};
    

    Dann funktioniert bestimmt auch deine Ausgabe.



  • abratar schrieb:

    #include <stdlib.h> 
    #include "stdlib.h"
    

    Warum zwei mal? Verstehst du den Unterschied? Wenn du C++ machen willst, benutz cstdlib , wenn überhaupt.



  • nwp3 schrieb:

    Eine Möglichkeit das zu reparieren ist das * aus *char pMap[11][15]; zu entfernen und direkt zu initialisieren:

    char pMap[11][15] = {
    		"ÉÍÍÍÍÍ»",
    		"º     º",
    		"º     º",
    		"º     º",
    		"º     º",
    		"º     º",
    		"º     º",
    		"º     º",
    		"º  @  º",
    		"ÈÍÍÍÍͼ"
    	};
    

    Dann funktioniert bestimmt auch deine Ausgabe.

    das hatte ich schon versucht .. doch dann weiss ich nicht wie ich auf pMap zugreifen kann .. z.B. "void Player::map()" zeigt mir dann an das es pMap nicht gibt.. wie kann ich das hinbekommen dass er es findet? dachte das geht mit dem * ..



  • Nathan schrieb:

    Denn sonst wüsstest du, dass du ein Stringliteral nicht verändern kannst, was du aber in getKey tust.

    Der tut kein Stringliteral verändern, wenn den Stern weglässt wie empfohlen.



  • Das ArrayArray kannst du im Konstruktor explizit setzen:

    http://ideone.com/KohfMO



  • Wutz schrieb:

    Das ArrayArray kannst du im Konstruktor explizit setzen:

    http://ideone.com/KohfMO

    Also erstmal danke für den die hilfe 🙂
    Aber ehrlich gesagt weiss ich nicht wie ich den code bei mir reinbauen soll 😕

    könntest du mir sagen bzw. erklären was ich aus meinem code löschen und was einfügen soll ?

    Dein code sieht recht gut aus, nur versteh ich den nicht ganz
    was ist z.b. "typedef" ? wieso kann ich da nicht einfach "char" und "struct" ohne "typedef" machen ?



  • Hallo,

    wenn du einen C++11-fähigen Compiler benutzt, müßte

    char map[11][15] =
        {
            "ÉÍÍÍÍÍ»",
            "º     º",
            "º     º",
            "º     º",
            "º     º",
            "º     º",
            "º     º",
            "º     º",
            "º  @  º",
            "ÈÍÍÍÍͼ"
        };
    

    im Header (innerhalb deiner Klassendefinition) funktionieren.

    Ansonsten wird es etwas komplizierter:

    // im Header (innerhalb deiner Klasse)
    char map[11][15];
    
    // im Konstruktor
    static const char init_map[11][15] =
        {
            "ÉÍÍÍÍÍ»",
            "º     º",
            "º     º",
            "º     º",
            "º     º",
            "º     º",
            "º     º",
            "º     º",
            "º  @  º",
            "ÈÍÍÍÍͼ"
        };
    
    // Array kopieren
    memcpy(&map[0][0], &init_map[0][0], sizeof(map));
    

    PS: Warum eigentlich [11][15]? Deine Daten sind doch [10][7] groß?



  • Th69 schrieb:

    // Array kopieren
    memcpy(&map[0][0], &init_map[0][0], sizeof(map));
    [/cpp]

    PS: Warum eigentlich [11][15]? Deine Daten sind doch [10][7] groß?

    1. Ich habe Visual Studio 2010.
    2. Was genau macht "Array kopieren" ? also was wird da kopiert und wohin ? ist das die ausgabe oder wie?
    3. weil der compiler mir sagt dass wenn ich da [11][8] rein tu dass es nicht ausreicht für eine 15... keine ahnung .. sonst kompiliert der auch nicht.. wahrscheinlich zählen die zeichen bei meiner map mehr als nur 1 zeichen oder so ..



  • Gewöhne dir beim Programmdesign an, verschiedene Funktionalitäten in verschiedene Programmteile (bei C++ sinnvollerweise Klassen) zu kapseln, hier also z.B. die Nutzeraktionen und die Ausgabe, und presse nicht alles in eine Klasse.
    Dazu ist natürlich ein kompletter Überblick über die Dinge notwendig.
    Dann definierst du die Schnittstellen deiner Klassen, instanziierst die Objekte (das geschieht sinnvollerweise in main oder zumindest in ein und derselben Aufrufebene) und arbeitest vorrangig mit den Objekten und deren Schnittstellenmethoden und eben nicht mit Funktionen (Sinn der OOP).

    #include <iostream>
    #include <cstdlib>
    #include <windows.h>
    
    using namespace std;
    
    struct Brett {
      Brett::Brett() {
        x = 3; y = 8; char z[10][8] = {
          "ÉÍÍÍÍÍ»",
          "º     º",
          "º     º",
          "º     º",
          "º     º",
          "º     º",
          "º     º",
          "º     º",
          "º  @  º",
          "ÈÍÍÍÍͼ" };
    
        memcpy(pMap,z,sizeof z);
      }
      char pMap[10][8];
      int x, y;
      void left(){  if (pMap[y][x-1] == ' ')  pMap[y][x--] = ' ', pMap[y][x] = '@'; }
      void right(){ if (pMap[y][x+1] == ' ')  pMap[y][x++] = ' ', pMap[y][x] = '@'; }
      void up(){    if (pMap[y-1][x] == ' ')  pMap[y--][x] = ' ', pMap[y][x] = '@'; }
      void down(){  if (pMap[y+1][x] == ' ')  pMap[y++][x] = ' ', pMap[y][x] = '@'; }
    
      void sp(int choosecolor)
      {
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), choosecolor);
      }
      void s()
      {
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
      }
    
      void print()
      {
        for (int i = 0; i < 10; i++)
        {
          sp(697);
          cout << pMap[i] << "\n";
          s();
        }
        system("pause>nul");
      }
    };
    
    class Player
    {
      Brett *brett;
      void getKey();
      bool game_running;
    
      void clearscreen();
    
    public:
      Player(Brett&b){
        game_running = true; brett = &b;
      }
    
      void run();
    };
    
    void Player::run()
    {
      while (game_running == true)
      {
        clearscreen();
        brett->print();
        getKey();
    
      }
    }
    
    void Player::getKey()
    {
      if (GetAsyncKeyState(VK_LEFT))
      {
        brett->left();
      }
      else
      if (GetAsyncKeyState(VK_RIGHT))
      {
        brett->right();
      }
      else
      if (GetAsyncKeyState(VK_UP))
      {
        brett->up();
      }
      else
      if (GetAsyncKeyState(VK_DOWN))
      {
        brett->down();
      }
      else
      if (GetAsyncKeyState(VK_ESCAPE))
      {
        game_running = false;
    
        exit(0);
      }
    
    }
    
    void Player::clearscreen()
    {
      HANDLE hOut;
      COORD Position;
    
      hOut = GetStdHandle(STD_OUTPUT_HANDLE);
    
      Position.X = 0;
      Position.Y = 0;
      SetConsoleCursorPosition(hOut, Position);
    }
    
    int main()
    {
      Brett brett;
      Player player(brett);
      player.run();
    }
    

Anmelden zum Antworten