0

I'm writing C++ code in order to practice and learn for myself only. But I am having trouble instantiating one of my custom objects.

I'll try to be brief in my explanation here (but also trying not to miss necessary details): Game is Text-Only. Dungeon class is the class I have trouble creating instance of. I also have a 'Game' class (when the Game class is instantiated, the results are as I expected).

In my Dungeon constructor I put a cout with some log info. But it never prints. However the initialization code within the same code block all appears to have happened. (I know this because if I call a function to print the value of one of its variables I can see that it has indeed been populated with the data).

(The line inside the Game() constructor which calls the Debug_PrintRaw() function, this gives the desired result which implies to me that the constructor Dungeon(string filename) is called, because the string is converted from the file at that moment and it has worked the full string (the contents of the file) are printed. But none of the LOG parts are printed. (I expected them to get printed as soon as the game starts, since at the moment Game is spawned, it should spawn a Dungeon also.

So the total project code isn't too large, its just started so I will post it all here (the code is probably very stupid and overblown because I don't always know what I am doing!):

(thanks for any help)

//MAIN.CPP
#include "Game.h"

Game game = Game();
bool quit_game = 0;

int main()
{
    while (!quit_game)
    {

    }
    return 0;
}
//GAME.H
#pragma once
#include "Dungeon.h"
#include "Player.h"

class Game
{
public:
    Game();
    Dungeon currentDungeon = Dungeon("Dungeons/dungeon1.txt");
    void ClearScreen();
    void ShowSplashScreen();
};
//GAME.CPP
#include "Game.h"
#include <iostream>

Game::Game()
{
    ShowSplashScreen();

    currentDungeon.Debug_PrintRaw(); //<- with this line included, we do get the desired string printed
}

void Game::ClearScreen()
{
    std::cout << "" << std::endl;
    system("cls");
}

void Game::ShowSplashScreen()
{
    ClearScreen();
    std::cout << "                         :: ::::: ::" << std::endl;
    std::cout << "                         :: ::::: ::" << std::endl;
    std::cout << "                         :: ::::: ::" << std::endl;
    std::cout << "                         :: ::::: ::" << std::endl << std::endl << std::endl;

    std::cout << "                        .:: ::::: ::." << std::endl;
    std::cout << "                       .::: ::::: :::." << std::endl;
    std::cout << "                      .:::' ::::: ':::." << std::endl;
    std::cout << "                     .::::' ::::: '::::." << std::endl;
    std::cout << "                    .::::'  :::::  '::::." << std::endl;
    std::cout << "                  .:::::'   :::::   ':::::." << std::endl;
    std::cout << "                .::::::'    :::::    '::::::." << std::endl;
    std::cout << "           ...:::::::'      :::::      ':::::::..." << std::endl;
    std::cout << "           :::::::''        :::::        '':::::::" << std::endl;
    std::cout << "           ::::''           :::::           ''::::" << std::endl;



    std::cout << "~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~" << std::endl;
    std::cout << "                        fAtari Games                        " << std::endl;
    std::cout << "~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~" << std::endl;
}

//DUNGEON.H
#pragma once

#include <vector>
#include "RoomData.h"


class Dungeon
{
public:
    Dungeon(std::string filename);
    std::string rawLevelText;
    std::vector<RoomData> rooms;

    void Debug_PrintRaw();
};


//DUNGEON.CPP
#include "Dungeon.h"
#include <fstream>
#include <sstream>
#include <iostream>

Dungeon::Dungeon(std::string filename)
{
    std::cout << "LOG: Dungeon Constructor" << std::endl;

    std::ifstream file(filename);
    std::stringstream buffer;
    buffer << file.rdbuf();

    rawLevelText = buffer.str();

    Debug_PrintRaw();
}

void Dungeon::Debug_PrintRaw()
{
    std::cout << "LOG: Dungeon PrintRaw Called." << std::endl;
    std::cout << rawLevelText << std::endl;
}

Weather Vane
  • 33,872
  • 7
  • 36
  • 56
I_Keep_Trying
  • 395
  • 3
  • 17
  • 1
    Are you sure that your Dungeon log statement isn't getting printed and then immediately cleared by the call to `ClearScreen` in `ShowSplashScreen` in `Game`'s constructor? – Nathan Pierson Aug 19 '21 at 19:08
  • OMG lol (how can i do embarassed emoji in font lol). I think this has solved my 'problem' :D – I_Keep_Trying Aug 19 '21 at 19:10
  • awesome now I can stop worry about this imaginary problem i found.... on to the next one :D . If you want to write as answer I can properly accept it as the answer (or I can just delete question if you prefer). Thanks for your help – I_Keep_Trying Aug 19 '21 at 19:13
  • If you understand the solution and can make a good write up explaining what went wrong and how the solution fixed it and believe your mistake can help future programmers, prefer to self answer. Suggestion: Dump the log to a file rather than the console. You're already using the console for the game, so the less clutter the better. If your system has [a `tail` command](https://www.freebsd.org/cgi/man.cgi?query=tail) or something like it, you can monitor the logfile in one console while running the game uninterrupted in another console. – user4581301 Aug 19 '21 at 19:57
  • Plus the log is preserved in the file so if you have to go back to see if you missed something, you can. – user4581301 Aug 19 '21 at 19:59
  • Thanks User. Great minds think alike haha. Just been working on `ofstream` and making a log output. Its working great. But Im currently a little stuck using `ctime_s` just because I want to add time to all my log statements haha. What fun – I_Keep_Trying Aug 19 '21 at 19:59
  • Really appreciate all the help guys. I am going to 'self answer' this question in a moment. Even though the question is very silly really because it was working all along and I was just clearing all my notes. But its nice to learn the reason for making an actual log file first hand (ie. By slipping up in this way) – I_Keep_Trying Aug 19 '21 at 20:00
  • If your compiler is up to date, [use this stuff](https://stackoverflow.com/a/12844843/4581301) instead of calling down into the C time formatting functions. As you'll see in the linked answer Mr. Hinnant's been hard at work making this stuff easier and easier and by C++20, it's pretty much idiotically simple. – user4581301 Aug 19 '21 at 20:25
  • nice link, thanks. I've actually managed it so far and using `ctime_s`, but one last problem I am working on is avoiding the newline the ctime seems to be adding into the logs. But other than that its working sweet. – I_Keep_Trying Aug 19 '21 at 20:28
  • You can also log your stuff to `std::cerr`, the standard error stream which is often used for logging. This would allow you to redirect just that output to a file `./my_program 2>log_file.txt` and then `tail` it from somewhere else – Ryan Haining Aug 19 '21 at 20:54
  • Thanks Ryan I will be sure to read up on that soon. – I_Keep_Trying Aug 19 '21 at 21:03

1 Answers1

1

OK well the answer turned out to be simple. As per the comments I was clearing the screen and hence my outputs with "LOG: xxxxx" were being cleared with it. I was stupidly expecting to magically still see them.

So the simple fix was not to clear the screen, then I could see all the log.

But of course I want to be able to clear the screen also, so this highlights to me the need for some output 'log' file(s). So the simple fix becomes a new can of worms ;)

Well I am very much a noobie and this is just how I personally implemented that logfile output. This consists of (optionally) getting the date/time using ctime_s, as well as using #include <fstream>

In the Game.h I added this variable and function:

std::ofstream log_debug
void WriteToLog_Debug(std::string);

in Game.cpp they are implemented as follows:

Game::Game()
{
   log_debug = std::ofstream("give_it_any_file_name.txt");
   WriteToLog_Debug("Log file created");
}

void Game::WriteToLog_Debug(std::string message)
{
    time_t t = time(NULL);
    char timeStr[26];
    ctime_s(timeStr, sizeof(timeStr), &t);

    timeStr[sizeof(timeStr) -2] = '\0';
    log_debug << timeStr << ":    " << message << std::endl;
}

The function looks a little complicated but much of that is just getting the time, and then removing the newline char from that string it gives us.

I hope this might help someone who reads this some day. :D Have fun

I_Keep_Trying
  • 395
  • 3
  • 17