I am doing a project for a class writing C-String-editing functions. 3/5 of the functions I have to write change the size of the char arrays I have to use, and they are being read through an ifstream input. Here is the program:
#include <iostream>
#include <fstream>
using namespace std;
void stringCopy(char *A, char *B);
bool stringCompare(char *A, char *B);
void stringConcatenation(char *A, char *B); //added const to make sure b is never changed
int stringPosition(char *A, char B);
int stringLength(char *A);
//-------------------MY-FUNCTIONS----------------------
int cStringLen(const char*); //finds string length, but doesn't account for null char
void reSize(char*&, int len, int newLen);
void input(char*& A, istream& is);
void printMessage(const char* word1, const char* word2, const char* message);
int main()
{
ifstream ifs{"input.txt"};
ofstream ofs{"output.txt"};
char* word1 = "";
char* word2 = "";
input(word1, ifs);
input(word2, ifs);
printMessage(word1, word2, "stringCopy()");
stringCopy(word1, word2);
printMessage(word1, word2, "after stringCopy()");
cout << endl;
input(word1, ifs);
input(word2, ifs);
printMessage(word1, word2, "stringCompare()");
if(stringCompare(word1, word2))
{
cout << "They match!" << endl;
}
else
{
cout << "They don't match!" << endl;
}
stringCopy(word1, word2);
printMessage(word1, word2, "comparing after stringCopy()");
if(stringCompare(word1, word2))
{
cout << "They match!" << endl;
}
else
{
cout << "They don't match!" << endl;
}
cout << endl;
input(word1, ifs);
input(word2, ifs);
printMessage(word1, word2, "stringConcatenation()");
stringConcatenation(word1, word2);
printMessage(word1, word2, "after stringConcatenation()");
cout << endl;
input(word1, ifs);
input(word2, ifs);
printMessage(word1, word2, "stringPosition()");
cout << "Searching for 'm' in word1..." << endl << "position returned is: " << stringPosition(word1, 'm') << endl;
cout << "Searching for 'n' in word2..." << endl << "position returned is: " << stringPosition(word2, 'n') << endl;
cout << endl;
input(word1, ifs);
cout << "stringLength()" << endl;
cout << "word1: " << word1 << endl;
cout << "The length of word1 is: " << stringLength(word1) << endl;
cout << "after stringLength()" << endl;
cout << "word1: " << word1 << endl;
return 0;
}
void stringCopy(char *A, char *B)
{
///GETTING THE SIZES OF BOTH ARRAYS
int counterA = cStringLen(A) + 1;
int counterB = cStringLen(B) + 1;
///MAKES SURE BOTH ARE THE SAME SIZE BEFORE COPYING
if(counterA < counterB)
{
reSize(A, counterA, counterB);
}
else
{
reSize(A, counterB, counterA);
}
///THE COPY
for(int i = 0; i < counterB; i++) *(A + i) = *(B + i); //each character is copied to A from B
}
bool stringCompare(char *A, char *B)
{
///getting length of one string
int counter = cStringLen(A);
///will move through string until diff char found
for(int i = 0; i < counter + 1; i++)
{
if(*(A + i) != *(B + i))
{
return false;
}
}
return true;
}
void stringConcatenation(char *A, char *B) //added const to make sure b is never changed
{
///getting length of both strings
int counterA = cStringLen(A)+1;
int counterB = cStringLen(B)+1;
///putting the length of both together for new string
const int COUNTERS = counterA + counterB - 1;
///making A the size of both strings - 1
reSize(A, counterA, COUNTERS);
///copying b to the parts of a past the original
for(int i = 0; i < counterB; i++)
{
*(A + (counterA - 1) + i) = *(B + i); //will override the '/0' char of A
}
}
int stringPosition(char *A, char B)
{
int counter = cStringLen(A) + 1;
///searching through string for char
for(int i = 0; i < counter; i++)
{
if(*(A + i) == B)
{
return i; //found!
}
}
///checking if b == '\0' and a '\0' isn't found somewhere before last spot of A
if(B == '\0')
{
return counter;
}
return -1; //not found
}
int stringLength(char *A)
{
int counter = cStringLen(A) + 1;
char* car = new char[counter + 1];
for(int i = 0; i < counter; i++)
{
*(car + 1 + i) = *(A + i);
}
*(car + 0) = counter;
delete[] A;
A = car;
/**
* Will take string as param.
* Shifts all characters to the right by one and store the length of the string in position 0.
- Length doesn't include position 0.
*/
return counter; //temp
}
//-----------------------------------------MY FUNCTIONS---------------------------------------------------------------------------
int cStringLen(const char* A) //finds string length, but doesn't account for null char
{
int counter = 0;
while(*(A + counter) != '\0')
{
counter++;
}
return counter;
}
void reSize(char*& A, int len, int newLen)
{
char* car = new char[newLen];
for(int i = 0; i < newLen; i++)
{
if(i < len)
{
*(car + i) = *(A + i);
}
else if(i >= len && i < newLen)
{
*(car + i) = '\0';
}
}
delete[] A;
A = car;
}
void input(char*& A, istream& is)
{
int wordSize = 0;
int arrSize = 1;
char c = 'o'; //checking char
char* car = new char[arrSize];
while((!(is.eof())) && (c != ' ' && c != '\t' && c != '\n'))
{
is.unsetf(ios_base::skipws);
is >> c;
if(is.eof())
{
delete[] A;
A = car;
return;
}
if(c != ' ' && c != '\t' && c != '\n')
{
if(wordSize == arrSize)
{
reSize(car, arrSize, arrSize * 2);
}
*(car + wordSize) = c;
}
wordSize++;
}
is.setf(ios_base::skipws);
delete[] A;
A = car;
}
void printMessage(const char* word1, const char* word2, const char* message)
{
cout << message << endl;
cout << "word1: " << word1 << endl << "word2: " << word2 << endl;
}
I thought I got it all done just fine. Keep in mind that I added the "&" operator after each of the pointer parameters already. Here is how they were before:
void stringCopy(char *&A, char *B);
bool stringCompare(char *A, char *B);
void stringConcatenation(char *&A, char *B); //added const to make sure b
is never changed
int stringPosition(char *A, char B);
int stringLength(char *&A);
But, when I got to class, my teacher said we weren't allowed to change the function headers in any way. So, I am stuck passing by value for the assignment. The problem is that I have no way of changing the c-strings outside the editing functions now. Any changes I do to them stay inside there.
It all compiles just fine, and, if I make the pointers pass-by-reference, the program runs flawlessly. I am just wondering how I could change the values of the c-strings outside of the editing functions. This assignment is starting to become a pain (so many f***ing restrictions).
I think what your teacher wants you to do is to change the value at the character pointer instead of creating a new string.
So instead trying to reassigning parameter A to a new char* you change the value that A points to in memory. That way the method that called your function still points to that same memory and when they access that location the get the value you changed from within your function.
The following program aims to instantiate and use the singleton pattern class proposed by Loki Astari and accepted as answer at the following link.
C++ Singleton design pattern
Note the addition of a simple counter, by way of the private counter variable, along with the increment() mutator, and getCtr() accessor methods.
Expected program output is:
0
1
Press any key to exit...
The actual output is
0
0
Press any key to exit...
Why is the counter in the singleton class not being incremented as expected?
What follows is a minimal, complete, and verifiable program, written to illustrate the issue.
#include "stdafx.h"
#include <iostream>
#include <string>
class S {
public:
static S & getInstance() {
static S instance;
instance.counter = 0; // initialize counter to 0
return instance;
}
S(S const &) = delete;
void operator = (S const &) = delete;
void increment() { ++counter; }
int getCtr() { return counter; }
private:
S() {}
int counter;
};
int main() {
S * s; // s is a pointer to the singleton object
S * t; // t is another pointer to the singleton object.
std::cout << s->getInstance().getCtr() << std::endl;
s->getInstance().increment(); // increment counter
std::cout << t->getInstance().getCtr() << std::endl;
std::cout << "Press any key to exit...";
std::cin.get();
return 0;
}
Thx, Keith :^)
your problem is you are initializing the counter inside the
getInstance() method
instead, initialize it inside the constructor
your code should be like the following,
#include <iostream>
#include <string>
class S {
public:
static S & getInstance() {
static S instance;
// instance.counter = 0; // initialize counter to 0
return instance;
}
S(S const &) = delete;
void operator = (S const &) = delete;
void increment() { ++counter; }
int getCtr() { return counter; }
private:
S() {counter =0;}
int counter;
};
int main() {
S * s; // s is a pointer to the singleton object
S * t; // t is another pointer to the singleton object.
std::cout << s->getInstance().getCtr() << std::endl;
s->getInstance().increment(); // increment counter
std::cout << t->getInstance().getCtr() << std::endl;
s->getInstance().increment(); // increment counter
std::cout << t->getInstance().getCtr() << std::endl;
s->getInstance().increment(); // increment counter
std::cout << t->getInstance().getCtr() << std::endl;
s->getInstance().increment(); // increment counter
std::cout << t->getInstance().getCtr() << std::endl;
s->getInstance().increment(); // increment counter
std::cout << t->getInstance().getCtr() << std::endl;
std::cout << "Press any key to exit...";
std::cin.get();
return 0;
}
then the Output will be
0
1
2
3
4
5
Press any key to exit...
#include <iostream>
using namespace std;
class Money
{
public:
Money();
Money(int, int);
void setDollars(int d);
void setCents(int c);
int getDollars() const;
int getCents() const;
double getAmount(int, int);
private:
int dollars;
int cents;
};
Money::Money()
{
dollars = 0;
cents = 0;
}
Money::Money(int d, int c)
{
dollars = d;
cents = c;
}
void Money::setDollars(int d)
{
dollars = d;
}
void Money::setCents(int c)
{
if (c > 100)
{
c = c % 100;
dollars = dollars + (c / 100);
}
//update the dollars member if the cents input argument is 100 or larger.
cents = c;
}
int Money::getDollars() const
{
return dollars;
}
int Money::getCents() const
{
return cents;
}
double Money::getAmount(int d, int c)
{
return dollars + (cents / 100);
}
int main()
{
int dlr;
int cts;
//double amt;
cout << "Please input amount of dollars: ";
cin >> dlr;
cout << "Please input amount of cents: ";
cin >> cts;
Money money0(dlr, cts);
cout << "The money object1 has amount: " << money0.getDollars() << "." << money0.getCents() << endl;
cout << "The money object2 has amount: " << money0.getAmount() << endl;
//I try to call the functions to tell user how much is it
//use both ways to tell user how much is it(1.getDollars+getCents, 2. getAmount)
return 0;
system("pause");
}
When I try to call the get functions in the main, the errors show up. How to call those functions correctly?
Here is my assignment:
Define a class named Money that stores a monetary amount. The class should have two private integer variables, one to store the number of dollars and another to store the number of cents. Include a default constructor that initializes the amount to $0.00 and an overloaded parameterized constructor to initialize any non-zero amount(as demonstrated in the example program below).
I'm implementing the show Deal Or No Deal, there's a class 'box' which in the main file i used to store the random values of the boxes and than, i saved each box in the vector. im trying now to print in the screen the boxes saved in the vector whit the iterator,without succeeding, any help???
//random assignation of pound value to the 22 boxes
for (int e = 1; e < 23; e++)
{
int pos;
bool op = true;
while (op)
{
pos = rand();
if (pos > 0 && pos < 23)
{
if (myArray[pos][1] == 0)
{
myArray[pos][1] = 1;
op = false;
}
}
}
box b(e, myArray[pos][0]); //creating the class box
game_box.push_back(b); //function of the vector to insert a data in it
}
//show boxes
for (auto a = game_box.begin(); a!= game_box.end(); a++)
{
cout << *a << endl;
}
You first need to remove the dereference operator (*) from the a.
Next you need to add an output operator for box. Assuming that box is a class with member data member1 and member2 this would look something like:
friend std::ostream& operator<< (std::ostream &out, const box& b)
{
out << box.memeber1 << " " << box.member2;
}
The key point is that you need to define this operator for every class.
Once you've done that and got it working you might also like to look at this library which defines << operators for all stl containers. This lets you replace
for (auto a = game_box.begin(); a!= game_box.end(); a++)
{
cout << *a << endl;
}
by simply
cout << game_box << endl;
this works..
class Box
{
float pound_contained;
int box_number;
public:
Box(int box_number, float pound_contained);
int getbox_number();
float getpound_contained();
};
int Box::getbox_number()
{
return this->box_number;
}
float Box::getpound_contained()
{
return this->pound_contained;
}
main()
{
vector<Box> game_box;
Box* boxes = &game_box[i];
cout <<boxes->getbox_number()<<endl;
}
I've been working on a program that will do a couple of equations in regards to audio, SPL, etc.
I decided to have the main class file present the user with an option to choose what equation he wants to do, while the equations are housed in another class file.
Atm, the main class file is setup just to test maxPeakSPL(), yet I can't get it to run.
main.cpp
//Kh[a]os
#include "equations.h"
#include <iostream>
void mainLoop();
int maxSPL = 0;
int main()
{
std::cout << "Created by Kh[a]os" << std::endl << std::endl;
mainLoop();
return 0;
}
void mainLoop()
{
std::cout << "hi";
maxSPL = equations::maxPeakSPL();
std::cout << std::endl << maxSPL << "db" << std::endl << std::endl;
}
equations.h
#ifndef EQUATIONS_H
#define EQUATIONS_H
#include <string>
class equations
{
public:
equations();
static int maxPeakSPL();
protected:
private:
};
#endif // EQUATIONS_H
equations.cpp
#include "equations.h"
#include <iostream>
#include <string>
equations::equations()
{
}
static int maxPeakSPL()
{
int Sens = 0;
double Distance = 0;
int Watts = 0;
int sWatts = 2;
int eWatts = 0;
double maxSPL = 0;
double counter = 0;
double wall = 0;
std::string corner = "";
bool v = true;
std::cout << "Sensitivity (db): " << std::endl;
std::cin >> Sens;
std::cout << "Amplification (watts): " << std::endl;
std::cin >> Watts;
std::cout << "Listening Distance (meters): " << std::endl;
std::cin >> Distance;
std::cout << "Distance from Wall (ft): " << std::endl;
std::cin >> wall;
std::cout << "Are you they in a corner? (y/n): " << std::endl;
std::cin >> corner;
maxSPL = Sens - (Distance*3 - 3);
while(v == true)
{
if (sWatts > Watts)
{
v = false;
eWatts = sWatts;
sWatts = sWatts/2;
Watts = Watts-sWatts;
counter = (double)Watts/(double)eWatts;
counter = counter*3;
maxSPL = maxSPL + counter;
}
if (v == true)
{
maxSPL = maxSPL + 3;
sWatts = sWatts*2;
}
}
if (wall <= 4)
maxSPL = maxSPL + 3;
if (corner == "Y" || corner == "YES" || corner == "y" || corner == "yes")
maxSPL = maxSPL + 3;
return maxSPL;
}
The error I get when I run it is: undefined reference to `equations::maxPeakSPL()'
I haven't a clue how to fix this, any assistance would be great. Thank you.
In your main, try putting the function before the main block. Include an underscore before the name of your directives/flags.