I am trying to create an array using cin to define the size. While that seems to be working (based on what I currently have), none of the other stuff I want to do seems to be working.
For instance, I want to use a for loop to find the smallest int in the array since I will then need to compare it with all the other ints in the array, but no matter where I have the statement to return the smallest int, it does not do it.
What am I doing wrong?
#include <iostream>
using namespace std;
int main(){
int userSize;
cout << "Please define size of array: ";
cin >> userSize;
int *duckArray = new int[userSize];
for (int i = 0; i < userSize; i++) {
cout << "Please enter a number into the array: ";
cin >> duckArray[i];
}
int smallest = duckArray[0];
for (int i = 0; i < userSize; i++){
if (duckArray[i] < smallest){
smallest = duckArray[i];
cout << smallest << endl;
}
}
//cout << smallest << endl;
return 0;
}
Your code is working if you change this:
for (int i = 0; i < userSize; i++){
if (duckArray[i] < smallest){
smallest = duckArray[i];
}
}
cout << smallest << endl;
This will find and print the smallest number entered.
Arrays in C++ must have their size declared to the compiler at runtime. Other people are going to explain how you can buffer memory to simulate a dynamically allocating arrays. You can also have your Array at a given size and as the user adds and removes, you can reject inputs over the current size.
I highly recommend you look into Vectors. Vectors are much like ArrayLists in Java. They are a form of higher level collections that resize themselves as you add more elements to them.
Related
This is my code in C++. When I am taking input {11 10 5 6 7} in the array, Every time it's giving output smallest as 0. But giving correct output to the other inputs.
#include<bits/stdc++.h>
using namespace std;
int main() {
int a[100000];
int large, small;
int n;
cin >> n;
for (int j = 0; j < n; j++) {
cin >> a[j];
}
for (int j = 0; j < n; j++) {
cout << a[j] << " ";
}
large = small = a[0];
for (int i = 1; i <= n; i++) {
if (a[i] < small) {
small = a[i];
}
if (a[i] > large) {
large = a[i];
}
}
cout << "Smallest is " << small << endl;
cout << "Largest is " << large << endl;
}
You have three loops, two of them run while i<n and the third one while i<=n. And then it uses a[n] item. How do you think what the value of a[n] is?
You were asking:
What is wrong in my code
Let me first answer this question and then we will refactor and optimize it.
So, let's list up the findings
#include<bits/stdc++.h> is non-compliant C++ code. It should never be used. It will run only on selected compilers
using namespace std; should not be used. Always use fully qualified names
C-Style arrays, like a[100000] should not be used in C++. Always use dedicated C++ containers like std::array or std::vector or others. In your case, the size of the array is determined at runtime. So, std::vector must be used
the “100000” is a magic number. Why 100000? Why not 500?. And what happens if the user enters 200000 as array size. Then the program will most likely crash
Use always meaningful variable names. Something like “n” will not be understood. The variable “arraySize” would be understood.
Variables shall always be initialized. And only defined, where they are used and not in the beginning of the program
Input should be verified (cin >> n). What will happen, if the user enters ‘x’ and not ‘5’. Remember, you do not initialize variable n.
large and small must be initialized with the smallest / largest value that the relevant data type can hold. Otherwise the result will always be wrong
array indices start with 0 and not with 1. So, your for loop will fail. The result will be wrong. And you used <=n. So, you will access an out of bounds value.
No need to use endl with cout. ‘\n’ will be sufficient
Then, from the design point of view. You do not need an array at all. You can make all checks immediately, directly after reading the next value.
Anyway, let us make the first step of refactoring. And ths adopted to your programming style. We will
still use C-Style arrays and dynamically allocate the memory
even use raw pointers for owned memory and new. Please note. This should not be done!
correct the bugs
use INT_MIN and INT_MAX
use meaningful variable names and comments
Please see the first refactoring step:
#include <iostream>
#include <climits>
int main() {
// Get the array size from the user and validate the input
unsigned int arraySize{};
if ((std::cin >> arraySize) and (arraySize > 0u)) {
// Now, allocate the memory for the array
int* const array = new int[arraySize]();
// Read all values from user into the just allocated array
for (unsigned int index = 0; index < arraySize; ++index) {
// Read value and check, if OK. If not, value will be 0
if (not (std::cin >> array[index])) std::cerr << "\nError: Wrong value\n";
}
// Now we set up the result values, always with the opposite maximum/minimum
int maxValueInArray = INT_MIN;
int minValueInArray = INT_MAX;
// Iterate over all values and check for min and maximum
for (unsigned int index = 0; index < arraySize; ++index) {
// Compare and assign potential new values
if (array[index] < minValueInArray) minValueInArray = array[index];
if (array[index] > maxValueInArray) maxValueInArray = array[index];
}
// Free the allocated memory. We do not need it any longer
delete [] array;
// Show result to user
std::cout << "Smallest is " << minValueInArray << '\n';
std::cout << "Largest is " << maxValueInArray << '\n';
}
else std::cerr << "\nError while reading array size\n\n";
}
So, next, let’s go a little bit more into the direction C++.
We will get rid of raw pointers, new and will use the correct limit values.
#include <iostream>
#include <limits>
#include <memory>
int main() {
// Get the array size from the user and validate the input
unsigned int arraySize{};
if ((std::cin >> arraySize) and (arraySize > 0u)) {
// Now, allocate the memory for the array
std::unique_ptr<int[]> array = std::make_unique<int[]>(arraySize);
// Read all values from user into the just allocated array
for (unsigned int index = 0; index < arraySize; ++index) {
// Read value and check, if OK. If not, value will be 0
if (not (std::cin >> array[index])) std::cerr << "\nError: Wrong value\n";
}
// Now we set up the result values, always with the opposite maximum/minimum
int maxValueInArray = std::numeric_limits<int>::min();
int minValueInArray = std::numeric_limits<int>::max();
// Iterate over all values and check for min and maximum
for (unsigned int index = 0; index < arraySize; ++index) {
// Compare and assign potential new values
if (array[index] < minValueInArray) minValueInArray = array[index];
if (array[index] > maxValueInArray) maxValueInArray = array[index];
}
// Show result to user
std::cout << "Smallest is " << minValueInArray << '\n';
std::cout << "Largest is " << maxValueInArray << '\n';
}
else std::cerr << "\nError while reading array size\n\n";
}
A little bit better. Now we get rid of the whole manual memory allocation and use a std::vector, which is by far better. And we will use range based for loops, which will make our life simpler:
#include <iostream>
#include <limits>
#include <vector>
int main() {
// Get the array size from the user and validate the input
unsigned int arraySize{};
if ((std::cin >> arraySize) and (arraySize > 0u)) {
// Now, allocate the memory for the array
std::vector<int> data(arraySize, 0);
// Read all values from user into the just allocated array
for (int& value : data) {
// Read value and check, if OK. If not, value will be 0
if (not (std::cin >> value)) std::cerr << "\nError: Wrong value\n";
}
// Now we set up the result values, always with the opposite maximum/minimum
int maxValueInArray = std::numeric_limits<int>::min();
int minValueInArray = std::numeric_limits<int>::max();
// Iterate over all values and check for min and maximum
for (const int& value : data) {
// Compare and assign potential new values
if (value < minValueInArray) minValueInArray = value;
if (value > maxValueInArray) maxValueInArray = value;
}
// Show result to user
std::cout << "Smallest is " << minValueInArray << '\n';
std::cout << "Largest is " << maxValueInArray << '\n';
}
else std::cerr << "\nError while reading array size\n\n";
}
And last but not least, we will get of the whole array/vector stuff. It is not needed.
#include <iostream>
#include <limits>
int main() {
// Get the number of values to check from the user and validate the input
unsigned int numberOfValues{};
if ((std::cin >> numberOfValues) and (numberOfValues > 0u)) {
// Now we set up the result values, always with the opposite maximum/minimum
int maxValueInArray = std::numeric_limits<int>::min();
int minValueInArray = std::numeric_limits<int>::max();
// Read all values from user and check them immediately
for (unsigned int i{}; i<numberOfValues; ++i) {
// Read value and check, if OK. If not, value will be 0
int value{};
if (not (std::cin >> value)) std::cerr << "\nError: Wrong value\n";
// Compare and assign potential new values
if (value < minValueInArray) minValueInArray = value;
if (value > maxValueInArray) maxValueInArray = value;
}
// Show result to user
std::cout << "Smallest is " << minValueInArray << '\n';
std::cout << "Largest is " << maxValueInArray << '\n';
}
else std::cerr << "\nError while reading number of values\n\n";
}
On the third loop it will be
for(int i=0;i<n;i++)
Here is the assignment:
Your goal is to write a program that displays a series of whole numbers from input in reverse order. Your
program will prompt the user for the number of values in this list, which it will use as the size for a dynamic
array declared after this prompt.
The array size is unknown, the value is the pointer, and the sub has to be assigned before the loop.
Here are the steps:
Declare variables, but don't "allocate the memory the memory for the pointer yet". Do this after prompting the user to enter the values.
Prompt user to enter the numbers of values to be listed. (There has to be a message for the user in case they enter a negative number). Then use the keyword new for the pointer.
Prompt the user to enter the values
Display the values in reverse.
Use the keyword delete for the dynamic array.
While I'm trying to run the program, the error was:
error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
for(int sub = 0; sub < size; size--)
--------------------------------------^
error: lvalue required as decrement operand
for (int sub = 0; sub > size; size--)
------------------------------------------------------^
Also, I am not sure what the keyword new does.
#include <iostream>
using namespace std;
int main()
{
int size, array;
cout << "How many values would you like to enter? ";
cin >> array;
int value;
int *array = new int[size];
if (size > 0)
{
for (int sub = 0; sub < size; size++)
{
cout << "Enter value #" << size << ": ";
cin >> value;
}
while (size > 0);
}
else
{
while (size < 0)
{
cout << "Size must be positive." << endl;
cout << "How many values would you like to enter? ";
cin >> size;
}
}
cout << "Here are the values you entered in reverse order: \n";
for (int sub = size - 1; sub >= 0; size--)
{
cout << "Value #" << size << " :" << value << endl;
}
delete[] array;
return 0;
}
PS: I know size is supposed to be unknown, but I've encountered another error saying
storage size of ‘size’ isn’t known
So, I add numbers to avoid that error.
Edit:So I changed the code thanks to #MikeCAT, but this error said terminate called after throwing an instance of 'std::bad_array_new_length what(): std::bad_array_new_length. This was because I enter a negative number for the size, which was supposed to happen for the if statement. Also, I need the size to start at 1 after the user enters how many values they want to enter, but the size always starts at the number that was entered.
As the assignment says, you should
Read a value
Allocate a dynamic array using the value read as its size
Read the numbers for the array
#include <iostream>
int main(void) {
// read a number (size of a dynamic array)
int numElements;
std::cin >> numElements;
// allocate a dynamic array
int *array = new int[numElements];
// read values for the dynamic array
for (int i = 0; i < numElements; i++) {
std::cin >> array[i];
}
// print the values in reversed order
for (int i = numElements - 1; i >= 0; i--) {
std::cout << array[i] << '\n';
}
// de-allocate the array
delete[] array;
// exit normally
return 0;
}
Error handling and non-essensial messages are omitted. Try adding them.
I wanted to write a code where user will give input the element of the array and then the elements will be print as an array. Here is my code but the code do not give the array as output.
#include<iostream>
using namespace std;
int main(){
int arr[100] , size , i , num ; //Here we are defining the maximum size of array is 100. So user can choose the size of array by him/her but cannot choose more than 100
cout << "Enter the size of array (Maximum array size you can take is 100) : ";
cin >> size;
if (size > 100)
{
cout << "You cannot take the size more than 100" << endl;
}else{
cout << "Inter the elements using space : ";
for (int i = 0; i < size; i++)
{
cin >> arr[i];
}
cout << "Enter data you want to insert : ";
cin >> num;
for (int i = size - 1 ; i >= 0 ; i--)
{
arr[i+1] = arr[i];
}
arr[0] = num;
size++;
}
cout << arr[i] << endl;
return 0;
}
Your question isn't entirely clear, but I see two basic problems.
First, you define variable i at the top of your code. That's fine, although there are arguments for variable names being longer than a single character. Think about searching for uses of that variable -- you're going to get it in all sorts of places that have nothing to do with the variable. while has an i. if has an i. Be that as it may.
But here's a real problem. You have some for loops like this:
for (int i = 0; ....)
There's nothing wrong with that, not exactly. It works. HOWEVER, it's considered bad form to reuse a variable inside an inner block that matches a variable from an outer block. It's legal, but it's a common source of bugs. I recommend you don't do it.
Then, at the bottom, you do this:
cout << arr[i] << endl;
At this point, we're back to the original variable i that you declare at the top. But you never actually initialize it, so it's some random value. And you're not doing any sort of loop.
I suspect if you wrap this inside another of your for-loops, you'd get the results you want.
And get rid of declaring i at the top.
I have class City with following private data: name of city, width,length and height of the city. I have to make dynamic array, which is inserted by constructor by default- City(),when the programs starts.Then the program uses method output() and prints inserted array of cities.
I should use bubble sort to sort the cities by their length. And when this is done, the program should show the sorted cities in increasing lengths.
The problem is that my data are in private(in public everything works excellent but principle of capsulation is violated!) so I can't do bubble sort.
I tried to do another dynamic array of type double double Lengths[n], which content is lengths of first array. Then I do sorting, but program prints only sorted lengths and this is not my goal.
I should print the names of cities sorted by their lengths.
Code:
class City{
private: char *name;
double width;
double length;
double height;
public:void Output();
City();
~City();
double GetLength()
{
return length;
}
double GetWidth(){ return width; }
double GetHeight(){ return height; }
char GetName(){ return *name; }
};
City::City()
{
char ime[20];
cout << "Name= ";
cin >> ime;
name = new char[strlen(ime) + 1];
for (int i = 0; i <=strlen(ime); i++)
name[i] = ime[i];
cout << "Width= ";
cin >> width;
cout << "Length= ";
cin >> length;
cout << "Height= ";
cin >> height;
}
void City::Output()
{
cout << "Name is: " << name << endl;
cout << " Width is: " << width <<" deg"<< endl;;
cout << " Length is: " << length << " deg"<<endl;
cout << " Height is: " << height <<" m"<<endl;
return;
}
City::~City()
{
cout << " " << endl;
cout << "Destructor of City!" << endl;
delete[] name;
}
int main()
{
//City town;
//town.Input();
//town.Output();
int n;
City *mA;
cout << "Input number of cities: " << endl;
cin >> n;
mA = new City[n];
for (int j = 0; j < n; j++)
{
mA[j].Output();
}
cout << "Cities from west to east, sorted by their length" << endl;
double *Lengths = new double[n];
for (int j = 0; j < n; j++)
{
Lengths[j] = mA[j].GetLength();
}
int k = 0;//counter
double max = Lengths[0];
for (int j = 1; j < n; j++)
{
if (Lengths[j - 1] >Lengths[j])
{
max = Lengths[j - 1];
Lengths[j - 1] = Lengths[j];
Lengths[j] = max;
}
}
for (int j = 0; j < n; j++)//cycle for output
{
mA[j].Output();
}
delete[]mA;
return 0;
}
As I can't quite comment on your response, I will give you a few bits of advice. First in the line of:
Array[j]=mA[j].GetName() ;
You have a random space which may be a copy change and relatively minor but for reading purposes that is wrong.
Second your naming conventions are really something you should work on. I should be able to read a variable and understand what it means but instead I struggle to understand what a variable named mA means.
Third your else clause does nothing literally. Your not moving any parts of the array if that is your intention my saying this:
mA[j+1];
you are simply targeting the element in the array that is above the iteration. I see you stuck with your idea of making something similar to a parallel array for the bubble sort, and that is fine but you lack any action in the first loop.
This is not bubble sort what so ever as you are simply going through each iteration and checking if the element in Lengths is equal in length to the element in mA and then storing that element in array but your else statement does nothing.
Your loop should look similar to something like this but I'm gonna get rid of the character array and the extra array for some reason as it is unnecessary and lets say you start out with an array of your objects:
if(myObjects[i].GetLength() > myObjects[i+1].GetLength()) //Shortest to longest name or vice versa?
{
//Store myObject[i] in temp spot
//myObject[i] = myObject[i+1]
//myObject[i+1] = temp Storage
}
This will give you a bubble sort of the objects on the first round. Of course your going to have to find out how to iterate through the array in loop to verify all of the elements have been sorted correctly as this will of course take many iterations for bubble sort.
I don't see a direct question but I can assume majority of the question by your story. You have multiple options on how to solve this case. One of the simple ways to solve this is create a function within the object that allows you to get the length of a member of an object for example in your case it would be name of city.
Create a method inside the object that you can call to return a private method's length. Create a loop that calls this method and checks each element side by side until you can't refine it any longer. Is there a specific reason your using char instead of string for name?
I'm not entirely sure of what you're asking.
However, from what I can tell your main issue is that you can't sort because you're trying to compare two private variables from two objects.
If the objects are placed into an Array of type city, you can bubblesort by length however you would be required to use the getters in order to reference the variables that are private during sorting.
For example (not exact syntax)
if(cityArray[0].getLength() < cityArray[1].getLength())
{
//Do Something
}
For a program I must use an array and not vector. I have to take in user's input, and it's a indefinite amount of them. The user can type in 5 values, or 50. I am absolutely stumped as to how to go about doing this. Using a for loop for example:
Int a[10];
Int b;
For (int i=0; i<10; i++)
{
Cout<<"enter values:";
Cin>>b;
A[i]=b;
}
With this I can take an array of 10 of user defined variables but how would I go about making it a dynamic size? Thank you for the help!
The size of a static array must be known at compile time, otherwise you must use a dynamic array. For example
#include <iostream>
int main()
{
// Determine how many total entries are expected
int entries;
std::cout << "How many values do you want to enter?" << std::endl;
std::cin >> entries;
// Allocate a dynamic array of the requested size
int* a = new int[entries];
// Populate the array
for (int i = 0; i < entries; ++i)
{
std::cout << "enter a value: ";
std::cin >> a[i];
std::cout << std::endl;
}
// Clean up your allocated memory
delete[] a;
return 0;
}