I have just studied c++ templates and it was great that the books example compiled and worked. Then in the exercises at the end of the chapter I tried my own template programme. The code simple passes an array to the template function and it determines the largest value in the array. The problem is that when the type double array is passed the template is treating it as type int and displaying 5 as the larges value and not 5.0.
Here is my code
// Exercise 5.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
template <typename T>
T max5(const T array[]);
int main()
{
using std::cout;
using std::cin;
using std::endl;
int intA[5]{ 1, 2, 5, 4, 3 };
double doubleA[5]{ 1.0, 2.0, 5.0, 4.0, 3.0 };
cout << "Max int " << max5(intA) << endl;
cout << "Max double " << max5(doubleA) << endl;
cin.get();
cin.get();
return 0;
}
template <typename T>
T max5(const T array[])
{
T max = array[0];
for (int i = 1; i < 5; i++)
{
if (array[i] > max) max = array[i];
//std::cout << "Max: " << max << std::endl;
}
return max;
}
Any ideas as to why?
Regards
Mickydint
You're getting the correct types back, the problem is with you displaying them.
cout << "int == " << typeid(max5(intA)).name() << endl;
cout << "double == " << typeid(max5(doubleA)).name() << endl;
std::cout has different ways of showing higher precision or different formatting.
Like:
std::setprecision
std::fixed
std::scientific
std::hexfloat
std::defaultfloat
and std::showpoint as Zulukas already pointed out.
// Exercise 5.cpp : Defines the entry point for the console application.
//
#include <iostream>
#include <typeinfo>
template <typename T>
T max5(const T array[]);
int main()
{
using std::cout;
using std::cin;
using std::endl;
int intA[5]{ 1, 2, 5, 4, 3 };
double doubleA[5]{ 1.0, 2.0, 5.0, 4.0, 3.0 };
cout << "int == " << typeid(max5(intA)).name() << endl;
cout << "double == " << typeid(max5(doubleA)).name() << endl;
cout << std::showpoint;
cout << "Max int " << max5(intA) << endl;
cout << "Max double " << max5(doubleA) << endl;
cout << std::noshowpoint;
cout << std::fixed;
cout << "Max int " << max5(intA) << endl;
cout << "Max double " << max5(doubleA) << endl;
cin.get();
cin.get();
return 0;
}
template <typename T>
T max5(const T array[])
{
T max = array[0];
for (int i = 1; i < 5; i++)
{
if (array[i] > max) max = array[i];
//std::cout << "Max: " << max << std::endl;
}
return max;
}
Live
Related
I am trying to find the smallest value and its index in a vector. But my programm seem to give weird results?
You can check it out here: http://cpp.sh/5qj7r
// Example program
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
int main()
{
std::vector<float> const test{5.5,4.,3.,0.2,7.,5.};
for (int i=0;i<6;++i)
{
std::cout << "test[i="<< i <<"]: " << test[i] << "\n";
}
size_t index{0};
for (size_t i{0}; i < 6U; ++i)
{
std::cout << "test[i="<<i<<"]: " << test[i]<<"\n";
std::cout << "old min: "<< test[index] <<"\n";
std::cout << "old index: "<< index <<"\n";
std::cout << "test[i] is smaller old min: ";
std::cout << std::boolalpha;
std::cout << (test[i] < test[index]) << "\n";
index = i ? (test[i] < test[index]) : index;
std::cout << "new min: "<< test[index] <<"\n";
std::cout << "new index: "<< index <<"\n";
}
std::cout << "Index of Smallest Value: " << index<<"\n";
}
The output is the following (at the very end)
"Index of Smallest Value: 1"
I expect to get the value 0.2 and its corresponding index 3.
maybe try it with this for loop
static float min = std::numeric_limits<float>::max();
for (float number : your_vector) {
if (number < min)
min = number;
}
std::cout << min;
I want to write a loop, that can give me the dimensions of an array. I want to make it usable for any array and it should return the sizes of the dimensions.
int arr[3][5][10][9] ;
cout << "dimension 1: " << sizeof(arr)/sizeof(arr[0]) << endl;
cout << "dimension 2: " << sizeof(arr[0])/sizeof(arr[0][0]) << endl;
cout << "dimension 3: " << sizeof(arr[0][0])/sizeof(arr[0][0][0]) << endl;
cout << "dimension 4: " << sizeof(arr[0][0][0])/sizeof(arr[0][0][0][0]) << endl;
cout << "dimension 5: " << sizeof(arr[0][0][0][0])/sizeof(arr[0][0][0][0][0]) << endl;
This should return 3,5,10,9 (and fail for the last statement).
So the pattern seems clear "each iteration add [0] after arr. The last iteration will fail, which should stop the while-loop.
How can I "concatenate + evaluate" the array name?
I would also appreciate help on what test checks "Will this fail?", or "Is there another dimension?" in C++, as I'm just learning it.
if you are using c++ 17 compiler, you can use type traits structs std::rank and std::extent as following
#include <iostream>
#include <type_traits>
template<typename T>
void print_dimension(std::size_t i) {
if (std::rank_v<T> > 0) {
std::cout << "Dimension " << i << ":" << std::extent_v<T> << std::endl;
print_dimension<typename std::remove_extent_t<T>>(i + 1);
}
}
int main() {
int arr[3][5][10][9] ;
print_dimension<decltype(arr)>(1);
return 0;
}
If you are using C++ 11/14 compiler, it would need slight modification
#include <iostream>
#include <type_traits>
template<typename T>
void print_dimension(std::size_t i) {
if (std::rank<T>::value > 0) {
std::cout << "Dimension " << i << ":" << std::extent<T>::value << std::endl;
print_dimension<typename std::remove_extent<T>::type>(i + 1);
}
}
int main() {
int arr[3][5][10][9] ;
print_dimension<decltype(arr)>(1);
return 0;
}
I just started learning about arrays and I have a tenuous grasp on them.
Tried making this program in a lab today and keep getting an error that numJarsSold, typesOfSalsa, and totalJarsSold are undeclared identifiers in MyFunctions.cpp. I've found online already that people have had the same project and seen their code and I've written my own to run just in main but somehow running it separated I've managed to break it. Any help would be appreciated. Thanks.
Main.cpp
#include "MyFunctions.h"
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main()
{
const int SIZE = 5;
string typesOfSalsa[SIZE] = { "Mild", "Medium", "Sweet", "Hot", "Zesty" };
int numJarsSold[SIZE]; // Holds Number of Jars of Salsa sold for each type
int totalJarsSold = getJarSalesData(typesOfSalsa, numJarsSold);
displayReport(typesOfSalsa, numJarsSold, totalJarsSold);
system("pause");
return 0;
}
MyFunctions.cpp
#include "MyFunctions.h"
using namespace std;
int getJarSalesData(string typesOfSalsa[], int numJarsSold[])
{
int totalJarsSold = 0;
for (int type = 0; type < SIZE; type++)
{
cout << "Jars sold last month of " << typesOfSalsa[type] << ": ";
cin >> numJarsSold[type];
while (numJarsSold[type] < 0)
{
cout << "Jars sold must be 0 or more. Please re-enter: ";
cin >> numJarsSold[type];
}
// Adds the number of jars sold to the total
totalJarsSold += numJarsSold[type];
}
return totalJarsSold;
}
int posOfLargest(int array[])
{
int indexOfLargest = 0;
for (int pos = 1; pos < SIZE; pos++)
{
if (array[pos] > array[indexOfLargest])
indexOfLargest = pos;
}
return indexOfLargest;
}
int posOfSmallest(int array[])
{
int indexOfSmallest = 0;
for (int pos = 1; pos < SIZE; pos++)
{
if (array[pos] < array[indexOfSmallest])
indexOfSmallest = pos;
}
return indexOfSmallest;
}
void displayReport(string[], int[], int)
{
int hiSalesProduct = posOfLargest(numJarsSold);
int loSalesProduct = posOfSmallest(numJarsSold);
cout << endl << endl;
cout << " Salsa Sales Report \n\n";
cout << "Name Jars Sold \n";
cout << "____________________________\n";
cout << typesOfSalsa[0] << " " << numJarsSold[0] << "\n";
cout << typesOfSalsa[1] << " " << numJarsSold[1] << "\n";
cout << typesOfSalsa[2] << " " << numJarsSold[2] << "\n";
cout << typesOfSalsa[3] << " " << numJarsSold[3] << "\n";
cout << typesOfSalsa[4] << " " << numJarsSold[4] << "\n";
for (int type = 0; type < SIZE; type++)
{
cout << left << setw(25) << typesOfSalsa[type] << setw(10) << numJarsSold[type] << endl;
cout << "\nTotal Sales: " << totalJarsSold << endl;
cout << "High Seller: " << typesOfSalsa[hiSalesProduct] << endl;
cout << "Low Seller: " << typesOfSalsa[loSalesProduct] << endl;
}
}
MyFunctions.h
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int getJarSalesData(string[], int[]);
int posOfLargest(int[]);
int posOfSmallest(int[]);
void displayReport(string[], int[], int);
In MyFunctions.cpp file the function := void displayReport(string[], int[], int) you didn't declared any variable name
it should be like
void displayReport(string typesOfSalsa[], int numJarsSold[], int totalJarsSold)
{
// copy the code
}
In CPP file #1, I'm trying to loop through the array to see if any of the inputed names match Mordor or the_Vale (from CPP file #2 towards the bottom), however my loop is not working and I only know how to loop through a string array, not a char
#Header File#
#ifndef KINGDOM_H
#define KINGDOM_H
namespace westeros
{
class Kingdom
{
public: //Makes this class public to the rest of the code
char m_name[32];
int m_population;
int count = 0;
};
void display(Kingdom&);
void display(Kingdom* k, int x);
void display(Kingdom* k, int x, int z);
void display(Kingdom* k, int x, char foo[]);
}
#endif
#CPP FIle #1#
#include <iostream>
#include "kingdom.h"
void display(Kingdom* k, int x, char foo[])
{
int a = 0;
int found = 0;
cout << "Searching for kingdom " << foo << " in Westeros" << endl;
for (a; a < x; a++)
{
if (k[a].m_name == foo)
//(strcmp(k[a].m_name) == 0)//Not working
{
cout << k[a].m_name << ", population " << k[a].m_population << endl;
found = 1;
}
}
if (found == 0)
{
cout << foo << " is not part of Westeros." << endl;
}
}
}
## CPP File (main) #2##
#include <iostream>
#include "kingdom.h"
using namespace std;
using namespace westeros;
int main(void)
{
int count = 0; // the number of kingdoms in the array
// TODO: declare the kingdoms pointer here (don't forget to initialize it)
Kingdom* pKingdoms = nullptr;
cout << "==========" << endl
<< "Input data" << endl
<< "==========" << endl
<< "Enter the number of kingdoms: ";
cin >> count;
cin.ignore();
pKingdoms = new Kingdom[count];
for (int i = 0; i < count; ++i)
{
// TODO: add code to accept user input for the kingdoms array
int x = 0;
x++;
cout << "Enter the name for kingdom #" << x + i << ": ";
cin >> pKingdoms[i].m_name;
cout << "Enter the number people living in " << pKingdoms[i].m_name << ": ";
cin >> pKingdoms[i].m_population;
}
cout << "==========" << endl << endl;
// testing that "display(...)" works
cout << "------------------------------" << endl
<< "The first kingdom of Westeros" << endl
<< "------------------------------" << endl;
display(pKingdoms[0]);
cout << "------------------------------" << endl << endl;
// This is where I am having the problem
display(pKingdoms, count, "Mordor");
cout << endl;
display(pKingdoms, count, "The_Vale");
cout << endl;
cout << endl;
delete[] pKingdoms;
pKingdoms = nullptr;
return 0;
}
if (k[a].m_name == foo)
This is not how you compare two C-Style strings. This only compares the pointers, which should result in false almost certainly. You could use strcmp (#include <string.h>):
if (!strcmp(k[a].m_name, foo))
A better way, though, since you're programming in C++, use std::string:
std::string m_name;
and the comparison would have worked flawlessly.
The code that I posted below is supposed to work in recursion (the Sort() function) even up to 1kk times. The problem is: when the Sort() function gets into loop number 43385 the console stops working and alerts: "The program has stopped working". Is it a problem with memory? If yes, where is the bad part of the code? Greetings.
#include <iostream>
#include <string>
using namespace std;
string a, b;
int n=0,i=0,counter=0;
int Sort(int i)
{
int x=0,y=0,tmp0=0;
char tmp1;
for(x=i;x<n;x++) {
if(a[x]==b[i]){
tmp0=x;
tmp1=a[x];
break;
}
else
continue;
}
for(y=tmp0;y>=i;y--)
y==i ? a[i]=tmp1 : a[y]=a[y-1];
counter+=tmp0-i;
if(i==n-1)
return counter;
else
Sort(i+1);
}
int main()
{
cin >> n >> a >> b;
Sort(0);
return 0;
}
Perhaps a call stack overflow because of too deep recursion?
To add to iltal's comment, you may want to print out information on strings a, b: a.size(), a.length(), a.capacity(), a.max_size()
I'm not sure what this code is trying to do. Here's a revision, with some print statements added, along with a random string generator.
#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
string a, b;
int n=0,i=0,counter=0;
int Sort(int i)
{
int x=0,y=0,tmp0=0;
char tmp1;
for(x=i;x<n;x++) {
if(a[x]==b[i]){
tmp0=x;
tmp1=a[x];
cout << "x = " << x << " set tmp0 to " << tmp0 << " and tmp1 to " << tmp1 << endl;
break;
}
else
continue;
}
for(y=tmp0;y>=i;y--)
y==i ? a[i]=tmp1 : a[y]=a[y-1];
counter+=tmp0-i;
cout << " endof sort: a is " << a << endl;
cout << " b is " << b << endl;
if(i==n-1) {
cout << "Returning counter " << counter << endl;
return counter;
} else {
cout << "Running sort(" << i << " + 1)" << endl;
Sort(i+1);
}
}
string randomStrGen(int length) {
static string charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
string result;
result.resize(length);
for (int i = 0; i < length; i++)
result[i] = charset[rand() % charset.length()];
return result;
}
int main()
{
n = 50;
srand(time(NULL));
string a0, b0;
a0 = randomStrGen(n);
a = a0;
b0 = randomStrGen(n);
b = b0;
// cin >> n >> a >> b;
cout << "Max string size is " << a.max_size() << endl;
cout << "Calling sort" << endl
<< " n is " << n << endl
<< " a is " << a << endl
<< " b is " << b << endl;
Sort(0);
cout << " endof program: a inital: " << a0 << endl;
cout << " a final: " << a << endl;
cout << " b inital: " << b0 << endl;
cout << " b final: " << b << endl;
return 0;
}
counter is of type int but it has a lot of values summed in it which may be in all larger than int. maybe try int64?
You could hard code some test cases, like n = 20, a = "xyz...", b = "abc...", and add print statements to your sort function to track what is going on. Also, it may be helpful to add some comments to clarify what the purpose of the different loops are.