Setting an array of bits - c++

I'm writing a program for my OO class and I'm having some trouble with my cout statements. The program is supposed to take in a value and convert it to a bitwise array. My problem is that no matter what number I put in it couts every element in the array to 0. The assignment said to initialize every element to 0 in the constructor, but when comparing it to the & operator in the Query function it can only return false. Any suggestions? (Note: we can't use vectors or any of the premade functions.)
in header file:
private:
static const CSIZE = 8 * sizeof(char);
int arraySize;
unsigned char* barray;
in .cpp file
#include <iostream>
#include "bitarray.h"
using namespace std;
ostream& operator<< (ostream& os, const BitArray& a)
{
for (unsigned int i = 0; i < a.arraySize * a.CSIZE; i++)
os << a.Query(i);
return os;
}
BitArray::BitArray(unsigned int n)
{
if (n % CSIZE != 0)
arraySize = (n / CSIZE) + 1;
else
arraySize = n / CSIZE;
barray = new unsigned char[arraySize];
for (int i = 0; i < arraySize; i++)
barray[i] = 0;
}
unsigned char BitArray::Mask (unsigned int num) const
{
return (1 << num % CSIZE);
}
void BitArray::Set (unsigned int index)
{
unsigned int i = index / CSIZE;
barray[i] |= Mask (index);
}
bool BitArray::Query (unsigned int index) const
{
unsigned int i = index / CSIZE;
if (barray[i] & Mask (index))
return true;
return false;
}
Main program:
#include <iostream>
using namespace std;
#include "sieve.h"
#include "bitarray.h"
int main()
{
unsigned int i, max, counter = 0;
cout << "\nEnter a positive integer for the maximum value: ";
cin >> max;
BitArray ba(max);
Sieve(ba); // find the primes (marking the bits)
cout << "The bit array looks like this: \n"
<< ba
<< '\n';
cout << "\nPrimes less than " << max << ':' << '\n';
for (i = 0; i < max; i++)
{
if (ba.Query(i))
{
counter++;
cout << i;
if (counter % 8 == 0)
{
cout << '\n';
counter = 0;
}
else
cout << '\t';
}
}
cout << "\nGoodbye!\n";
return 0;
}

Related

Getting out of range exception when using while loop with vector in c++

I am getting an out of range exception with my while loop in my code.
I have tried to use an Array instead and the error does not occur with the same loop structure. I am confused why this would happen. I believe that the savedValue <= value[rank.at(current-1)]) statement is what is causing the error.
int suffixArray::size;
std::vector<int> suffixArray::rank;
int main( int argc, char* argv[]) {
std:: string test = "BANANA$";
suffixArray testString (test);
return 0;
}
#include <iostream>
#include <vector>
class suffixArray{
public: static int size;
public: static std::vector<int> rank;
public: suffixArray(std:: string concatenated ){
size =(int) concatenated.length();
std:: cout << size << std:: endl;
rank.resize(7);
char *suffixPointers[concatenated.length()];
int value[concatenated.length()];
for(int i =0; i <= size-1; i++){
suffixPointers[i] = &concatenated[i];
value[i] = (int)concatenated[i];
}
std::cout << "[";
for(int i = 0; i<= size-1; i++){
std::cout <<value[i] << " ";
}
std::cout << "]"<< std:: endl;
for(int i = 0; i<=size -1; i++){
if(i == 0){
rank.assign(i,i);
}
else if(value[i] > value[i-1]){
rank.assign(i,i);
}else{
int current =i;
int savedValue = value[i];
int prevSavedRank;
while(current-1 >= 0 && savedValue <= value[rank.at(current-1)]){
prevSavedRank= rank.at(current-1);
rank.assign(current-1, i);
rank.assign(current, prevSavedRank);
current--;
}
}
}
}
};
Adding more logging into your program reveals the problem: you rank.assign(0,0) - the first 0 specifies the new vector length, so this call removes all the elements in the vector (see std::vector::assign docs at cppreference) then call rank.at(0): 0 is not a valid index into an empty vector, so std::out_of_range.
You'll have to rethink your logic.
Program with extra logging:
#include <iostream>
#include <vector>
template <typename T>
struct Vector : std::vector<T>
{
void assign(size_t count, const T& value)
{
std::cout << "assign(count " << count << ", " << value << ")\n";
std::vector<T>::assign(count, value);
}
const T& at(size_t pos) const
{
std::cout << "at(" << pos << ")\n";
return std::vector<T>::at(pos);
}
};
class suffixArray{
public: static int size;
public: static Vector<int> rank;
public: suffixArray(std:: string concatenated ){
size =(int) concatenated.length();
std:: cout << size << std:: endl;
rank.resize(7);
char *suffixPointers[concatenated.length()];
int value[concatenated.length()];
for(int i =0; i <= size-1; i++){
suffixPointers[i] = &concatenated[i];
value[i] = (int)concatenated[i];
}
std::cout << "[";
for(int i = 0; i<= size-1; i++){
std::cout <<value[i] << " ";
}
std::cout << "]"<< std:: endl;
for(int i = 0; i<=size -1; i++){
if(i == 0){
rank.assign(i,i);
}
else if(value[i] > value[i-1]){
rank.assign(i,i);
}else{
int current =i;
int savedValue = value[i];
int prevSavedRank;
while(current-1 >= 0 && savedValue <= value[rank.at(current-1)]){
prevSavedRank= rank.at(current-1);
rank.assign(current-1, i);
rank.assign(current, prevSavedRank);
current--;
}
}
}
}
};
int suffixArray::size;
Vector<int> suffixArray::rank;
int main( int argc, char* argv[]) {
std:: string test = "BANANA$";
suffixArray testString (test);
}
Output:
7
[66 65 78 65 78 65 36 ]
assign(count 0, 0)
at(0)
terminate called after throwing an instance of 'std::out_of_range'
what(): vector::_M_range_check: __n (which is 0) >= this->size() (which is 0)
I have tried to use an Array instead and the error does not occur with the same loop structure.
std::array and C-style arrays (T[]) are fixed sized containers, lacking an equivalent of the std::vector::assign you're using to resize your vector, so your program must have been modified quite heavily - not just a clean substitution of an array.

Dynamic allocation of an array into a function with pointer parameters

I am having issues finishing passing an array via pointers through a series of functions. I create a function using dynamic allocation to create it. Even though that is successful I cannot get it to pass through functions that take pointers as arguments. The functions return the mean median and mode and have been completed. However I cannot pass them when converting them into pointer syntax. Thanks for the help in advance.
#include <iostream>
#include <cstdlib>
using namespace std;
int students;
int * studentarray;
int stumode;
double stuavg;
int stumed;
int arr;
int mode(int *[], int );
double average(int *[], int);
double median(int *[], int);
void selectSort(int [], int);
void swap(int *, int *);
int makeArray(int*, int);
int main()
{
studentarray = &arr;
cout << "How many students are there?" << endl;
cin >> students;
makeArray(studentarray, students);
for (int i = 0; i < students; i++) {
cout << "How many movies did student " << i + 1 << " view?" << endl;
cin >> studentarray[i];
}
selectSort(studentarray, students);
stumode = mode(&studentarray, students);
stuavg = average(&studentarray, students);
stumed = median(&studentarray, students);
cout << "The array has been sorted in ascending order." << endl;
cout << "The mode is " << stumode << "." << endl;
cout << "The mean is " << stuavg << "." << endl;
cout << "The median is " << stumed << "." << endl;
delete[] studentarray;
return 0;
}
int mode(int *arr, int size)
{
if (size <= 0) return 0;
int most = 0, position = 0, most_count = 0;
int counter = 1;
for (int i = 1; i < size; i++)
{
if (* (arr + i) != * (arr + position) )
{
if (counter > most)
{
most = counter;
most_count = 0;
}
else if (counter == most) most_count++;
position = i;
counter = 0;
}
else counter++;
}
if (most_count) return 0;
else return * ( arr + position );
}
double average(int *arr, int size)
{
if (size <= 0) return 0;
int total = 0;
for (int i = 0; i < size; i++) {
total += *(arr + i);
}
return (double)total / size;
}
double median(int *arr, int size)
{
if (size <= 0) return 0;
if (size % 2 == 0)
return (double) (* (arr + (size + 1) / 2));
else {
int mid = size / 2;
return (double)(* (arr + mid) + * (arr + mid + 1) / 2);
}
return 0;
}
void selectSort(int arr[], int size)
{
int min;
for (int i = 0; i < size - 1; i++)
{
min = i;
for (int j = i + 1; j < size; j++)
{
if ( arr[j] < arr[min])
{
min = j;
}
}
swap(&arr[min], &arr[i]);
}
}
void swap(int *one, int *two) {
int temp = *one;
*one = *two;
*two = temp;
}
int makeArray(int *arr, int size)
{
arr = new int[size];
return *arr;
}
Your implementation of makeArray is not right.
int makeArray(int *arr, int size)
{
// Allocates memory and assigns it to arr.
// This is a local change to arr. The value of the variable in
// main remains unchanged.
arr = new int[size];
// Returns an uninitialized value.
return *arr;
// The memory allocated in the previous line is now a memory leak.
}
You can make it simpler by using:
int* makeArray(int size)
{
return new int[size];
}
and use it in main as:
arr = makeArray(students);
However, I don't see how that is better than using:
arr = new int[students];
If you do that, makeArray becomes unnecessary. If makeArray needs to have additional code to fill up the array with some values, it will be useful. Otherwise, it does not add any useful functionality to your program.
Having said all of that, it is better to use std::vector instead of managing dynamically allocated memory in your own code. You would use:
std::vector<int> arr(students);
PS
I did not go through rest of your code. There might be other errors.

Trying to convert C++ binary array to hexadecimal then print results

I'm wanting to print an int array with 8 bytes and convert it to bin & hex with the output as such:
0 00000000 00
1 00000001 07
...
I've finished creating the binary convert function. I want to use the same function as the binary conversion -with an array, but check the left half with the right half and solve each different sided of the 8 bytes; left most -3 and right most is -7.
What am I doing wrong? I cannot figure out how to implement it and I know my hex function is all out of wack.
#include <iostream>
#include <string>
#include <math.h>
using namespace std;
const int num = 8; //may not be needed -added for hex
void Generatebinary(int arr[]);
void GeneratehexDec(int arr[]);
void print_binary(int arr[]); //haven't created yet
int main()
{
int arr[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
int i = 1;
while (i < 256)
{
Generatebinary(arr);
print_binary(arr); //not created yet
GeneratehexDec(arr);
i++;
}
}
void Generatebinary(int arr[])
{
for (int i = 7; i > 0; i--)
{
if (arr[i] == 1)
arr[i] = 0;
else if (arr[i] == 0)
{
arr[i] = 1;
break;
}
}
}
void GereatehexDec(int num)
{ //improper use
int a;
int i;
int answer[] = { };
a = num % 16;
i++;
answer[i] = num;
for (int i = num; i > 0; i--)
{
cout << answer[i];
}
cout << a;
}
First of all, you can't do int answer[] = { }; an array has to be pre-allocated (indicating how many elements it will store) or has to be dynamically allocated during run-time, then be freed, you have to manage your memory, not forget to deallocate... It's for this reason that Stroustrup tells you to not use arrays unless necessary. Use std::vector
void GereatehexDec(int num)
{ //improper use
int a = 0; // always initialize your variables
int i = 0; // is this i supposed to be the same as the i in the for loop below?
std::vector<int> answer;
a = num % 16;
i++; // this doesn't make sense
answer.at(i) = num;
for (int i = num; i > 0; i--) // what about the i variable you declared previously?
{
cout << answer.at(i);
}
cout << a;
}
Here's a template function that could help you (converts numbers into string hex)
template <typename I> std::string n2hexstr(I w, size_t hex_len = sizeof(I) << 1) {
static const char* digits = "0123456789ABCDEF";
std::string rc(hex_len, '0');
for (size_t i = 0, j = (hex_len - 1) * 4; i<hex_len; ++i, j -= 4)
rc[i] = digits[(w >> j) & 0x0f];
return "0x" + rc;
}
int main() {
std::cout << n2hexstr(127);
}

Inputting the amount you want displayed in the array

I am writing a program that displays integer arrays. I set the size of the array, but I am wondering how I can ask the user the index of the array that they want listed. Say the const SIZE = 10, and the user wants to see the first three in the array. I want to also write an exception that catches the error if the user input is over the size of the array. If you need to see some code, let me know. Any help is appreciated!
intergerarray.h
class IntArray
{
private:
int *aptr; // Pointer to the array
int arraySize; // Holds the array size
void subscriptError(); // Handles invalid subscripts
public:
class OutOfBoundException
{
public:
int index;
OutOfBoundException(){};
int getInde() { return index; }
};
IntArray(int); // Constructor
IntArray(const IntArray &); // Copy constructor
~IntArray(); // Destructor
int size() const // Returns the array size
{
return arraySize;
}
int &operator[](const int &); // Overloaded [] operator
};
IntergerArray.cpp
IntArray::IntArray(int s)
{
arraySize = s;
aptr = new int[s];
for (int count = 0; count < arraySize; count++)
*(aptr + count) = 0;
}
IntArray::IntArray(const IntArray &obj)
{
arraySize = obj.arraySize;
aptr = new int[arraySize];
for (int count = 0; count < arraySize; count++)
*(aptr + count) = *(obj.aptr + count);
}
IntArray::~IntArray()
{
if (arraySize > 0)
delete[] aptr;
}
void IntArray::subscriptError()
{
cout << "ERROR: Subscript out of range.\n";
exit(0);
}
int &IntArray::operator[](const int &sub)
{
if (sub < 0 || sub >= arraySize)
subscriptError();
return aptr[sub];
}
driver file.cpp
int main()
{
int SIZE = 10;
//int index;
//cout << "enter an index";
//cin >> index;
IntArray table(SIZE);
for (int x = 0; x < SIZE; x++)
table[x] = x;
for (int x = 0; x < SIZE; x++)
cout << table[x] << " ";
cout << endl;
//table[SIZE + 1] = 0;
return 0;
}
Isn't this what you are trying to do? why so much code for such a simple problem?
const int arraySize = 10;
int array[arraySize];
int elementToDis;
do
{
std::cout << "Number of array elements to display: ";
std::cin >> elementToDis;
} while (elementToDis > arraySize || elementToDis < 0); // this is your exeption
for (int ccc(0); ccc < elementToDis; ++ccc)
std::cout << "Index " << ccc << ": " << array[ccc] << '\n';
I think you want to display all elements lower than an index value entered by the user :
Let array[] be the array name of size=10,you can get an index value (say l) from the user and use that value inside a for loop for printing all elements in index lower than l
int array[size]
void disp_in(int l)
{
if(l>=size) // if l greater than or equal to size (as index start at 0)
throw l;
else
{
cout<<"Elements : ";
for(int i=0;i<=l;i++) //if we have say l=2 ,array values in indexes 0,1and 2 will be displayed
cout<<array[i];
}
}
int main ()
{
int l;
cout<<"Enter index : ";
cin>>l; //till this index value, the array value will be displayed
try
{
disp_in(l);
}
catch(int e)
{
cout<<"Index value greater than max index";
}
return 0;
}
You could try something like this:
#include <vector>
#include <iostream>
#include <algorithm>
#include <iterator>
void print_numbers( const std::vector<int>& array, int nNumbers, const char* pszSeparator )
{
if ( nNumbers > static_cast<int>(array.size()) )
{
throw std::exception();
}
std::copy( array.begin(), array.begin() + nNumbers, std::ostream_iterator<int>( std::cout, pszSeparator ) );
}
int main()
{
std::vector<int> array( 10 );
//Just for testing
{
int n = 0;
auto generator = [n]() mutable
{
return n++;
};
std::generate_n( array.begin(), array.size(), generator );
}
try
{
print_numbers(array, 11, "\n");
}
catch ( std::exception e )
{
std::cout << "Error message..." << std::endl;
}
return 0;
}

C++ Turning arrays into functions?

I have been attempting this for hours to no avail, as you can see in my code I have separate functions, they were all together in main, but I am required to turn each into a separate function. However when I try anything I get errors, even when I try to pass parameters. Can someone point me in the right direction?
#include <iostream>
#include <cstdlib>
#include <ctime>
void printarray();
void average();
void largestnumber();
using namespace std;
int main()
{
printarray();
average();
largestnumber();
}
void printarray() {
srand(time(0));
int n[10], tot = 0;
for (int i = 0; i < 10; i++)
{
n[i] = (1 + rand() % 100);
cout << n[i] << endl;
}
}
void average() {
int j, tot = 0, n[10];
for (j = 0; j < 10; j++)
{
tot += n[j];
}
cout << "The average of the numbers in the array are " << tot / j << endl;
}
void largestnumber() {
int w = 1, int n[10];
int temp = n[0];
while (w < 10)
{
if (temp < n[w])
temp = n[w];
w++;
}
cout << "The largest number in the array is " << temp << endl;
}
The array you are working with needs to be passed in to each function, so the same array is used everywhere. It is a good idea to pass the size as well, just for flexibility reasons.
Now your functions pretty much work as you wrote them.
#include <iostream>
#include <cstdlib>
#include <ctime>
void printarray(int n[], size_t size);
void average(int n[], size_t size);
void largestnumber(int n[], size_t size);
using namespace std;
int main()
{
const size_t arr_size = 10;
int n[arr_size];
printarray(n, arr_size);
average(n, arr_size);
largestnumber(n, arr_size);
}
void printarray(int n[], size_t size) {
srand((unsigned int)time(0));
int tot = 0;
for (size_t i = 0; i < size; i++)
{
n[i] = (1 + rand() % 100);
cout << n[i] << endl;
}
}
void average(int n[], size_t size) {
size_t j;
int tot = 0;
for (j = 0; j < size; j++)
{
tot += n[j];
}
cout << "The average of the numbers in the array are " << tot / j << endl;
}
void largestnumber(int n[], size_t size) {
size_t w = 1;
int temp = n[0];
while (w < size)
{
if (temp < n[w])
temp = n[w];
w++;
}
cout << "The largest number in the array is " << temp << endl;
}
One simple improvement is to break the printarray out into an initarray function that fills the array and printarray that prints the content.
It would also be a good idea to do some checking for things like an empty array (functions assume n[0] exists, for instance).
The next obvious step is to put all this in a class. Also, if you are allowed to, the c array should be replaced with a vector, as that does a great job of keeping all the resource information together.