Error C2228 In a Simple Counter Program C++ - c++

First time here, so forgive me if I'm not entirely following protocol. I will adjust as is necessary. I'm trying to make a simple program that increments (or decrements) through a counter. The counter's functions are through a class, and I'm trying to use the main for testing for functionality. I could very easily be missing something super simple, as is always the case with me, but I can't figure it out so I figured I'd ask here, since I've come here very often finding help easily. I've tried sifting through answers and nothing has been helping so far. Here's the code:
#include <iostream>
using namespace std;
class counter
{
public:
counter();
counter(int begin, int maximum);
void increment();
void decrement();
int getter();
private:
int count;
int max;
};
// Default constructor.
counter::counter()
{
count = 0;
max = 17;
}
// Constructor that allows you to put in a starting point for the counter
// and a maximum value for the counter.
counter::counter(int begin, int maximum)
{
max = maximum;
if (begin > maximum)
{
cout << "You input an invalid value to begin. Set to default.";
count = 0;
}
else
{
count = begin;
}
}
// Increments counter by one. If counter would exceed max, then goes to 0.
void counter::increment()
{
if (count == max)
{
count = 0;
}
else
{
count++;
}
}
// Decrements counter by one. If counter we go below 0, then goes to max.
void counter::decrement()
{
if (count == 0)
{
count = max;
}
else
{
count--;
}
}
// Getter for counter value.
int counter::getter()
{
return count;
}
int main()
{
counter test();
for (int i = 0; i < 20; i++)
{
test.increment();
cout << test.getter() << "\n";
}
}
The error that's appearing is:
"dsCh2Exercise.cpp(81): error C2228: left of '.increment' must have
class/struct/union dsCh2Exercise.cpp(82): error C2228: left of
'.getter' must have class/struct/union"
Thanks ahead of time for any and all input! It's greatly appreciated!

counter test(); declares a function named test that takes no arguments and returns a counter, not a variable named test that contains a counter. Change that line to:
counter test;

Related

Member variable resetting back to 0

When running through the test the count variable from the class stack1 gets reset back to 0 when using its pop function. Strangely however, during the push loop, the count increases as intended but when pop occurs, the count gets reset back to 0 and subtracts into the negatives from there. Is there something I'm forgetting?
#include <iostream>
using namespace std;
class TheStack
{
public:
TheStack();
void push(int);
int pop();
bool isEmpty();
private:
const int MaxSize = 10;
int arr[10];
int count;
};
TheStack::TheStack()
{
count = 0;
}
void TheStack::push(int userInput)
{
if (count >= MaxSize)
{
cout << "Stack is full." << endl;
}
else
{
arr[count] = userInput;
count+=1;
}
}
int TheStack::pop()
{
if (isEmpty())
{
cout << "Stack is empty." << endl;
}
else
{
int temp = arr[count];
arr[count] = NULL;
count-=1;
return temp;
}
}
bool TheStack::isEmpty()
{
if (count == 0)
{
return true;
}
else
{
return false;
}
}
int main()
{
TheStack stack1;
if (stack1.isEmpty())
{
cout << "isEmpty() works" << endl;
}
stack1.pop();
for (int i = 0; i < 10; i++)
{
stack1.push(i);
}
stack1.push(0);
stack1.pop();
stack1.pop();
stack1.pop();
stack1.pop();
system("pause");
}
When you do push you first save the data into the array and then increment count. This means that in order to properly do pop you need to work in reverse: first decrement count and only then read data from the array.
But in the code you are doing it backwards. When the stack is full, count is at max value (10 in your case), and your arr[count] = NULL; writes beyond the array boundary. This causes undefined behavior and, in particular, destroys your count value. (This is why it suddenly becomes 0.)
Also:
arr[count] = NULL; makes no sense. NULL is supposed to be used in pointer contexts, not in integer contexts. This is not even guaranteed to compile.
What is the point of that anyway? Initially your array contains garbage above the current top of the stack. Why do you suddenly care to clean it up after doing pop?
Not all control paths of pop() return value. This is undefined behavior in itself.
const int MaxSize = 10; in the class definition is a C++11 feature. Since you are already using C++11, you can do the same for count. Just do int count = 0; right inside the class definition and you will not have to write the constructor explicitly.
Although in your implementation MaxSize would make more sense as a static const class member. In that case you'll also be able to declare your array as int arr[MaxSize];.
You must first decrease count and then access arr[count] in int TheStack::pop(). Now you get access above the last pushed element, event out of bound of array if the stack is full.

How do I return value to main function without directly calling the function

I have multiple functions in my program. Each function has some conditions. If conditions are met, then it passes on the value to another function which again checks the value with some conditions, modifies it.
The first function [named 'squarefree()'] is called from main [obviously] and it further goes on to call another function which in course calls another function untill the process stops at last function named 'end()'. Like this:
#include <iostream>
using namespace std;
int squarefree(int n);
int goodnumber(int sf);
int end(int gn);
int main() {
// your code goes here
int l,r;
cin>>l;
cin>>r;
for(int p=l;p<=r;p++)
{squarefree(p);}
/*int ret=end(int gn); PROBLEM LIES HERE
cout<<ret; */
return 0;
}
int squarefree(int n){
int i;
for(int i=2;i<n;i++)
{
if((n%(i*i))==0)
{
cout<<"number not square free"<<endl;
break;
}
else{
cout<<"number square free"<<endl;
goodnumber(n);
break;
}
}
return 0;
}
int goodnumber(int sf){
cout<<"Sf is:"<<sf<<endl;
int s=0,c=0,flag=0;
for(int j=1;j<=sf;j++)
{
if(sf%j==0)
{
s+=j;
for(int k=2;k<=j/2;++k)
{
if(j%k==0)
{
c++;
}
}
}
}
cout<<"s is:"<<s<<endl;
cout<<"no.of prime numbers dividin s are:"<<c<<endl;
for(int l=2;l<=c/2;++l)
{
if(c%l==0)
{
flag=1;
break;
}
}
if (flag==0)
{cout << "C is a prime number, so this is good number and needs to be passed to next function"<<endl;
end(s);
}
else
{cout << "C is not a prime number"<<endl;
}
return 0;
}
int end(int gn)
{
int sum=0;
sum+=gn;
cout<<"SUm of factors of the good number is:"<<sum<<endl;
return sum;
}
The 'end()' function returns a value sum. Now I want this value sum to be updated everytime the for loop in main() function runs. For example: Sum in first iterations is 5, sum is 2nd iteration is 10, so total sum gets 15 and so on.
If somehow, the value returned by end function can be fetched into main function, that would be great.
Look at all those int-returning functions that are always returning 0. You might be able to take advantage of that.
A trivial example:
#include <iostream>
int step3(int val)
{
return val * val;
}
int step2(int val)
{
return step3(val + 1);
}
int step1(int val)
{
return step2(val * 2);
}
int main()
{
std::cout << step1(1);
}
But take care. You might find a case where you don't get any valid results and need to inform the caller that no result was found.
In addition to the idea of having the functions return the result of the next stage in the pipeline, which is an excellent idea, you can pass the address of the variable in which to store the result (allowing you to return more than one result, or an error code), or store the result of each stage in a temporary variable and return that (allowing you to use a result in more than one computation). I would advise against using a global variable to bypass the stack; it’s considered poor practice.
Some Examples:
// Returning the result of the next stage in the pipeline:
int g(int);
int f(int x)
{
return g(x);
}
// Passing a variable by reference:
enum errcode { success, failure };
errcode sqr( int input, int& output )
{
output = input * input; // This modifies the second variable the caller gave.
return success;
}
// Storing in a temporary variable:
int stage2(int);
int stage1(int x)
{
const int y = stage2(x); // Store the result in a temporary.
const int z = sqr(y);
return z;
}
// Passing results through a global variable is a bad idea:
int necessary_evil = 0; // Declared in global scope; should at least be
// declared static if possible to make it visible only in this source file.
// Namespaces are a fancier way to do something similar.
void kludge(int x)
{
necessary_evil = x * x; // The caller will check the global.
return;
}
There are examples of all of these in the standard library: printf() is essentially a wrapper for vfprintf(), strtol() takes a parameter by reference that the function sets to a pointer to the remainder of the string, and errno is a global variable.

How to limit a decrement?

There is a initial game difficulty which is
game_difficulty=5 //Initial
Every 3 times if you get it right, your difficulty goes up to infinity but every 3 times you get it wrong, your difficulty goes down but not below 5. So, in this code for ex:
if(user_words==words) win_count+=1;
else() incorrect_count+=1;
if(win_count%3==0) /*increase diff*/;
if(incorrect_count%3==0) /*decrease difficulty*/;
How should I go about doing this?
Simple answer:
if(incorrect_count%3==0) difficulty = max(difficulty-1, 5);
But personally I would wrap it up in a small class then you can contain all the logic and expand it as you go along, something such as:
class Difficulty
{
public:
Difficulty() {};
void AddWin()
{
m_IncorrectCount = 0; // reset because we got one right?
if (++m_WinCount % 3)
{
m_WinCount = 0;
++m_CurrentDifficulty;
}
}
void AddIncorrect()
{
m_WinCount = 0; // reset because we got one wrong?
if (++m_IncorrectCount >= 3 && m_CurrentDifficulty > 5)
{
m_IncorrectCount = 0;
--m_CurrentDifficulty;
}
}
int GetDifficulty()
{
return m_CurrentDifficulty;
}
private:
int m_CurrentDifficulty = 5;
int m_WinCount = 0;
int m_IncorrectCount = 0;
};
You could just add this as a condition:
if (user words==words) {
win_count += 1;
if (win_count %3 == 0) {
++diff;
}
} else {
incorrect_count += 1;
if (incorrect_count % 3 == 0 && diff > 5) {
--diff
}
}
For example:
if(win_count%3==0) difficulty++;
if(incorrect_count%3==0 && difficulty > 5) difficulty--;
This can be turned into a motivating example for custom data types.
Create a class which wraps the difficulty int as a private member variable, and in the public member functions make sure that the so-called contract is met. You will end up with a value which is always guaranteed to meet your specifications. Here is an example:
class Difficulty
{
public:
// initial values for a new Difficulty object:
Difficulty() :
right_answer_count(0),
wrong_answer_count(0),
value(5)
{}
// called when a right answer should be taken into account:
void GotItRight()
{
++right_answer_count;
if (right_answer_count == 3)
{
right_answer_count = 0;
++value;
}
}
// called when a wrong answer should be taken into account:
void GotItWrong()
{
++wrong_answer_count;
if (wrong_answer_count == 3)
{
wrong_answer_count = 0;
--value;
if (value < 5)
{
value = 5;
}
}
}
// returns the value itself
int Value() const
{
return value;
}
private:
int right_answer_count;
int wrong_answer_count;
int value;
};
And here is how you would use the class:
Difficulty game_difficulty;
// six right answers:
for (int count = 0; count < 6; ++count)
{
game_difficulty.GotItRight();
}
// check wrapped value:
std::cout << game_difficulty.Value() << "\n";
// three wrong answers:
for (int count = 0; count < 3; ++count)
{
game_difficulty.GotItWrong();
}
// check wrapped value:
std::cout << game_difficulty.Value() << "\n";
// one hundred wrong answers:
for (int count = 0; count < 100; ++count)
{
game_difficulty.GotItWrong();
}
// check wrapped value:
std::cout << game_difficulty.Value() << "\n";
Output:
7
6
5
Once you have a firm grasp on how such types are created and used, you can start to look into operator overloading so that the type can be used more like a real int, i.e. with +, - and so on.
How should I go about doing this?
You have marked this question as C++. IMHO the c++ way is to create a class encapsulating all your issues.
Perhaps something like:
class GameDifficulty
{
public:
GameDifficulty () :
game_difficulty (5), win_count(0), incorrect_count(0)
{}
~GameDifficulty () {}
void update(const T& words)
{
if(user words==words) win_count+=1;
else incorrect_count+=1;
// modify game_difficulty as you desire
if(win_count%3 == 0)
game_difficulty += 1 ; // increase diff no upper limit
if((incorrect_count%3 == 0) && (game_difficulty > 5))
game_difficulty -= 1; //decrease diff;
}
inline int gameDifficulty() { return (game_difficulty); }
// and any other access per needs of your game
private:
int game_difficulty;
int win_count;
int incorrect_count;
}
// note - not compiled or tested
usage would be:
// instantiate
GameDiffculty gameDifficulty;
// ...
// use update()
gameDifficulty.update(word);
// ...
// use access
gameDifficulty.gameDifficulty();
Advantage: encapsulation
This code is in one place, not polluting elsewhere in your code.
You can change these policies in this one place, with no impact to the rest of your code.

Sorted list: must have class/struct/union

so i have been working on a code for over two weeks and its not going too well. here are the instructions and the code is below it, as well as errors:
Task 1: Create one instance of this class. (the sorted list; he also had other instructions on HOW to start the code, but its already been done by me below in the code such as typedef...) You also need to read in data from one data file: float.dat, which contains the following numbers:
5.5
6.2
7.1
8.0
9.0
10.0
1.0
2.0
3.3
4.4
Data in float.dat contains floating numbers, which should be inserted into the object of SortedList. Note that you do not have any prior knowledge about data values in float.dat, but we assume that there are 10 elements in the data file.
Task 2: Use GetNextItem( ) to print out all the elements in the list in sorted sequence on computer screen.
Task 3: Use GetNextItem( ) to output all the elements in the list in sorted sequence onto a data file, output.dat.
Task 4: Design your test cases to demonstrate InsertItem( ), DeleteItem( ) and RetrieveItem( ) are working as expected.
here is the code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
#define MAX_ITEMS 10
typedef float ItemType;
class SortedList
{
private:
int length;
ItemType values[MAX_ITEMS];
int currentPos;
enum RelationType { LESS, GREATER, EQUAL };
public:
SortedList() {length = 0; currentPos = -1;}
int getLength() {return length;}
RelationType ComparedTo(ItemType x)
{
if (length > x.getLength())
return LESS;
else if (length == x.getLength())
return GREATER;
else
return EQUAL;
}
void MakeEmpty() {length = 0;}
void InsertItem(ItemType x)
{
int first = 0, last = length --;
bool moreToSearch = (first <= last);
int location = 0;
int midpoint= (first + last) / 2;
while (moreToSearch)
{
switch (x.ComparedTo(values[location]))
{
case LESS: //search in 1st half
moreToSearch = (first <= last);
break;
case GREATER:
location++;
moreToSearch = (location < length);
break;
}
}
for (int index = length; length > location; index--)
{
values[index] = values[index - 1];
}
values[location] = x;
length++;
}
void DeleteItem(ItemType x)
{
int location = 0;
while (x.ComparedTo(values[location]) != EQUAL)
location++;
for (int index = location ++; index < length; index++)
values[index --] = values[index];
length--;
}
void RetrieveItem(ItemType &x, bool & found)
{
int midpoint;
int first = 0, last = length - 1;
bool moreToSearch = (first <= last);
found = false;
int index = 0;
while (moreToSearch && !found)
{
midpoint = (first + last) / 2;
switch (x.ComparedTo(values[index++]))
{
case LESS: //search in 1st half
moreToSearch = (first <= last);
last = midpoint - 1;
break;
case GREATER: //Search in 2nd half
first = midpoint + 1;
moreToSearch = (first <= last);
break;
case EQUAL: //x has been found
found = true;
break;
}
}
}
int LengthIs() {return length;}
void ResetList() {currentPos = -1;}
bool IsFull()
{
if (length < 9)
return false;
else
return true;
}
void GetNextItem(ItemType &x)
{
currentPos++;
x = values[currentPos];
cout << x;
}
};
int main()
{
SortedList x;
ifstream inFile; ofstream output;
string line;
bool allAboutLists;
int i = 0;
int size = 0;
inFile.open("float.txt");
float values[10];
while (!inFile.eof()) // write or read data from inFile into values
{
inFile >> values[i];
i++;
size++; // this will count how many values there are in the array
x.InsertItem(values[i]);
++i;
}
x.ResetList();
cout << "The following is the list that's been made:" << endl << endl;
x.InsertItem(64);
//x.printlist();
cout << endl;
x.DeleteItem(64);
//x.printlist();
x.RetrieveItem(7.1, allAboutLists);
cout << endl;
cout << endl << "The length is: "; x.LengthIs(); cout << endl;
cout << "Is the list full?: " << boolalpha << x.IsFull() << endl;
cout << "The next item is: ";
for (int i = 0; i < 10; i++)
{
cout << x.GetNextItem << endl;
}
x.ResetList();
inFile.close();
output.open("output.txt");
for (int f = 0; f < 10; f++)
{
output << x.GetNextItem << endl;
}
system("pause");
return 0;
}
and the compiler keeps saying this:
(25) error C2228: left of '.getLength' must have class/struct/union [they mean the x. its red lined under, same for the rest of those left of etc..]
(27) error C2228: left of '.getLength' must have class/struct/union
(44) error C2228: left of '.ComparedTo' must have class/struct/union
(66): error C2228: left of '.ComparedTo' must have class/struct/union
-and also, 7.1 in main has something about refernce type mistake.
I am in extereme hurry as i have been working on it for 2 weeks now and its driving me crazy ! I have the code done as seen and more than wnough and just need to know what to change exactly because I am following everything I have been searching and researching yet its no good. so precise details or code specifically taken from mine and fixed would be appreciated.
Thanks!
You are passing x as ItemType which is a float.
float doesn't have those methods... looks like you wanted to pass it as a SortedList
The compare function needs two parameters in order to do a compare. Instead of ComparedTo, you may want to call it CompareToLocation.
RelationType CompareToLocation(ItemType x, size_t location){
if(x < values[location]) return LESS;
if(x == values[location]) return EQUAL;
return GREATER;}
An example usage would be:
result = CompareToLocation(x, location);
// ...
You defined ComparedTo as a method for SortedList, yet everytime you call that function, you call it on ItemType objects, which are actually floats.
As you can see in the definition of the method, you are trying to use, once again, SortedList methods on float Objects:
RelationType ComparedTo(ItemType x)
{
if (length > x.getLength())
return LESS;
else if (length == x.getLength())
return GREATER;
else
return EQUAL;
}
Your problem is not really a compiling one, but a conceptual one, since you don't seem to grasp what your are actually coding.
I'd recommend have your declarations and implementations separate, so you can see at a glance how does your class work.
Your class declaration should look something like this:
class SortedList
{
private:
int length;
ItemType values[MAX_ITEMS];
int currentPos;
enum RelationType { LESS, GREATER, EQUAL };
public:
SortedList();
int getLength();
RelationType ComparedTo(ItemType x) ;
void MakeEmpty();
void InsertItem(ItemType x) ;
void DeleteItem(ItemType x);
void RetrieveItem(ItemType &x, bool & found);
int LengthIs();
void ResetList();
bool IsFull();
void GetNextItem(ItemType &x);
};
You should focus on each method, making clear what each one of them is trying to achieve, and what does it need to achieve it (parameters).
For example:
RelationType ComparedTo(ItemType x) ;
Your SortedList class has this function, which receives an ItemType (float) as a parameter.
What is this trying to achieve? How do you compare a whole ordered list to a single element?
How can a single number be greater, less or EQUAL to a set of numbers?
Maybe what you really want to do is compate parameter X with an element inside the list?
If this is the case, how do you know which element in the list must be compared to parameter X? You should add another parameter telling you which element inside your ordered list to compare X to.
I quess this doesn't really solve your problem, but at least I hope this helps you understand better what your problem is.

C++ Priority Queue, logical error, can't figure out

I'm implementing a simple priority queue in C++.
However when it runs, it prints out gibberish numbers.
Am I somehow trying to access invalid entries in the array in my code?
Below is the code.
Also, is my "remove" function somehow not doing its job? Conceptually, shall I be putting null into the first entry and return whatever was just erased?
Thanks.
[Priority.h]
#ifndef Priority_h
#define Priority_h
class Priority
{
public:
Priority(void);
Priority(int s);
~Priority(void);
void insert(long value);
long remove();
long peekMin();
bool isEmpty();
bool isFull();
int maxSize;
long queArray [5];
int nItems;
private:
};
#endif
[Priority.cpp]
#include <iostream>
#include <string>
#include <sstream>
#include <stack>
#include "Priority.h"
using namespace std;
Priority::Priority(void)
{
}
Priority::Priority(int s)
{
nItems = 0;
}
Priority::~Priority(void)
{
}
void Priority::insert(long item)
{
int j;
if(nItems==0) // if no items,
{
queArray[0] = item; nItems++;
}// insert at 0
else // if items,
{
for(j=nItems-1; j=0; j--) // start at end,
{
if( item > queArray[j] ) // if new item larger,
queArray[j+1] = queArray[j]; // shift upward
else // if smaller,
break; // done shifting
} // end for
queArray[j+1] = item; // insert it
nItems++;
} // end else (nItems > 0)
}
long Priority::remove()
{
return queArray[0];
}
long Priority::peekMin()
{
return queArray[nItems-1];
}
bool Priority::isEmpty()
{
return (nItems==0);
}
bool Priority::isFull()
{
return (nItems == maxSize);
}
int main ()
{
Priority thePQ;
thePQ.insert(30);
thePQ.insert(50);
thePQ.insert(10);
thePQ.insert(40);
thePQ.insert(20);
while( !thePQ.isEmpty() )
{
long item = thePQ.remove();
cout << item << " "; // 10, 20, 30, 40, 50
} // end while
cout << "" << endl;
system("pause");
}
Here is one error:
for(j=nItems-1; j=0; j--) // start at end,
^ this is assignment, not comparison.
I am also not convinced that there isn't an off-by-one error in
queArray[j+1] = item; // insert it
Finally, your default constructor fails to initialize nItems.
There could be further errors, but I'll stop at this.
I agree with the other answers here, but I would add this:
Your "Remove" method isn't actually removing anything - it is just returning the first element - but it doesn't do anything to the array itself.
Edited to say that your insert method needs some work - it may or may not write over the end of the array, but it is certainly confusing as to what it is doing.
Try initializing your queue array in the constructor.