Parsing a file to assign variables to strucuture. C++ - c++

Here is my code, I'm genuinely interested how far off I am.
bool characterGetCFG(char typeOverLoad, string var_name, string full_text)
{
int pos = full_text.find(var_name) + 1;
if (full_text.at(pos) == *"t") {
cout << "returned " << full_text.at(pos) << "\n";
return true;
}
else
{
return false;
}
}
int characterGetCFG(int typeOverLoad, string var_name, string full_text)
{
int pos = full_text.find(var_name) + var_name.length() + 1;
cout << "returned " << full_text.at(pos) << "\n";
return full_text.at(pos);
}
features setconfig(features featstruct)
{
features config; //BOOL/BOOL/BOOL/BOOL/INT[2]/BOOL/INT
ifstream file;
file.open("config.cfg");
if (!file.is_open()) {
exit(-1);
}
string raw;
while (file.good()) {
file >> raw;
}
for (int x = 0; x < 11; x++) {
switch (x) {
case 1:
config.var1 = characterGetCFG('t', "var1", raw);
case 2:
config.var2 = characterGetCFG('t', "var2", raw);
case 3:
config.var3 = characterGetCFG('t', "var3", raw);
case 4:
config.var4 = characterGetCFG('t', "var4", raw);
case 5:
config.var5[1] = characterGetCFG(136, "var51", raw); //min
case 6:
config.var6[2] = characterGetCFG(542, "var62", raw); //max
case 7:
config.var7 = characterGetCFG('t', "var7", raw);
case 8:
config.var8 = characterGetCFG('t', "var8", raw);
case 9:
config.var9 = characterGetCFG('t', "var9", raw);
case 10:
config.var10 = characterGetCFG('t', "var10", raw);
case 11:
config.var11 = characterGetCFG('t', "var11", raw);
}
}
file.close();
return config;
}
And here is my text/cfg file I am using
var1=false
var2=false
var3=true
var4=false
var51=2
var62=7
var7=true
var8=t
var9=true
var10=true
var11=true
Here is what I am getting returned when I print what I am returning to console
As you can see it does not reflect how many times I iterate through the loop, so at the end of the day I'm stumped.

Related

c++ terminate std::logic error ......where did my code go wrong?

I'm encountering this really weird error and I dont know where I'm constructing a string with a null parameter, could someone please help me out? Thanks!
Here's the error:
terminate_called_after_throwing_an_instance_of_'std::logic_error'
__what():__basic_string::_M_construct_null_not_valid
Here's my code:
/*
ID: 2005amr1
TASK: friday
LANG: C++
*/
#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <vector>
using namespace std;
vector <string> days = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
bool leap (int y){
if (y%100 == 0){
if (y%400 == 0){
return true;
}
else{
return false;
}
}
else if (y%4 == 0){
return true;
}
else{
return false;
}
}
int targetedSearch (vector<string> array, string key){
int index = 0;
while( (index < array.size( )) && (key != array[index])){
if (array[index] != key){
index++;
}
}
return (index);
}
string findLastDay(string FDAY, int daysInMonth){ // all good here
int indexOfString = targetedSearch(days, FDAY);
if (FDAY == "Mon" && daysInMonth == 28){
return ("Sun");
}
return (days[(daysInMonth - (7*(daysInMonth/7))-1) + indexOfString]);
}
string find13Day (string firstDay){ // all good here
int indexOfString = targetedSearch(days, firstDay);
return (days[indexOfString+5]);
}
string findFirstDayNextMonth (string LDAY){
int indexOfString = targetedSearch(days, LDAY);
if (indexOfString+1 > 6){
return (days[(indexOfString+1)-7]);
}
else{
return (days[indexOfString+1]);
}
}
int numDays (int month, int year){
switch(month) {
case 0:
return 31;
break;
case 1:
if (leap(year) == true){
return 29;
}
else{
return 28;
}
break;
case 2:
return 31;
break;
case 3:
return 30;
break;
case 4:
return 31;
break;
case 5:
return 30;
break;
case 6:
return 31;
break;
case 7:
return 31;
break;
case 8:
return 30;
break;
case 9:
return 31;
break;
case 10:
return 30;
break;
case 11:
return 31;
break;
}
return 31;
}
int main() {
ofstream fout ("friday.out");
ifstream fin ("friday.in");
string startDay = "Mon";
int dayValues[7] = {0,0,0,0,0,0,0};
int n;
fin >> n;
map <string,int> dayValue;
for (int i = 1900; i< 1900+n; i++){
for (int m =0; m<12; m++){
int PAN = numDays (m,i);
string tday = find13Day(startDay);
dayValues[targetedSearch(days,tday)]++;
string LDAY = findLastDay(startDay, PAN);
startDay = findFirstDayNextMonth(LDAY);
}
}
fout << " " << dayValues[5] << " " << dayValues[6]<< " " << dayValues[0]<< " " << dayValues[1]<< " " << dayValues[2]<< " " << dayValues[3]<< " " << dayValues[4];
}

Why does my check not work in checking for duplicated results( pointers)

int main()
{ srand(time(NULL));
Card c;
Card *Pc;
Pc = new Card [52];
Card ** someHands;
// typedef Card * Hand;
// Hand *someHands;
CardtoArray(c,Pc);
printDeckofCards(Pc,c);
}
Card GenerateCards(Card c)
{
int CardNum;
CardNum=rand() % 13 + 1;
int colour =rand() % 4 + 1;
switch(CardNum)
{
case 1: c.rank= Ace;
break;
case 2: c.rank= Two;
break;
case 3: c.rank= Three;
break;
case 4: c.rank= Four;
break;
case 5: c.rank= Five;
break;
case 6: c.rank= Six;
break;
case 7: c.rank= Seven;
break;
case 8: c.rank= Eight;
break;
case 9: c.rank= Nine;
break;
case 10: c.rank= Ten;
break;
case 11: c.rank= Jack;
break;
case 12: c.rank= Queen;
break;
case 13: c.rank= King;
break;
}
switch(colour)
{
case 1:c.color="Diamond";
break;
case 2:c.color="Club";
break;
case 3:c.color="Heart";
break;
case 4:c.color="Spade";
break;
}
return c;
}
//prints a single card this function is to be call into the function //printsdeckofcards
void printCard(Card c)
{
cout<<*c.color;
if(c.rank==Ace)
cout<<"A";
else if(c.rank==Two)
cout<<"2";
else if(c.rank==Three)
cout<<"3";
else if(c.rank==Four)
cout<<"4";
else if(c.rank==Five)
cout<<"5";
else if(c.rank==Six)
cout<<"6";
else if(c.rank==Seven)
cout<<"7";
else if(c.rank==Eight)
cout<<"8";
else if(c.rank==Nine)
cout<<"9";
else if(c.rank==Ten)
cout<<"10";
else if(c.rank==Jack)
cout<<"J";
else if(c.rank==Queen)
cout<<"Q";
else if(c.rank==King)
cout<<"K";
}
//generate and inserts 52 cards it also calls the function samecard to check if
//duplicated cards have been generated and if so regenerates a new one before //inserting into the array
void CardtoArray(Card &c,Card *Pc)
{
Card *origin;
origin=Pc;
for( int i=0;i<52;i++)
{
c=GenerateCards(c);
if(SameCard(c,origin)==false)
{
*Pc=c;
Pc++;
}
else
i--;
}
}
void printDeckofCards(Card *Pc,Card c)
{
for( int i=0;i<52;i++)
{
printCard(*Pc);
cout<<" ";
Pc++;
}
}
bool SameCard(Card c,Card *Pc)
{ bool check;
for(int i=0; i<52; i++)
{
if(Pc->color==c.color && Pc->rank==c.rank)
{
check = true;
}
else
{
check = false;
}
Pc++;
}
return check;
}
Blockquote
Because you are checking ALL cards, your boolean must be set to false before the loop and is set to true in the loop; it should not be set to false again in the loop:
bool SameCard(Card c,Card *Pc)
{ bool check= false;
for(int i=0; i<52; i++)
{
if(Pc->color==c.color && Pc->rank==c.rank)
{
check = true;
}
//else
///{
// check = false;
//}
Pc++;
}
return check;
}
or even:
bool SameCard(Card c,Card *Pc)
{
for(int i=0; i<52; i++, pc++)
if(Pc->color==c.color && Pc->rank==c.rank)
return true;
return false;
}

Switch statement will NOT print a string

char gamerCentral::getGamerTag( )
{
switch(gamerTag)
{
case '1': return gamerTag = "Diamond";
break;
case '2': return gamerTag = "Silver";
break;
case '3': return gamerTag = "Bronze";
break;
case '4': return gamerTag = "Wood";
break;
default: return gamerTag = "Uninstall";
break;
}
char gamerTag;
GamerClub::GamerClub(
char tag)
{
gamerTag = tag;
}
I'm trying to return the gamerTag, but it says that it cannot convert to a string. Is their a way to convert the char to a string inside the switch statement?
Have your function return a string, it can still operate on the single character as input. Here's an example.
std::string getGamerTag(char t)
{
switch(t)
{
case '1': return "Diamond";
case '2': return "Silver";
// ...
}
return "";
}
// prints "Silver"
cout << getGamerTag('2');
use string variable or use char*
char* getGamerTag(int t)
{
switch(t)
{
case 1: return "Diamond";
case 2: return "Silver";
}
}
int main()
{
cout << getGamerTag(2);
}
I recommend using an array of strings:
std::string getGamerTag(unsigned int t)
{
static const char * tag_names[] =
{
"Diamond", "Silver", "Bronze", "Wood", "Unistall",
};
static const unsigned int name_quantity =
sizeof(tag_names) / sizeof(tag_names[0]);
std::string name;
if ((t > 0) && (t <= name_quantity))
{
name = tag_names[t - 1];
}
return name;
}

How to include global functions in a separate file

I am trying to organize my code by grouping functions in seperate header/source files. I've #included the header file in my main .cpp, but the compiler does not see the functions in convertTypes.cpp. What gives? And how do I use my 'key' typedef globally (so also in the seperated function sources)? Lots of code, sorry.
/*
* NoteMaker.cpp
*
* Created on: Sep 4, 2013
* Author: edwinrietmeijer
*/
typedef struct {
int keyNum;
int keyType;
} key;
#include <iostream>
#include <string>
#include <iomanip>
#include "convertTypes.h"
using namespace std;
const int KEYSET[ ] = { 0, 2, 4, 5, 7, 8, 9 };
int* generateNotes( int, key );
void echoNoteList( const int* , const int, const key );
string getKeyStringFromUser();
int main() {
key keyStruct;
int octave;
int nrOfNotes;
string firstNoteName;
// Get inputs
cout << "What key would you like to generate notes in? ( f, cis, es, etc.)" << endl;
firstNoteName = getKeyStringFromUser();
cout << "In what octave would you like to generate notes? (-1 / 9)" << endl;
cin >> octave;
octave += 1;
cout << "How many notes do you wish to generate?" << endl;
cin >> nrOfNotes;
// create a key data struct from input string
keyStruct = convertKeyStringToKeyStruct( firstNoteName );
// add the starting octave nr to the keyStruct
keyStruct.keyNum += octave * 12;
// generate note list
int* noteList = new int[ nrOfNotes ];
noteList = generateNotes( nrOfNotes, keyStruct );
// echo note list to terminal
echoNoteList( noteList , nrOfNotes, keyStruct);
cin.get();
}
int* generateNotes( int notes, key keyStruct) {
int* newList = new int [notes];
int currNote = keyStruct.keyNum + keyStruct.keyType;
int currDist = 0;
newList[0] = currNote;
for (int i=1; i < notes; i ++) {
currDist = i % 7;
if ( currDist == 0 || currDist == 3 ) // half step or whole step?
{ currNote = currNote + 1; }
else
{ currNote = currNote + 2; }
newList[ i ] = currNote;
}
cout << "Generated list." << endl;
return newList;
}
void echoNoteList( const int* noteList, const int nrOfNotes, const key thisKeyStruct )
{
int currNote;
for (int i = 0; i < nrOfNotes ; i ++) {
currNote = noteList[ i ] % 12;
if ( currNote < 0 )
currNote += 12;
cout << left;
cout << setw(5) << noteList[ i ] << setw( 5 ) << convertToNoteName( currNote, thisKeyStruct.keyType ) << endl;
}
}
string getKeyStringFromUser() {
bool correctInput = false;
string getKeyName;
int keyNum;
while ( ! correctInput ) {
cin >> getKeyName;
cout << endl;
keyNum = getKeyName[ 0 ];
if ( keyNum > 96 && keyNum < 104 ) {
correctInput = true;
}
else
{
cout << "Wrong input. Try again." << endl;
}
}
return getKeyName;
}
convertTypes.h
#ifdef CONVERTTYPES_H
#define CONVERTTYPES_H
std::string convertToNoteName( int, int );
key convertKeyStringToKeyStruct( std::string );
#endif
convertTypes.cpp
/*
* convertTypes.cpp
*
* Created on: Sep 5, 2013
* Author: edwinrietmeijer
*/
#include <string>
#include "convertTypes.h"
using namespace std;
typedef struct {
int keyNum;
int keyType;
} key;
key convertKeyStringToKeyStruct( string firstNote ) {
int stringSize;
int keyType = 0;
char keyChar;
key thisKey;
keyChar = firstNote[ 0 ];
// get key type (flat, sharp, normal)
stringSize = firstNote.size( );
if (stringSize > 1 ) {
switch( firstNote[ 1 ] ) {
case 'e':
keyType = -1; break;
case 's':
keyType = -1; break;
case 'i':
keyType = 1; break;
default:
keyType = 0; break;
}
}
// convert key char to ascii code
int ASkey = keyChar;
thisKey.keyNum = KEYSET[ ASkey - 99 ];
thisKey.keyType = keyType;
return thisKey;
}
string convertToNoteName( int thisNote, int thisKeyType = 0) {
string noteName;
char addKeyType;
switch( thisKeyType ) {
case -1:
addKeyType = 'b'; break;
case 0:
addKeyType =' '; break;
case 1:
addKeyType = '#'; break;
}
switch( thisNote ) {
case 0:
noteName = "C"; break;
case 1:
if( thisKeyType == 1)
noteName = string ("C") + addKeyType;
else
noteName = string("D") + addKeyType; break;
case 2:
noteName = "D"; break;
case 3:
if( thisKeyType == 1)
noteName = string ("D") + addKeyType;
else
noteName = string("E") + addKeyType; break;
case 4:
noteName = "E"; break;
case 5:
noteName = "F"; break;
case 6:
if( thisKeyType == 1)
noteName = string ("F") + addKeyType;
else
noteName = string("G") + addKeyType; break;
case 7:
noteName = "G"; break;
case 8:
if( thisKeyType == 1)
noteName = string ("G") + addKeyType;
else
noteName = string("A") + addKeyType; break;
case 9:
noteName = "A"; break;
case 10:
if( thisKeyType == 1)
noteName = string ("A") + addKeyType;
else
noteName = string("B") + addKeyType; break;
case 11:
noteName = "B"; break;
default:
noteName = "!"; break;
}
return noteName;
}
Change:
#ifdef CONVERTTYPES_H
to:
#ifndef CONVERTTYPES_H
You are effectively compiling-out your definitions.
As to your second point, move this:
typedef struct {
int keyNum;
int keyType;
} key;
into the header file (before its first use there).
However I would warn against using a name like key as it's commonly used as a variable name. I would go for key_t or MySpecialKeyForStuffImDoing (or somesuch).
In addition to #trojanfor's anwer: also create a new NoteMaker.h containing the key structure definition or move the stuct definition to convertTypes.hso that you don't duplicate it in multiple places

Not able to trace the crash because of inconsistency

I am making a blackjack game in cocos2d-x here is the following code of the same where I am getting crash but can not understant why this is happening whats going wrong ? I tried several things thinking that crash might be because of string memory leak or something
CCSprite* _big = CCSprite::createWithSpriteFrameName(ptr);
Here is the card cpp file which inherits CCSprite
Card.cpp
#include "Card.h"
Card::Card() {
}
Card::~Card() {
}
void Card::init(int value, int suit) {
mValue = value;
mSuit = suit;
mGameValue = 0;
UnHide();
}
void Card::UnHide() {
mHidden = false;
//if(this)
//this->removeAllChildrenWithCleanup(true);
//this->setDisplayFrame(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("card"));
this->initWithSpriteFrameName("card");
char strName[64]={0};
//memset ( strName, 0, sizeof ( strName ));
switch(mSuit){
case 0: sprintf(strName,"%s","club_big");break;
case 1: sprintf(strName,"%s","diamond_big");break;
case 2: sprintf(strName,"%s","spade_big");break;
case 3: sprintf(strName,"%s","heart_big");break;
default :
break;
}
const char *ptr = strdup(strName);
CCSprite* _big = CCSprite::createWithSpriteFrameName(ptr);
delete ptr;
// CCSprite* big = CCSprite::create(strName);
_big->setPosition(ccp(55, 44));
this->addChild(_big);
switch(mSuit){
case 0: sprintf(strName,"%s","club");break;
case 1: sprintf(strName,"%s","diamond");break;
case 2: sprintf(strName,"%s","spade");break;
case 3: sprintf(strName,"%s","heart");break;
default :
break;
}
const char *_ptr = strdup(strName);
CCSprite* _small = CCSprite::createWithSpriteFrameName(_ptr);
delete _ptr;
// CCSprite* small = CCSprite::create(str);
_small->setPosition(ccp(16, 82));
this->addChild(_small);
if(mSuit==0 || mSuit==2){
switch(mValue){
case 1: sprintf(strName,"%s","blacka");mGameValue = 1;break;
case 2: sprintf(strName,"%s","black2");mGameValue = mValue;break;
case 3: sprintf(strName,"%s","black3");mGameValue = mValue;break;
case 4: sprintf(strName,"%s","black4");mGameValue = mValue;break;
case 5: sprintf(strName,"%s","black5");mGameValue = mValue;break;
case 6: sprintf(strName,"%s","black6");mGameValue = mValue;break;
case 7: sprintf(strName,"%s","black7");mGameValue = mValue;break;
case 8: sprintf(strName,"%s","black8");mGameValue = mValue;break;
case 9: sprintf(strName,"%s","black9");mGameValue = mValue;break;
case 10: sprintf(strName,"%s","black10");mGameValue = mValue;break;
case 11: sprintf(strName,"%s","blackj");mGameValue = 10;break;
case 12: sprintf(strName,"%s","blackq");mGameValue = 10;break;
case 13: sprintf(strName,"%s","blackk");mGameValue = 10;break;
default :
break;
}
}
else {
switch(mValue){
case 1: sprintf(strName,"%s","reda");mGameValue = 1;break;
case 2: sprintf(strName,"%s","red2");mGameValue = mValue;break;
case 3: sprintf(strName,"%s","red3");mGameValue = mValue;break;
case 4: sprintf(strName,"%s","red4");mGameValue = mValue;break;
case 5: sprintf(strName,"%s","red5");mGameValue = mValue;break;
case 6: sprintf(strName,"%s","red6");mGameValue = mValue;break;
case 7: sprintf(strName,"%s","red7");mGameValue = mValue;break;
case 8: sprintf(strName,"%s","red8");mGameValue = mValue;break;
case 9: sprintf(strName,"%s","red9");mGameValue = mValue;break;
case 10: sprintf(strName,"%s","red10");mGameValue = mValue;break;
case 11: sprintf(strName,"%s","redj");mGameValue = 10;break;
case 12: sprintf(strName,"%s","redq");mGameValue = 10;break;
case 13: sprintf(strName,"%s","redk");mGameValue = 10;break;
default :
break;
}
}
const char *_ptrr = strdup(strName);
CCSprite* _num = CCSprite::createWithSpriteFrameName(_ptrr);
delete _ptrr;
// CCSprite* _num = CCSprite::create(strName);
_num->setPosition(ccp(18, 108));
this->addChild(_num);
}
void Card::Hide() {
mHidden = true;
this->removeAllChildrenWithCleanup(true);
this->setDisplayFrame(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("deck"));
//this->initWithSpriteFrameName("deck");
}
Intialization of cards is as per this
for (int suit = 0; suit < 4; suit++) {
for (int value = 0; value < 13; value++) {
Card* card = new Card;
//card->init
card->init(value+1, suit);
mCard[suit*13 + value] = card;
}
}
The crash I get is on the line of initWithSpriteFrameName but it doesnt occur frequently
h file:
class Card : public cocos2d::Node
{
public:
int mValue;
int mSuit;
bool mHidden;
int mGameValue;
CCSprite* front;
CCSprite* back;
static Card* create();
bool init(int value, int suit);
void UnHide();
void Hide();
};
cpp file
Card* Card::create(int value, int suit){
Card* card = new Card();
if(card && card->init(value, suit)){
card->autorelease();
return card;
}
else{
CC_SAFE_DELETE(card);
return NULL;
}
}
bool Card::init(int value, int suit) {
if(CCNode::init()){
mValue = value;
mSuit = suit;
mGameValue = 0;
//create your front and back sprite here as what you did in Unhide
CCSprite* back = blablabla;
CCSprite* front = blablabla;
//add them as a child of current node
this->addChild(back);
this->addChild(front);
this->UnHide();
return true;
}
return false;
}
void Card::UnHide() {
back->setVisible(false);
front->setVisible(true);
}
void Card::Hide() {
back->setVisible(true);
front->setVisible(false);
}
and for your deck, from my understanding,
CCArray::createWithCapacity(52);
will be a better choice.