console based game crashes for no reason - c++

i am trying to make the beginnings of a very basic game i am trying to have it just make the border of the game witch will be x's and they player is H but when i build and run it the program will immediately crash please help
#include <iostream>
using namespace std;
int cords[2];
string map[6][6] =
{
{"X","X","X","X","X","X"},
{"X"," "," "," "," ","X"},
{"X"," "," "," "," ","X"},
{"X"," ","H"," "," ","X"},
{"X"," "," "," "," ","X"},
{"X","X","X","X","X","X"}
};
string input;
bool running = true;
void tick(){
if(input == "w"){
cords[1]++;
}
if(input == "s"){
cords[1] = cords[1] - 1;
}
if(input == "a"){
cords[0] = cords[0] - 1;
}
if(input == "d"){
cords[0]++;
}
}
void render(){
cout << map[1][1] << map[1][2] << map[1][3] << map[1][4] << map[1][5] << map[1][6] <<endl
<< map[2][1] << map[2][2] << map[2][3] << map[2][4] << map[2][5] << map[2][6] <<endl
<< map[3][1] << map[3][2] << map[3][3] << map[3][4] << map[3][5] << map[3][6] <<endl
<< map[4][1] << map[4][2] << map[4][3] << map[4][4] << map[4][5] << map[4][6] <<endl
<< map[5][1] << map[5][2] << map[5][3] << map[5][4] << map[5][5] << map[5][6] <<endl
<< map[6][1] << map[6][2] << map[6][3] << map[6][4] << map[6][5] << map[6][6] <<endl;
}
void run(){
int ticks;
int frames;
tick();
render();
}
int main(){
while(running == true){
run();
cin>> input;
}
}

Both map indeces must be between 0 and 5: map[6][3] is incorrect, for example

If you had written a loop to print out your 2d array, you may have avoided the error:
const int matSize = 6;
for (int i = 0; i < matSize; ++i)
{
for (int j = 0; j < matSize; ++j )
cout << m[i][j];
cout << "\n";
}

You should change your board to use string or char, not arrays of single character strings:
std::string map[6] =
{
"XXXXXX",
"X X",
"X X",
"X H X",
"X X",
"XXXXXX",
};
char map_as_char_array[6][6] =
{
{'X','X','X','X','X','X'},
{'X',' ',' ',' ',' ','X'},
{'X',' ',' ',' ',' ','X'},
{'X',' ','H',' ',' ','X'},
{'X',' ',' ',' ',' ','X'},
{'X','X','X','X','X','X'}
};
The string data type is overkill for single letters.
Remember, the string type can be accessed as a single dimension array of characters.

Related

string equal doesn't work c++

I have been struggling with comparing two strings which I read from files, "one" & "two" both have the same words (e.g. salt) but it doesn't return "Equal". I have also used == but it made no difference.
#include <iostream>
#include <cstring>
#include <fstream>
using namespace std;
int main (){
string en[100];
string line;
int i=0;
ifstream fileEn ("hey.txt");
if (fileEn.is_open()){
while (!fileEn.eof()){
getline(fileEn,line);
en[i]=line;
i++;
}
}
fileEn.close();
string fa[100];
string line1;
i=0;
ifstream fileFa ("hey1.txt");
if (fileFa.is_open()){
while (!fileFa.eof()){
getline(fileFa,line1);
fa[i]=line1;
i++;
}
}
fileFa.close();
ifstream Matn("matn.txt");
string matn[100];
if(Matn.is_open()){
for(int i = 0; i < 100; ++i){
Matn >> matn[i];
}
}
Matn.close();
string one = en[0];
string two = matn[0];
cout << one << " " << two;
if(one.compare(two) == 0){
cout << "Equal";
}
}
I suggest adding some debugging output to your program:
while (!fileEn.eof()){
getline(fileEn,line);
// Debugging output
std::cout << "en[" << i << "] = '" << line << "'" << std::endl;
en[i]=line;
i++;
}
and
for(int i = 0; i < 100; ++i){
Matn >> matn[i];
// Debugging output
std::cout << "matn[" << i << "] = '" << matn[i] << "'" << std::endl;
}
Hopefully you can see what the problem is by looking at the output.
In addition, please note that use of while (!fileEn.eof()){ ... } is not correct. See Why is iostream::eof inside a loop condition considered wrong?.
I suggest changing that loop to:
while (getline(fileEn,line)) {
// Debugging output
std::cout << "en[" << i << "] = '" << line << "'" << std::endl;
en[i]=line;
i++;
}
Similarly, don't assume that Matn >> matn[i] is successful. I suggest changing that loop to:
for(int i = 0; i < 100; ++i) {
std::string s;
if ( !(Matn >> s) )
{
// Read was not successful. Stop the loop.
break;
}
matn[i] = s;
// Debugging output
std::cout << "matn[" << i << "] = '" << matn[i] << "'" << std::endl;
}

can't write on a string in C++

I have the next function and i want to print some parameters separated by a comma, my problem is that the console didn't show anything when "parametro[i] = linea[i]" in the FOR iteration.
Example:
Parametro 1: []
void funcionSeparadora (string linea){
int numParametros = 1;
string parametro;
for (int unsigned i=0;i<linea.length();i++){
if (linea[i] == ','){
cout <<"Parámetro "<<numParametros<<": "<<"["<< parametro <<"]"<< '\n';
numParametros++;
}
else (parametro[i] = linea[i]);
}
}
Mostly the way you handle the filling of parametro was wrong. Fixed version:
void funcionSeparadora(string linea) {
int numParametros = 1;
string parametro;
for (int unsigned i = 0; i<linea.length(); i++) {
if (linea[i] == ',') {
cout << "Parámetro " << numParametros << ": " << "[" << parametro << "]" << '\n';
numParametros++;
parametro.clear();
}
else {
parametro += linea[i];
}
}
if (!parametro.empty()) {
cout << "Parámetro " << numParametros << ": " << "[" << parametro << "]" << '\n';
}
}
Points you missed
Use curly brackets in else condition
Use size_t instead of unsigned in in for loop
initialize the parametro variable with necessary length
Try this
#include <iostream>
#include <string>
using namespace std;
void funcionSeparadora(string linea) {
int numParametros = 1;
string parametro(linea.length(),' ');
for (size_t i = 0; i < linea.length(); i++) {
if (linea[i] == ',') {
cout << "Parámetro " << numParametros << ": " << "[" << parametro << "]" << endl;
numParametros++;
}
else {
parametro[i] = linea[i];
}
}
}
int main()
{
funcionSeparadora("what is this,");
system("pause");
return 0;
}

How to convert values from .art file into ASCII art in C++

Working on a project where I am supposed to load a file based on user input, convert the data in that file into coordinates in the window and then use ASCII characters to draw a picture.
Files are in .art and start with the width and height of the window needed and each subsequent line is the ROW, COLUMN, CHARACTER, and COUNT that needs to be drawn. So basically the position the particular character should be started at and then how many times it should be drawn.
What I am struggling with is how to import that data into something usable so as I can draw the requested image. My initial thought is to import the data as a 4-D array but then I draw a blank as to where I should go from there.
Example lines for a .art file:
50 x 25
2, 15, *, 9
2, 48, *, 9
3, 6, *, 15
UPDATE: Given up on trying to load the files since I just can't wrap my head around that so I've changed to just drawing the art by hand and calling a string but I'm even having issues with that. With my code below, if I select option 1 the output is 001FFA80 rather than outputting the ASCII art that is in the string.
#include <stdio.h>
#include <cstdlib>
#include <string>
#include <iostream>
using namespace std;
int main ()
{
string shapeCupid[]=
{" ",
" .. ",
" $. ,o$$$o. ",
" $. $$$$$$$o. .. ",
" .$. $' $$$$$$ ,o'' ",
" .$' $ '$$$$$,o'.,' .oo ' ",
" .$' $. $$$$' ,, .o'. ",
" .$' '$o. 'O$ .. ooo''',oo ' ",
" .$' .o$' '$$'' ,,o' ",
" .%$,,,,,ooO' ' ,,o'' ",
" .$o. ,o' $o ..oo' ",
" ''O'''''''''',' $'$. .o' "};
string shapeFly = "Fly";
string shapeHeart = "Heart";
string shapeImpossible = "Impossible";
string shapeSeuss = "Seuss";
string shapeWorry = "Worry";
int UserInput;
cout << "What do you want to draw?\n";
cout << "1. Cupid\n2. Fly\n3. Heart\n4. Impossible\n5. Seuss\n6. Worry\nNumber: ";
cin >> UserInput;
if (UserInput == 1){
cout << shapeCupid;}
else if (UserInput == 2){
cout << shapeFly;}
else if (UserInput == 3){
cout << shapeHeart;}
else if (UserInput == 4){
cout << shapeImpossible;}
else if (UserInput == 5){
cout << shapeSeuss;}
else if (UserInput == 6){
cout << shapeWorry;}
else if (UserInput != 1 || 2 || 3 || 4 || 5 || 6)
cout << "Please select proper value.\n";
system("pause");
return 0;
}
Here's a quick and dirty version that might help. I didn't add a ton of error checking, but it works for the 2 examples I used. If you do plan to embed the data as string literals you'll want to be sure to escape any special characters like backslash and double quotes. The Boop example has both.
For the embedded string literal data the first line must be padded to be as long as the longest line since it is used to write the width. An enhancement would be to iterate through all lines to get the max width and use that.
#include <string>
#include <iostream>
#include <vector>
#include <fstream>
using StringVec = std::vector<std::string>;
StringVec shapeCupid =
{
" ",
" .. ",
" $. ,o$$$o. ",
" $. $$$$$$$o. .. ",
" .$. $' $$$$$$ ,o'' ",
" .$' $ '$$$$$,o'.,' .oo ' ",
" .$' $. $$$$' ,, .o'. ",
" .$' '$o. 'O$ .. ooo''',oo ' ",
" .$' .o$' '$$'' ,,o' ",
" .%$,,,,,ooO' ' ,,o'' ",
" .$o. ,o' $o ..oo' ",
" ''O'''''''''',' $'$. .o' "
};
//Borrowed from http://www.chris.com/ascii/index.php?art=cartoons/betty%20boop
StringVec boop =
{
" _(,__ __), ",
" (_,d888888888b,d888888888b",
" d888888888888/888888888888b_)",
" (_8888888P'\"\"'`Y8Y`'\"\"'\"Y88888b",
" Y8888P.-' ` '-.Y8888b_)",
" ,_Y88P (_(_( )_)_) d88Y_,",
" Y88b, (o ) (o ) d8888P",
" `Y888 '-' '-' `88Y`",
" ,d/O\\ c /O\\b,",
" \\_/'.,______w______,.'\\_/",
" .-` `-.",
" / , d88b d88b_ \\",
" / / 88888bd88888`\\ \\",
" / / \\ Y88888888Y \\ \\",
" \\ \\ \\ 88888888 / /",
" `\\ `. \\d8888888b, /\\\\/",
" `.//.d8888888888b; |",
" |/d888888888888b/",
" d8888888888888888b",
" ,_d88p\"\"q88888p\"\"q888b,",
" `\"\"'`\\ \"`| /`'\"\"`",
" `. |===/",
" > | |",
" / | |",
" | | |",
" | Y /",
" \\ / /",
" jgs | /| /",
" / / / |",
" /=/ |=/"
};
void Write(const std::string& filename, StringVec& data)
{
if(data.empty())
{
return;
}
std::ofstream out(filename);
if(out)
{
out << data[0].size() << " x " << data.size() << "\n";
for(size_t row = 0; row < data.size(); ++row)
{
const std::string& line = data[row];
size_t col_start = 0;
size_t col_end = 0;
char col_char = line[0];
for(size_t col = 0; col < line.size(); ++col)
{
//If we hit a new character write the previous run to the file
if(col_char != line[col])
{
//but only if it wasn't a run of spaces.
if(col_char != ' ')
{
out << row << ", " << col_start << ", " << col_char << ", " << col_end - col_start + 1 << "\n";
}
col_char = line[col];
col_start = col;
col_end = col;
}
col_end = col;
}
//write the last run
if(col_char != ' ')
{
out << row << ", " << col_start << ", " << col_char << ", " << col_end - col_start + 1 << "\n";
}
}
}
}
StringVec Read(const std::string& filename)
{
StringVec data;
std::ifstream in(filename);
if(in)
{
char dummy;
size_t width;
size_t height;
if(in >> width >> dummy >> height)
{
data.resize(height, std::string(width, ' '));
}
if(!data.empty())
{
size_t row;
size_t col;
char ch;
size_t len;
while(in >> row >> dummy >> col >> dummy >> ch >> dummy >> len)
{
for(size_t i = col; i < col + len; ++i)
{
data[row][i] = ch;
}
}
}
}
return data;
}
void Print(const StringVec& data)
{
for(const std::string& s : data)
{
std::cout << s << "\n";
}
std::cout << "\n";
}
int main()
{
Write("cupid.art", shapeCupid);
Print(Read("cupid.art"));
Write("boop.art", boop);
Print(Read("boop.art"));
return 0;
}

The code is printing the same values when it should be randomly generating each ovr and also it is not printing the first value in the array

The issue that I am having is that with the code below, each plOvr for all of the class objects is the same. This causes them to have the same stats for everything. Also, I have an array with names that should be printed but it is skipping the first value.
using namespace std;
class Player
{
public:
int plOvr;
float plSpg, plSps;
string werk;
void setPlayeName(string);
string plName;
void setPlyrVal()
{
srand (time(NULL));
plOvr = rand()% 29 + 70;
plSps = plOvr / 10;
plSpg = plSps / 2;
}
};
void Player::setPlayeName(string werk)
{
plName = werk;
}
int main()
{
Player plyr1,plyr2,plyr3,plyr4,plyr5;
string firstTime;
string name[5] = {"Eric Gelinas","John Merill", "Jaromir Jagr", "Travis Zajac","Reid Boucher"};
bool firstOp;
cout << "Is this the first time this program has run?" << endl;
cin >> firstTime;
if (firstTime == "Yes" || firstTime == "yes")
{
firstOp == firstOp;
plyr1.setPlyrVal();
plyr1.setPlayeName(name[1]);
plyr2.setPlyrVal();
plyr2.setPlayeName(name[2]);
plyr3.setPlyrVal();
plyr3.setPlayeName(name[3]);
plyr4.setPlyrVal();
plyr4.setPlayeName(name[4]);
plyr5.setPlyrVal();
plyr5.setPlayeName(name[5]);
ofstream playerSaveData;
playerSaveData.open ("savedata.txt");
playerSaveData << plyr1.plName << "," << plyr1.plOvr << "," << plyr1.plSpg << "," << plyr1.plSps << "\n";
playerSaveData << plyr2.plName << "," << plyr2.plOvr << "," << plyr2.plSpg << "," << plyr2.plSps << "\n";
playerSaveData << plyr3.plName << "," << plyr3.plOvr << "," << plyr3.plSpg << "," << plyr3.plSps << "\n";
playerSaveData << plyr4.plName << "," << plyr4.plOvr << "," << plyr4.plSpg << "," << plyr4.plSps << "\n";
playerSaveData << plyr5.plName << "," << plyr5.plOvr << "," << plyr5.plSpg << "," << plyr5.plSps << "\n";
playerSaveData.close();
cout << "done.\n";
}
else
{
firstOp == !firstOp;
}
return 0;
}
You may use std::uniform_int_distribution<int> and an engine as std::mt19937 from <random>.
The engine (as srand) has to be initialized with seed only once.
Your program rewritten:
#include <ctime>
#include <iostream>
#include <fstream>
#include <string>
#include <random>
class Player
{
public:
void setPlayeName(const std::string& name) { plName = name; }
void setPlyrVal(std::mt19937& rand_engine)
{
std::uniform_int_distribution<int> distr(70, 98);
plOvr = distr(rand_engine);
plSps = plOvr / 10;
plSpg = plSps / 2;
}
public:
int plOvr;
float plSpg, plSps;
std::string werk;
std::string plName;
};
int main()
{
std::mt19937 rand_engine(time(nullptr));
Player plyrs[5];
const std::string names[5] = {"Eric Gelinas","John Merill", "Jaromir Jagr", "Travis Zajac","Reid Boucher"};
std::cout << "Is this the first time this program has run?" << std::endl;
std::string firstTime;
std::cin >> firstTime;
if (firstTime == "Yes" || firstTime == "yes") {
for (int i = 0; i != 5; ++i) {
plyrs[i].setPlyrVal(rand_engine);
plyrs[i].setPlayeName(names[i]);
}
std::ofstream playerSaveData;
playerSaveData.open ("savedata.txt");
for (const auto& plyr : plyrs) {
playerSaveData << plyr.plName << "," << plyr.plOvr << "," << plyr.plSpg << "," << plyr.plSps << "\n";
}
std::cout << "done." << std::endl;
}
return 0;
}
Live example
You should call srand() only once in the whole program, instead of calling it before each rand().

Problems with struct

so i was having two types of issues from my code... the general forms are:
"left of ... must have class/struct/union " :
doc.id[j] = NULL;
doc.ISBN[j] = NULL;
doc.title[j] = NULL;
doc.year[j] = NULL;
and " 'doc' uses undefined struct 'main::m_doc'"
struct m_doc doc;
while the struct m_doc doc is included in the top of each function .
here is my struct :
struct m_doc{
char id[30];
int ISBN[30];
char title[50];
char author[50];
int year[30];
};
my fist function :
void menudoc()
{ struct m_doc doc;
int c = 0, a = 0, b;
cout << "1. Them tai lieu moi" << endl;
cout << "2. Xoa tai lieu" << endl;
cout << "3. Bao cao theo nam xuat ban" << endl;
cout << "0. Tro lai menu truoc" << endl;
cout << "Ban chon:";
cin >> b;
switch (b)
{
case 1:
{
for (int i = 0;; i++)
{
if (doc.id[i] == NULL && doc.ISBN[i] == NULL && doc.title[i] == NULL && doc.author[i] == NULL && doc.year[i] == NULL)
{
i = c; break;
}
else continue;
}
cin >> doc.author[c] ;
cin >> doc.id[c] ;
cin >> doc.ISBN[c] ;
cin >> doc.title[c];
cin >> doc.year[c];
for (int i = 0;; i++){
for (int j = 1;; j++){
if (doc.id[i] == doc.id[j]){
doc.author[j] = NULL;
doc.id[j] = NULL;
doc.ISBN[j] = NULL;
doc.title[j] = NULL;
doc.year[j] = NULL;
}
if (doc.year[i]<1000 || doc.year[i]>9999){
doc.author[i] = NULL;
doc.id[i] = NULL;
doc.ISBN[i] = NULL;
doc.title[i] = NULL;
doc.year[i] = NULL;
}
}
}
break;
}
case 2:
{
int x;
char docid[50];
cout << "IDDOC: ";
cin >> docid[50];
cout << "\n";
for (int i = 0;; i++){
if (docid[50] == doc.id[i]) {
doc.author[i] = NULL;
doc.id[i] = NULL;
doc.ISBN[i] = NULL;
doc.title[i] = NULL;
doc.year[i] = NULL;
x++;
}
}
if (x == 0) cout << "IDDOC khong ton tai." << endl;
break;
}
case 3:
{
int yeardoc[50];
cin >> yeardoc[50];
for (int i = 0;; i++){
if (yeardoc[50] == doc.year[i])
write_output(i, "report.scv");
}
break;
}
case 0:
{
menubegin();
break;
}
menudoc();
}
}
my second function :
int write_output(int i, char* filename){
ios::out;
struct m_doc doc;
// open file for output
ofstream fout(filename);
char * k, *h;
k = strchr(doc.title, ',');
h = strchr(doc.author, ',');
if (k != 0 && h != 0)fout << doc.id[i] << "\n" << doc.ISBN[i] << "\n" << '"' << doc.title[i] << '"' << "\n" << '"' << doc.author[i] << '"' << "\n" << doc.year[i] << endl;
if (k != 0) fout << doc.id[i] << "\n" << doc.ISBN[i] << "\n" << '"' << doc.title[i] << '"' << "\n" << doc.author[i] << "\n" << doc.year[i] << endl;
if (h != 0)fout << doc.id[i] << "\n" << doc.ISBN[i] << "\n" << doc.title[i] << "\n" << '"' << doc.author[i] << '"' << "\n" << doc.year[i] << endl;
// write informations
if (k == 0 && h == 0)fout << doc.id[i] << "\n" << doc.ISBN[i] << "\n" << doc.title[i] << "\n" << doc.author[i] << "\n" << doc.year[i] << endl;
// close file
fout.close();
return 0;
}
anybody im asked said that it was something about scope but none of them know the problem since everything looks fine... please help me , every help is much appreciated :)
I'm taking a guess that you are confused about when to use forward declarations and when to include the structure definition. Here are some guidelines.
Forward Declaration
A forward declaration of a structure is of the form:
struct m_doc doc;
This form is used to resolve definitions, any pointer or reference that refers to the symbol doc. Usually this is placed in a header file before other structure or function declarations to reduce the number of #include files.
Structure Definition
You need to have the structure definition present before any code that:
Creates an instance of the structure,
Or before anything that refers to the details of the structure
(members & methods).
Placing structures in #include files
Rather than typing the structure everywhere it is used, a convenient practice is to place it in a header file, usually ".h" for C language structures and ".hpp" or ".hh" for C++ classes and structures. So when you have a function in a source file that references the structure (or creates an instance of the structure), include the file with the definition before it is used by the function.
Most compilers issue the error
"left of ... must have class/struct/union "
when it can't find the definition or declaration of the structure.