How to call user defined code in C++ - c++

I'm new to C++ (not programming in general, just C++) and I'm learning to program in C++ with a subscription to Pluralsight. I'm writing a practice program (a set of games through the computer's console) and I'm stuck on something. While working on a Tic-Tac-Toe game, I want to call a formula for the board that I won't have to rewrite every time. Therefore I defined a set of strings to work for me, but I cannot figure out how to call my user defined formula. I'm not going to post all of the code, because it is very long, but I will show your the parts you need (if a line has "...." on it, that means I removed multiple lines of code to make it fit better for this site). Incase you're wondering, I'm using Microsoft Visual Studio Community 2017 RC and C++14.
HEADER FILE:
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include <iostream>
#include <string>
using namespace std;
MAIN FILE:
....
#define TTTBoard () \
{ \
system("cls"); \
cout << "\n\n Let's play Tic-Tac-Toe!\n\n\n"; \
cout << " A B C " << endl; \
cout << " _______________________ " << endl; \
cout << " | | | |" << endl; \
cout << " 1 | " << PlayerSymA1 << " | " << PlayerSymB1 << " | " << PlayerSymC1 << " |" << endl; \
cout << " |_______|_______|_______|" << endl; \
cout << " | | | |" << endl; \
cout << " 2 | " << PlayerSymA2 << " | " << PlayerSymB2 << " | " << PlayerSymC2 << " |" << endl; \
cout << " |_______|_______|_______|" << endl; \
cout << " | | | |" << endl; \
cout << " 3 | " << PlayerSymA3 << " | " << PlayerSymB3 << " | " << PlayerSymC3 << " |" << endl; \
cout << " |_______|_______|_______|" << endl; \
}
....
int main()
{
//This is where I want to call my TTTBoard formula
}
I tried to call it multiple ways, but nothing worked. Below is what I already tried. I know some of what I tried didn't make complete sense, but I was annoyed that I couldn't get it to work, so I tried it all anyway.
TTTBoard
TTTBoard;
TTTBoard()
TTTBoard();
TTTBoard()
{
}
TTTBoard();
{
}
Thank you in advance for the help!!!

Preprocessor macros are not called. Instead they are expanded, meaning the body of the macro is inserted in place of the macro invocation, with arguments replaced.
So if you have a macro like
#define FOO() { \
bar(); \
}
And then using it
int main()
{
FOO()
}
What the preprocessor creates and the compiler sees is
int main()
{
{ bar(); }
}
The above example also shows how to use a function-like macro.
Lastly, you don't need macros. In a case like yours it makes much more sense to use actual functions. In modern C++ there are seldom much needs for macros.

Related

How do I stop segmentation error with array in C++?

I am creating a simple command line, tic-tac-toe game in C++. Whenever I reun the code I get no compiler errors but then VSCode tells me once I have given input that there is a Segmentation Fault. I will paste my code below:
#include <iostream>
#include <cmath>
using namespace std;
void print_board(string board[3][3])
{
cout << " | | " << endl;
cout << " " << board[0][0] << " | " << board[0][1] << " | " << board[0][2] << " " << endl;
cout << "_____|_____|_____" << endl;
cout << " | | " << endl;
cout << " " << board[1][0] << " | " << board[1][1] << " | " << board[1][2] << " " << endl;
cout << "_____|_____|_____" << endl;
cout << " | | " << endl;
cout << " " << board[2][0] << " | " << board[2][1] << " | " << board[2][2] << " " << endl;
cout << " | | " << endl;
}
string turn(string board[3][3], bool xturn)
{
int position;
cout << "Where would you like to go (1 - 9): ";
cin >> position;
if (xturn)
{
string player_turn = "X";
}
else
{
string player_turn = "O";
}
board[(int)floor(position / 3)][(position % 3) - 1] = "X";
return board[3][3];
}
int main(void)
{
string board[3][3] = {{" ", " ", " "}, {" ", " ", " "}, {" ", " ", " "}};
bool xturn = true;
while (true)
{
print_board(board);
board[3][3] = turn(board, xturn);
xturn = !xturn;
}
return 0;
}
Any help is much is much appreciated. Thanks! If it helps I am using the GCC compiler.
void print_board(string board[3][3])
why are you using a string[3][3] ? you basically just need a 3x3 character array
board[(int)floor(position / 3)][(position % 3) - 1] = "X";
make sure you keep yourself in range 0..2, -1 is outside and will
cause undefined behavior
return board[3][3];
No that is wrong in more ways than one, and in any case there is no need to return a copy
board[3][3] = turn(board, xturn);
this will not go well, you return a board of 3x3 strings but assign
it to at best, an undefined place.
since you already pass the address of the board to your turn function, that is that is all needed. change it in place.
turn(board, xturn);
arrays are addresses in memory, it is the starting address where in memory some data is stored
if you pass an array/matrix to a function you are letting the function know where in memory it is stored, so any changes to the array/matrix will be done in place, therefore you do not need to return a copy.

Is there a Python fstring or string formatting equivalent in C++?

I'm working on a project in C++ and I needed to make a string that has elements of an array in it. I know in python you have things like sting formatting and fstrings, but I don't know if C++ has any equivalent. I have no earthly idea as to whether or not that's a thing, so I figured this is the best place to ask. I'm making a tic-tac-toe game and I have the board made and I have the positions on the board made. All I'm trying to do is optimize the board so that I can call it from one function in another function and have the parent function return the board so I can work with it. My basic idea for how to do this was to take the board and turn it all into one big string with a bunch of newlines in it and the array elements in it. I also made it in a function so I can just call it wherever I need it and just have it there. Here is the board function I made:
void board(){
char board_pos[3][3] = {{'1', '2', '3'}, {'4', '5', '6'}, {'7', '8', '9'}};
cout << " | | " << endl;
cout << " " << board_pos[0][0] << " | " << board_pos[0][1] << " | " << board_pos[0][2] << " " << endl;
cout << " | | " << endl;
cout << "-----------------" << endl;
cout << " | | " << endl;
cout << " " << board_pos[1][0] << " | " << board_pos[1][1] << " | " << board_pos[1][2] << " " << endl;
cout << " | | " << endl;
cout << "-----------------" << endl;
cout << " | | " << endl;
cout << " " << board_pos[2][0] << " | " << board_pos[2][1] << " | " << board_pos[2][2] << " " << endl;
cout << " | | " << endl;
}
Edit: I got it figured out thanks to the help of you guys, I really appreciate it. :)
I would just return the type that you use to hold the board. In your case you started with char[3][3].
I would write that using the C++11 array:
using Row = std::array<char, 3>;
using Board = std::array<Row, 3>;
Now you can make all kinds of functions:
void move(char player, Board const& b, int row, int col);
bool is_game_over(Board const&);
void print(Board const& b);
Etc.
Your print function could be:
void print(Board const& b)
{
std::cout << " | | \n";
auto print_row = [](Row const& row) {
std::cout << " " << row[0] << " | " << row[1] << " | " << row[2]
<< " \n";
};
print_row(b[0]);
std::cout << " | | \n";
std::cout << "-----------------\n";
std::cout << " | | \n";
print_row(b[1]);
std::cout << " | | \n";
std::cout << "-----------------\n";
std::cout << " | | \n";
print_row(b[2]);
std::cout << " | | \n";
}
See it Live
Prints
| |
1 | 2 | 3
| |
-----------------
| |
4 | 5 | 6
| |
-----------------
| |
7 | 8 | 9
| |

how to tell if a character is inside a string c++

I am making a hangman game on my own and I have ran into a problem where I need to know if the guess is in the secret word. if it is I will change the bool innum to true, if it is not it will stay false. i have looked it up and cannot find anything that works. also the name printe is just the name of the string its just what I've named it.
here is the code I am working with:
using namespace std;
#include <iostream>
#include <conio.h>
void title();
void rightanswer();
void try1();
void try2();
void try3();
void try4();
void try5();
void try6();
void spacer();
int main()
{
bool innum = false;
int printe = 0, attempts_wrong = 0, trynum = 6;
char guess;
string secretword, hint1, hint2;
title();
// the welcoming senteces
cout << "Welcome to HANG MAN\n\n" << endl;
cout << "Please enter the secret word (no spaces): ";
cin >> secretword;
// the hints
cout << "\nenter the first hint: ";
cin >> hint1;
cout << "\nenter the second hint: ";
cin >> hint2;
//explanation for hints
cout << "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"; //so guesser cant see word
cout << "\nthe hints will be used as the guesser runs out of attemptts" << endl;
cout << "the first hint will be used immediately\n\n" << endl;
cout << "press any button to start...";
_getch();
cout << "\n\n" << endl;
for (int i = 0; secretword[i] != '\0'; ++i)
{
printe++;
}
rightanswer();
cout << "\nyour word is " << printe << " letters long" << endl;
if (attempts_wrong == 0)
{
cout << "your first hint is: ";
cout << hint1 << endl;
}
if (attempts_wrong == 3)
{
cout << "your second hint is: ";
cout << hint2 << endl;
}
cout << "enter a letter: ";
cin >> guess;
// im gonna have the code go here
// <-----------------------------
if (innum == true)
{
spacer();
cout << guess << " is in the secret word" << endl;
rightanswer();
}
else if (innum == false)
{
spacer();
cout << guess << " is not in the secret word" << endl;
rightanswer();
attempts_wrong++;
}
return 0;
}
void title() {
cout << "*****************************************" << endl;
cout << "* _____ *" << endl;
cout << "* | | /\\ |\\ | | *" << endl;
cout << "* |_____| /__\\ | \\ | | ___ *" << endl;
cout << "* | | / \\ | \\ | | | *" << endl;
cout << "* | | / \\| \\| |_____| *" << endl;
cout << "* *" << endl;
cout << "* |\\ /| /\\ |\\ | *" << endl;
cout << "* | \\ / | /__\\ | \\ | *" << endl;
cout << "* | \\ / | / \\ | \\ | *" << endl;
cout << "* | V | / \\| \\| *" << endl;
cout << "* *" << endl;
cout << "*****************************************" << endl;
}
//head, body, 2 arms, 2 legs - 6 in total
void rightanswer() {
//if the guess is right and the start
cout << " ___ " << endl;
cout << " | | " << endl;
cout << " | " << endl;
cout << " __|__ " << endl;
}
void try1() {
cout << " ___ " << endl;
cout << " | | " << endl;
cout << " O | " << endl;
cout << " | " << endl;
cout << " __|__ " << endl;
}
void try2() {
cout << " ___ " << endl;
cout << " | | " << endl;
cout << " O | " << endl;
cout << " | | " << endl;
cout << " __|__ " << endl;
}
void try3() {
cout << " ___ " << endl;
cout << " | | " << endl;
cout << " O | " << endl;
cout << " /| | " << endl;
cout << " __|__ " << endl;
}
void try4() {
cout << " ___ " << endl;
cout << " | | " << endl;
cout << " O | " << endl;
cout << " /|\ | " << endl;
cout << " __|__ " << endl;
}
void try5() {
cout << " ___ " << endl;
cout << " | | " << endl;
cout << " O | " << endl;
cout << " /|\ | " << endl;
cout << " / __|__ " << endl;
}
void try6() {
cout << " ___ " << endl;
cout << " | | " << endl;
cout << " O | " << endl;
cout << " /|\ | " << endl;
cout << " / \__|__ " << endl;
cout << " YOU LOSE" << endl;
cout << "you have run out of guesses";
exit(0);
}
// it creates a line to differ one try from the other
void spacer() {
cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
}
I don't know how much to show so that is all of it, its probably not the best but it works. I know that I don't some of the voids functions at the bottom but it works for now. if you have any suggestions tell me them. also don't be to harsh, I'm a beginner.
There are a few ways of approaching this. If you actually want to simply find if a string contains a character, the following works:
char needle;
haystack.find(needle) != string::npos;
As others have correctly answered. However, in this case, I think you are looking for something slightly different. Its a game of hangman so what you actually may want to do is show the portions of the word that the individual has actually guessed correctly.
Efficient
If we assume that: display is a string initialised with _ (or some character that is not a valid letter in a guessable word) as each character to the length of the string, you can work with this to partially display it.
If we have a map<char, vector<size_t>> that tells us exactly the indices that each character occurs at, which is easy to compute, we can take the guess and iterate through the corresponding vector of indices and replace characters in display with the actual character and then remove the character from the map. Once the map is empty, then the entire string has been guessed. You may also want to maintain a set of characters that have already been guessed to ensure that the same character can only be guessed once.
I will leave it as an exercise for you to implement this as it shouldn't be too difficult. If you'd like some pointers, let me know.
Less Efficient
This second way is less efficient, but since its a real-time game it won't make a difference unless these strings are really long.
Simply hold a copy of the string and iterate through it. Every time check which character you are checking against then replace the character at the index you are at in the _ word with the correct character. You can also keep a flag which checks whether or not any replacements happen and if not, you know that the character does not exist in the word.
You may use std::string::find method to find the given character (returns the position of the character or std::string::npos if it is not found): http://www.cplusplus.com/reference/string/string/find/
Example:
std::string str = "Hello.World";
auto found = str.find('.');
if (found != std::string::npos)
std::cout << "Period found at: " << found << std::endl;
In your case, it could look as such:
innum = (secretword.find(guess) != std::string::npos);
Try string.find.
auto i =secretword.find(guess); gives you the index. If it equals std::string::npos it isn't there.
Also, std::string has a size() method you can rrplace your letter counting with.

2D Vector Initialization: Initialization setting weird length

I am creating a 10x10 grid for a battleship game. I am using vector template of a 2D array, and am running into trouble when I am initializing it. When I initialize the 2D vector I am trying to set each space of the 10x10 vector to ' ', but for some reason I am getting each coordinate initialized to 10 spaces instead of 1 space.
board.hpp
#ifndef BOARD_HPP
#define BOARD_HPP
#include "ship.hpp"
#include <vector>
class Board
{
private:
std::vector<std::vector<char> > coordinate;
Ship carrier;
Ship battleship;
Ship floater;
Ship submarine;
Ship destroyer;
public:
Board();
char *coord(int row, int column);
};
#endif // BOARD_HPP
board.cpp
#include "board.hpp"
Board::Board() : coordinate(std::vector<std::vector<char> >(10, std::vector<char>(10, ' '))), carrier('C',5), battleship('B',4), floater('F',3), submarine('S',3), destroyer('D',2)
{
//Constructor
}
char *Board::coord(int row, int column)
{
return &coordinate[row][column];
}
Here is the game file the boards feed into:
game.hpp
#ifndef GAME_HPP
#define GAME_HPP
#include "board.hpp"
class Game
{
private:
Board *playerBoard;
Board *compBoard;
Board *compBoardHidden;
public:
Game(Board *player_board, Board *comp_board, Board *comp_board_hidden);
void display();
};
#endif // GAME_HPP
game.cpp
#include "game.hpp"
#include <iostream>
Game::Game(Board *player_board, Board *comp_board, Board *comp_board_hidden) : playerBoard(player_board), compBoard(comp_board), compBoardHidden(comp_board_hidden)
{
//Constructor
}
void Game::display()
{
std::cout << " | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10| | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10|" <<std::endl;
for (int i = 0; i < 10; i++)
{
std::cout << " ---+---+---+---+---+---+---+---+---+---+---+ ---+---+---+---+---+---+---+---+---+---+---+\n " << char(65+i) << " | " << playerBoard->coord(i,0) << " | " << playerBoard->coord(i,1) << " | " << playerBoard->coord(i,2) << " | " << playerBoard->coord(i,3) << " | " << playerBoard->coord(i,4) << " | " << playerBoard->coord(i,5) << " | " << playerBoard->coord(i,6) << " | " << playerBoard->coord(i,7) << " | " << playerBoard->coord(i,8) << " | " << playerBoard->coord(i,9) << " | " << char(65+i) << " | " << compBoard->coord(i,0) << " | " << compBoard->coord(i,1) << " | " << compBoard->coord(i,2) << " | " << compBoard->coord(i,3) << " | " << compBoard->coord(i,4) << " | " << compBoard->coord(i,5) << " | " << compBoard->coord(i,6) << " | " << compBoard->coord(i,7) << " | " << compBoard->coord(i,8) << " | " << compBoard->coord(i,9) << " |" << std::endl;
}
}
Your vector is completely fine, the only problem is when you print a single element.
Your code has undefined behavior because you are printing a char array which isn't null-terminated. std::cout has an overload for operator<< for char*, i.e. strings, and that overload is taken. You need to dereference it to print out the actual character.
Why are you even using pointers? If you someone on the outside has to be able to modify it, just use a reference.

xcode "expected unqualified-id" on cout

I'm trying to make a program to calculate the y component of a user-input number for 7 different aspect ratios. This is probably a simple problem somewhere in the declarations at the top, but I have very little experience with c++. I am writing in xcode. Thanks!
I'm getting the following error messages:
19:13: Invalid operands to binary expression ('std::__1::basic_istream' and '')
32:6: Expected unqualified-id
//
// aspect1.cpp
// aspectRatioCalculator
//
#include <iostream>
using namespace std;
int main()
{
int a;
cout << "Enter a number to calculate its complements at multiple aspect ratios." << endl;
cin>> a >> endl;
int b = (a*9)/17;
int c = (a*9)/16;
int d = (a*5)/8;
int e = (a*4)/5;
int f = (a*3)/5;
int g = (a*3)/4;
int h = (a*2)/3;
cout << "17:9 | " << a << ":" << b << endl;
cout << "16:9 | " << a << ":" << c << endl;
cout << " 8:5 | " << a << ":" << d << endl;
cout << " 5:4 | " << a << ":" << e << endl;
cout << " 5:3 | " << a << ":" << f << endl;
cout << " 4:3 | " << a << ":" << g << endl;
cout << " 3:2 | " << a << ":" << h << endl;
}
std::endl is an output manipulator. It isn't meant to be used with input streams (which are used for input). Change this: cin >> a >> endl; to cin >> a; cout << endl;.