Function to check dimension value and what it is - c++

I am trying to write a program that checks to see if a dimension of a rectangle is greater than zero. In the void function Check i tried using an array to check the value and used a string to display what dimension was wrong to the user. I am getting an error that it "cannot convert argument 1 from 'double[6]' to 'double'.
#include <iostream>
#include <string>
using namespace std;
void Check(double, string);
int main()
{
const int size = 3;
double DimArray[size];
string MyArray[size] = { "Height", "Length", "Width"};
cout << "Enter the height, length and width of rectangle: ";
cin >> DimArray[0] >> DimArray[1] >> DimArray[2];
Check(DimArray, MyArray);
return 0;
}
void Check(double arr1[], string arr2[])
{
int i;
for (i = 0; i < 4; i++)
{
if (arr1[i] <= 0)
cout << "Your entered " << arr2[i] << "is less than zero!";
cout << "Please enter a valid number --> ";
cin >> arr1[i];
}
}

You should declare the function correctly. Instead of
void Check(double, string);
there should be
void Check( double[], const std::string[], size_t );
Also instead of the loop in the function body
for (i = 0; i < 4; i++)
there must be
for (i = 0; i < 3; i++)
And the function could be defined as
void Check( double arr1[], const std::string arr2[], size_t n )
{
for ( size_t i = 0; i < n; i++ )
{
while ( arr1[i] <= 0 )
{
std::cout << "Your entered " << arr2[i] << "is not positive!\n";
std::cout << "Please enter a valid number --> ";
std::cin >> arr1[i];
}
}
}
Or if you will define file-wide constant
const size_t SIZE = 3;
then the function definition (and correspondingly its declaration) could be simplified
void Check( double arr1[], const std::string arr2[] )
{
for ( size_t i = 0; i < SIZE; i++ )
{
while ( arr1[i] <= 0 )
{
std::cout << "Your entered " << arr2[i] << "is not positive!\n";
std::cout << "Please enter a valid number --> ";
std::cin >> arr1[i];
}
}
}
Also instead of the array of std::string(s) it would be better to define an array of const char *
const char * MyArray[size] = { "Height", "Length", "Width"};
because as I have understood you are not going to change it.

Since your prototype expects a type double and you are passing a double arr1[]..
Change the prototype:
void Check(double, string);
to:
void Check(double arr1[], string arr2[])

Related

Template argument deduction/substitution failed:

I have a compile error when using "output_array()" in a templated member function, the following code is a simple example:
#include <iostream>
using namespace std;
int menu()
{
int opt;
cout << "\n**********MENU**********";
cout << "\n1. Print the Array in reverse order";
cin >> opt;
return opt;
}
void input_array(int b[], int n)
{
cout << "\nEnter the elements of the array";
for (int i = 0; i < n; i++)
{
cin >> b[i];
}
return;
}
void output_array(int c[], int n)
{
for (int j = 0; j < n; j++)
{
cout << c[j] << " ";
}
return;
}
void rev_arr(int b[], int n)
{
int start = 0, end = n - 1;
cout << "Array before reversing : " << output_array(b, n);
for (int i = 0; i < n / 2; i++)
{
float temp = b[start];
b[start] = b[end];
b[end] = temp;
start++;
end--;
}
cout << "Array after reversing : " << output_array(b, n);
return;
}
void task(int b[], int n, int opt)
{
switch (opt)
{
case 1:
rev_arr(b, n);
break;
default:
cout << "!!! Sorry Wrong Choice !!!";
}
return;
}
int main()
{
int size;
int a[50];
cout << "\n You can Enter 50 elements in the array.\nHow much you want to enter?";
cin >> size;
input_array(a, size);
int opt = menu();
task(a, size, opt);
return 0;
}
The output_array(int*, int) is a printing function, not an opertot<< overlaod. Therefore, your can't place output_arrry(b, n) after operator<<. Simple separate into two statments:
Change
cout << "Array after reversing : " << output_array(b, n); // Not good.
into
cout << "Array after reversing : "; output_array(b, n); // ok.
Or you have to write an operator<< overloading, give rules for operator<< to print you array. But, before doing this, you have to bind the size n in your array (as some kind of structure). The size is needed to be used in the function operator<<.

How to pass array size to different functions?

I have a problem and it seems like I cannot find a proper answer that would do the trick... So I have this static array arr[some_number] and I want to have a menu which does things with that array. Of course 1 of the options is to fill the array. Everything should be in separate functions. Here is the first one:`
void fill_array(int arr[], const int size) {
int n;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
}
`
There should be the option to let the user input how much elements he wants for the array, obv. n < some_number in this case... but with this comes my question : How can I pass the variable n in this particular case to another function so it can illiterate the number of elements the user input but not the const size of the array. Thanks in advance.
The best option is to separate responsibilities. A function like fill_array() has no business prompting the user for the array size at all. It already has a size value being passed in as input, just use that value as-is:
void fill_array(int arr[], const int size)
{
for (int i = 0; i < size; i++)
cin >> arr[i];
}
Prompt the user beforehand, and then pass the entered size to your functions as needed, eg:
int ask_user_for_size(int max_number)
{
int n;
do
{
cout << "Enter a number between 1 - " << max_number << ": ";
cin >> n;
if ((n > 0) && (n <= max_number)) break;
cout << "Invalid number, try again" << endl;
}
while (true);
return n;
}
void fill_array(int arr[], const int size)
{
for (int i = 0; i < size; i++)
cin >> arr[i];
}
void output_array(const int arr[], const int size)
{
for (int i = 0; i < size; i++)
cout << arr[i];
}
...
int arr[some_number];
int n = ask_user_for_size(some_number);
cout << "Enter " << n << " numbers: ";
fill_array(arr, n);
output_array(arr, n);
Alternatively:
int ask_user_for_size()
{
int n;
do
{
cout << "Enter a number greater than 0: ";
cin >> n;
if (n > 0) break;
cout << "Invalid number, try again" << endl;
}
while (true);
return n;
}
void fill_array(int *arr, const int size)
{
for (int i = 0; i < size; i++)
cin >> arr[i];
}
void output_array(const int *arr, const int size)
{
for (int i = 0; i < size; i++)
cout << arr[i];
}
...
int n = ask_user_for_size();
int *arr = new int[n];
cout << "Enter " << n << " numbers: ";
fill_array(arr, n);
output_array(arr, n);
delete[] arr;

Cannot display proper percentage, or total from array in for loops

The problem I am having with my program is, first, when I calculate percent, it's not adding all the elements in the array to a total and diving them from. I tried putting the total += percents[i]; in a nested for-loop, but it just gave me negative %.
Also, my total at the end won't display anything. At first, I had it and all the function defined in the main(), but it didn't do anything. Even after the change, it doesn't work. Also, last thing, my file has 20 items, yet the loops only read in 19 items. If I change to 20, it crashes.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void inputValues(string names[], int votes[])
{
ifstream inputfile;
inputfile.open("votedata.txt");
if(inputfile.is_open())
{
for(int i = 0; i < 19; i++)
{
inputfile >> names[i] >> votes[i];
}
}
}
double *calcPercents( double percents[], int votes[], double total)
{
for(int i = 0; i < 19; i++)
{
percents[i] = votes[i];
total += percents[i];
percents[i] = (percents[i]/total)*100;
}
return percents;
}
string determineWinner(string names[], double percents[])
{
double temp = 0;
string winner;
for(int i = 0; i < 19; i++)
{
if(percents[i] > temp)
{
temp = percents[i];
winner = names[i];
}
}
return winner;
}
void displayResults(string names[], int votes[], double percents[])
{
int total = 0;
calcPercents(percents, votes, total);
cout << "Candidate Votes Received % of Total Votes " << endl;
for(int i = 0; i < 19; i++)
{
cout << names[i] << " " << votes[i] << " " << percents[i] << "%" << endl;
}
cout << "Total " << total << endl;
cout << " The winner of the election is " << determineWinner(names, percents) << endl;
}
int main()
{
string names[19], winner;
int votes[19];
double percents[19];
inputValues(names, votes);
displayResults(names, votes, percents);
}
My file is in the style:
bob (tab) 1254
joe (tab) 768
etc.
If you have to use arrays instead of std::vectors you should pass their size to the functions using them. One way is to set the size using a constant, like this:
#include <iostream>
#include <fstream>
#include <string>
using namespace std; // bad practice
const int size = 20;
void inputValues(string names[], int votes[], int n);
// add the size as a parameter of the function ^^^^
int calcPercents( double percents[], int votes[], int n );
//^^ I'll explain later why I changed your signature ^^^
string determineWinner(string names[], double percents[], int n );
void displayResults(string names[], int votes[], double percents[], int n);
int main()
{
// It's always better to initialize the variables to avoid undefined behavior
// like the negative percentages you have noticed
string names[size] ="";
int votes[size] = {0};
double percents[size] = {0.0};
inputValues(names, votes, size);
displayResults(names, votes, percents, size);
}
To calculate the percentages you can use two loops, one for the sum and the other to get the percentage. In your function you pass total as a parameter by value, so it will be copied and the changes will never be visible outside the function. I choose to return that vaule, even if doing so the name of function becomes a litle misleading:
int calcPercents( double percents[], int votes[], int n )
{
int total = 0;
for(int i = 0; i < n; i++)
// note the bound ^^^
{
total += votes[i];
}
double factor = 100.0 / total;
for(int i = 0; i < n; i++)
{
percents[i] = factor * votes[i];
}
return total;
}
You should also add some checks to the input function, I only add the size parameter. Note that having initialized the arrays, even if it fails reading the file the arrays doesn't contain random values:
void inputValues(string names[], int votes[], int n)
{
ifstream inputfile;
inputfile.open("votedata.txt");
if(inputfile.is_open())
{
for(int i = 0; i < n; i++)
{
inputfile >> names[i] >> votes[i];
}
}
}
I'd change the function which determine the winner too:
string determineWinner(string names[], double percents[], int n )
{
if ( !n )
{
return "";
}
double max = percents[0];
// update an index instead of a string
int winner = 0;
for( int i = 1; i < n; i++ )
{
if( percents[i] > max )
{
max = percents[i];
winner = i;
}
}
return names[winner];
}
For the last function, only remember to add the size:
void displayResults(string names[], int votes[], double percents[], int n)
{
int total = calcPercents(percents, votes, n);
cout << "Candidate Votes Received % of Total Votes " << endl;
for( int i = 0; i < n; i++ )
{
cout << names[i] << " " << votes[i] << " "
<< percents[i] << "%" << endl;
}
cout << "Total " << total << endl;
cout << " The winner of the election is "
<< determineWinner(names, percents,n) << endl;
}

Using strtol to get long double in c++

I am trying to get the long double out of an array.
long double num;
char * pEnd;
char line[] = {5,0,2,5,2,2,5,4,5,.,5,6,6};
num = strtold(line1, &pEnd);
For some reason the num i am getting is rounded to 502522545.6
I am quite new to C++ so is there something i am doing wrong ? What needs to be done to get the entire number in the num instead of the rounded up?
Thank you for the help !!!
Sorry that's my first post here =)
So the entire program code is as following :
class Number
{
private:
long double num ;
char line[19], line2[19];
int i, k;
public:
Number()
{}
void getData()
{
i = 0;
char ch= 'a';
cout << "\nPlease provide me with the number: ";
while ((ch = _getche()) != '\r')
{
line[i] = ch;
line2[i] = ch;
i++;
}
}
void printData() const
{
cout << endl;
cout << "Printing like an Array: ";
for (int j = 0; j < i; j++)
{
cout << line[j];
}
cout << "\nModified Array is: ";
for (int j = 0; j < (i-k); j++)
{
cout << line2[j];
}
cout << "\nTHe long Double is: " << num;
}
void getLong()
{
char * pEnd;
k = 1;
for (int j = 0; j < i; j++)
{
if (line2[j+k] == ',')
{
k++;
line2[j] = line2[j + k];
}
line2[j] = line2[j + k];
}
line2[i -k] = line2[19];
num = strtold(line2, &pEnd);
}
};
int main()
{
Number num;
char ch = 'a';
while (ch != 'n')
{
num.getData();
num.getLong();
num.printData();
cout << "\nWould you like to enter another number ? (y/n)";
cin >> ch;
}
return 0;
}
The idea is that the number entered is in the following format ($50,555,355.67) or any other number. The program then removes all signs apart of numbers and "."
Then i tried to get the long double num out of an array.
If you run the program you always get the rounded number from num.
The C++ way of doing this is pretty simple:
#include <sstream>
#include <iostream>
#include <iomanip>
int main() {
const std::string line = "502522545.566";
long double num;
std::istringstream s(line);
s >> num;
std::cout << std::fixed << std::setprecision(1) << num << std::endl;
}
Using modern C++ you can simply do:
auto line = "502522545.566"s;
auto num = std::stold(line);
Live example
Theres probably a more C++ way, but sscanf will work:
const char *str = "3.1459";
long double f;
sscanf(str, "%Lf", &f);

Passing 2D array to a Function in c++

I am Having Problem with Passing a 2D array to a c++ Function. The function is supposed to print the value of 2D array. But getting errors.
In function void showAttributeUsage(int)
Invalid types for int(int) for array subscript.
I know the problem is with the syntax in which I am passing the particular array to function but I don't know how to have this particular problem solved.
Code:
#include <iostream>
using namespace std;
void showAttributeUsage(int);
int main()
{
int qN, aN;
cout << "Enter Number of Queries : ";
cin >> qN;
cout << "\nEnter Number of Attributes : ";
cin >> aN;
int attVal[qN][aN];
cout << "\nEnter Attribute Usage Values" << endl;
for(int n = 0; n < qN; n++) { //for looping in queries
cout << "\n\n***************** COLUMN " << n + 1 << " *******************\n\n";
for(int i = 0; i < aN; i++) { //for looping in Attributes
LOOP1:
cout << "Use(Q" << n + 1 << " , " << "A" << i + 1 << ") = ";
cin >> attVal[n][i];
cout << endl;
if((attVal[n][i] > 1) || (attVal[n][i] < 0)) {
cout << "\n\nTHE VALUE MUST BE 1 or 0 . Please Re-Enter The Values\n\n";
goto LOOP1; //if wrong input value
}
}
}
showAttributeUsage(attVal[qN][aN]);
cout << "\n\nYOUR ATTRIBUTE USAGE MATRIX IS\n\n";
getch();
return 0;
}
void showAttributeUsage(int att)
{
int n = 0, i = 0;
while(n != '\0') {
while(i != '\0') {
cout << att[n][i] << " ";
i++;
}
cout << endl;
n++;
}
}
I really suggest to use std::vector : live example
void showAttributeUsage(const std::vector<std::vector<int>>& att)
{
for (std::size_t n = 0; n != att.size(); ++n) {
for (std::size_t i = 0; i != att.size(); ++i) {
cout << att[n][i] << " ";
}
cout << endl;
}
}
And call it that way:
showAttributeUsage(attVal);
Looking at your code, I see no reason why you can't use std::vector.
First, your code uses a non-standard C++ extension, namely Variable Length Arrays (VLA). If your goal is to write standard C++ code, what you wrote is not valid standard C++.
Second, your initial attempt of passing an int is wrong, but if you were to use vector, your attempt at passing an int will look almost identical if you used vector.
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
typedef std::vector<int> IntArray;
typedef std::vector<IntArray> IntArray2D;
using namespace std;
void showAttributeUsage(const IntArray2D&);
int main()
{
int qN, aN;
cout << "Enter Number of Queries : ";
cin >> qN;
cout << "\nEnter Number of Attributes : ";
cin >> aN;
IntArray2D attVal(qN, IntArray(aN));
//... Input left out ...
showAttributeUsage(attVal);
return 0;
}
void showAttributeUsage(const IntArray2D& att)
{
for_each(att.begin(), att.end(),
[](const IntArray& ia) {std::copy(ia.begin(), ia.end(), ostream_iterator<int>(cout, " ")); cout << endl;});
}
I left out the input part of the code. The vector uses [] just like a regular array, so no code has to be rewritten once you declare the vector. You can use the code given to you in the other answer by molbdnilo for inputing the data (without using the goto).
Second, just to throw it into the mix, the showAttributeUsage function uses the copy algorithm to output the information. The for_each goes throw each row of the vector, calling std::copy for the row of elements. If you are using a C++11 compliant compiler, the above should compile.
You should declare the function like this.
void array_function(int m, int n, float a[m][n])
{
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
a[i][j] = 0.0;
}
where you pass in the dimensions of array.
This question has already been answered here. You need to use pointers or templates. Other solutions exists too.
In short do something like this:
template <size_t rows, size_t cols>
void showAttributeUsage(int (&array)[rows][cols])
{
for (size_t i = 0; i < rows; ++i)
{
std::cout << i << ": ";
for (size_t j = 0; j < cols; ++j)
std::cout << array[i][j] << '\t';
std::cout << std::endl;
}
}
You're using a compiler extension that lets you declare arrays with a size determined at runtime.
There is no way to pass a 2D array with such dimensions to a function, since all but one dimension for an array as a function parameter must be known at compile time.
You can use fixed dimensions and use the values read as limits that you pass to the function:
const int max_queries = 100;
const int max_attributes = 100;
void showAttributeUsage(int array[max_queries][max_attributes], int queries, int attributes);
int main()
{
int attVal[max_queries][max_attributes];
int qN = 0;
int aN = 0;
cout << "Enter Number of Queries (<= 100) : ";
cin >> qN;
cout << "\nEnter Number of Attributes (<= 100) : ";
cin >> aN;
cout << "\nEnter Attribute Usage Values" << endl;
for (int n = 0; n < qN; n++)
{
cout << "\n\n***************** COLUMN " << n + 1 <<" *******************\n\n";
for (int i = 0; i < aN; i++)
{
bool bad_input = true;
while (bad_input)
{
bad_input = false; // Assume that input will be correct this time.
cout << "Use(Q" << n + 1 << " , " << "A" << i + 1 << ") = ";
cin >> attVal[n][i];
cout << endl;
if (attVal[n][i] > 1 || attVal[n][i] < 0)
{
cout << "\n\nTHE VALUE MUST BE 1 or 0 . Please Re-Enter The Values\n\n";
bad_input = true;
}
}
}
}
cout << "\n\nYOUR ATTRIBUTE USAGE MATRIX IS\n\n";
showAttributeUsage(attVal, qN, aN);
getch();
return 0;
}
void showAttributeUsage(int att[max_queries][max_attributes], int queries, int attributes)
{
for (int i = 0; i < queries; i++)
{
for (int j = 0; j < attributes; j++)
{
cout << att[i][j] << " ";
}
cout << endl;
}
}
For comparison, the same program using std::vector, which is almost identical but with no size limitations:
void showAttributeUsage(vector<vector<int> > att);
int main()
{
cout << "Enter Number of Queries (<= 100) : ";
cin >> qN;
cout << "\nEnter Number of Attributes (<= 100) : ";
cin >> aN;
vector<vector<int> > attVal(qN, vector<int>(aN));
cout << "\nEnter Attribute Usage Values"<<endl;
for (int n = 0; n < qN; n++)
{
cout<<"\n\n***************** COLUMN "<<n+1<<" *******************\n\n";
for (int i = 0; i < aN; i++)
{
bool bad = true;
while (bad)
{
bad = false;
cout << "Use(Q" << n + 1 << " , " << "A" << i + 1 << ") = ";
cin >> attVal[n][i];
cout << endl;
if (attVal[n][i] > 1 || attVal[n][i] < 0)
{
cout << "\n\nTHE VALUE MUST BE 1 or 0 . Please Re-Enter The Values\n\n";
bad = true;
}
}
}
}
cout << "\n\nYOUR ATTRIBUTE USAGE MATRIX IS\n\n";
showAttributeUsage(attVal);
getch();
return 0;
}
void showAttributeUsage(vector<vector<int> > att);
{
for (int i = 0; i < att.size(); i++)
{
for (int j = 0; j < att[i].size(); j++)
{
cout << att[i][j] << " ";
}
cout << endl;
}
}
The Particular Logic worked for me. At last found it. :-)
int** create2dArray(int rows, int cols) {
int** array = new int*[rows];
for (int row=0; row<rows; row++) {
array[row] = new int[cols];
}
return array;
}
void delete2dArray(int **ar, int rows, int cols) {
for (int row=0; row<rows; row++) {
delete [] ar[row];
}
delete [] ar;
}
void loadDefault(int **ar, int rows, int cols) {
int a = 0;
for (int row=0; row<rows; row++) {
for (int col=0; col<cols; col++) {
ar[row][col] = a++;
}
}
}
void print(int **ar, int rows, int cols) {
for (int row=0; row<rows; row++) {
for (int col=0; col<cols; col++) {
cout << " | " << ar[row][col];
}
cout << " | " << endl;
}
}
int main () {
int rows = 0;
int cols = 0;
cout<<"ENTER NUMBER OF ROWS:\t";cin>>rows;
cout<<"\nENTER NUMBER OF COLUMNS:\t";cin>>cols;
cout<<"\n\n";
int** a = create2dArray(rows, cols);
loadDefault(a, rows, cols);
print(a, rows, cols);
delete2dArray(a, rows, cols);
getch();
return 0;
}
if its c++ then you can use a templete that would work with any number of dimensions
template<typename T>
void func(T& v)
{
// code here
}
int main()
{
int arr[][7] = {
{1,2,3,4,5,6,7},
{1,2,3,4,5,6,7}
};
func(arr);
char triplestring[][2][5] = {
{
"str1",
"str2"
},
{
"str3",
"str4"
}
};
func(triplestring);
return 0;
}