Having trouble while solving an array problem that produces an infinite loop - c++

Ask the user for a number between 1 and 9. If the user does not enter a number between 1 and 9, repeatedly ask for an integer value until they do. Once they have entered a number between 1 and 9, print the array.Given the array- int array[] = { 4, 6, 7, 3, 8, 2, 1, 9, 5 };
#include<iostream>
int printArray(){
int arraySize,i;
int array[] = { 4, 6, 7, 3, 8, 2, 1, 9, 5 };
arraySize=sizeof(array)/sizeof(array[0]);
std::cout<<"The length of the array is:"<<" "<<arraySize<<"\n";
for(i=0;i<arraySize;i++){
std::cout<<array[i]<<"\n";
}
}
int main(){
tryAgain:
int x;
std::cout<< "Enter any number between 1 and 9"<<"\n";
std::cin>>x;
if(x<=9 && x>=1){
printArray();
}
else
goto tryAgain;
return 0;
}

What you have here is undefined behaviour caused by not returning a valid value from function printArray that is supposed to return an int.
The standard addresses this issue:
9.6.3 The return statement
...
2. ... Otherwise, flowing off the end of a function other than main results in undefined behavior.
Compiling with -Wall option in GCC produces this warning:
warning: no return statement in function returning non-void [-Wreturn-type]
Since the function only prints data, you should have void instead of int as return type.

I think you shouldn't use goto, use for
The line int printArray(){ should be void printArray(){ for you needn't return
The follow code could work:
#include <iostream>
void printArray(){
int arraySize, i;
int array[] = { 4, 6, 7, 3, 8, 2, 1, 9, 5 };
arraySize = sizeof(array) / sizeof(array[0]);
std::cout << "The length of the array is:" << " " << arraySize << "\n";
for (i = 0; i < arraySize; ++i)
std::cout<<array[i]<<"\n";
}
int main(){
for (;;) {
std::cout << "Enter any number between 1 and 9"<<"\n";
int x;
std::cin >> x;
if(std::cin.fail()) {
std::cin.clear();
std::cin.ignore(1024, '\n');
continue;
}
if (x < 1 || x > 9)
continue;
printArray();
break;
}
return 0;
}

Related

Why does an error occur when I modulus the value in array?

may i know what exactly have gone wrong in this code? cause the output of the even number is not what i expected if i input the value in the comment
//int number[10]={0, 2, 5, 8, -2, 0, 6, 4, 3, 1};
int number[10], divided_number[10], total_odd_numbers, total_even_numbers, a;
for(int i=0;i<=9;i++){
a=i+1;
cout<<"Number "<<a<<": ";
cin>>number[i];
}
for(int i =0; i<=9; i++){
cout<<*(number+i)<<" ";
}
cout<<endl;
for(int i=0;i<=9; i++){
divided_number[i]=number[i]%2;
if(divided_number[i]!=0){
total_odd_numbers +=1;
}
else if (divided_number[i]==0){
total_even_numbers++;
}
}
for(int i=0;i<=9; i++){
cout<<*(divided_number+i)<<" ";
}
cout<<"\n Total odd number: "<<total_odd_numbers<<endl;
cout<<"\n Total even number: "<<total_even_numbers<<endl;
The problem is that total_odd_numbers and total_even_numbers are not initialized before being accessed. This is called undefined behavior. In this case, the program will take whichever trash data is already in the memory assigned to those variables and just use it as-is (and so, of course, the output may or may not be correct, depends on what's in that memory at the time of assignment).
It should be noted that :
Using an unitialized value is, by itself, not undefined behavior, but the value is simply indeterminate. Accessing this then is UB if the value happens to be a trap representation for the type. Unsigned types rarely have trap representations, so you would be relatively safe on that side.
Modified program:
#include <iostream>
using namespace std;
int main()
{
int number[10]={0, 2, 5, 8, -2, 0, 6, 4, 3, 1};
int divided_number[10], total_odd_numbers = 0, total_even_numbers = 0, a;
for(int i =0; i<=9; i++){
cout<<*(number+i)<<" ";
}
cout<<endl;
for(int i=0;i<=9; i++){
divided_number[i]=number[i]%2;
if(divided_number[i]!=0){
total_odd_numbers +=1;
}
else if (divided_number[i]==0){
total_even_numbers++;
}
}
for(int i=0;i<=9; i++){
cout<<*(divided_number+i)<<" ";
}
cout<<"\n Total odd number: "<<total_odd_numbers<<endl;
cout<<"\n Total even number: "<<total_even_numbers<<endl;
}
Output:
0 2 5 8 -2 0 6 4 3 1
0 0 1 0 0 0 0 0 1 1
Total odd number: 3
Total even number: 7
And, of course, the code could be cleaned up much further:
int number[10]={0, 2, 5, 8, -2, 0, 6, 4, 3, 1};
int odds = 0, evens = 0;
for(int i=0;i<=9; i++)
{
int left = number[i] % 2; cout << left << " ";
if (left != 0) {odds++;} else {evens++;}
}
cout<<"\nTotal odd number: "<<odds<<'\n'<<"Total even number: "<<evens;
Further reading:
(Why) is using an uninitialized variable undefined behavior?
https://en.cppreference.com/w/cpp/language/ub
And also:
Why is "using namespace std;" considered bad practice?

c++ array copy gives weird result

I have known java for a while and I was trying to translate a java program i wrote to c++ but the copy function gives an odd result:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
long gcd2(long a, long b) {
if ( a == 0 )
return b;
return gcd2(b%a,a);
}
long gcd(long nums[]) {
long ans = nums[0];
int len = sizeof(nums);
for (int i = 1; i < len; i++)
ans = gcd2( nums[i] , ans );
return ans;
}
string com(string s) {
s = s+",";
return (","+s);
}
void printa(long array[]) {
for (int i = 0 ; i < sizeof(array); i++)
cout << array[i] << ", ";
cout << "\n";
}
int main()
{
int length;
cin >> length;
long input[length];
for (int i = 0; i < length; i++)
cin >> input[i];
string possible = "";
int ans = 0;
for (int a = 0; a < length; a++) {
for (int b = length; b > a; b--) {
long arr[b-a];
std::copy(input+a,input+b,arr);
printa(arr);
long gcdans = gcd(arr);
if (possible.find( com(gcdans+"") ) == -1 ) {
possible += com(gcdans+"");
ans++;
}
}
}
cout << (ans);
return 0;
}
I give it the input of:
4
9 6 2 4
and it returns:
9, 6, 2, 4, 140725969483488, 4197851, 9, 6,
9, 6, 2, 4197851, 9, 6, 2, 4,
9, 6, 2, 4197851, 9, 6, 2, 4,
9, 4197851, 9, 6, 2, 4, 140725969483488, 4197766,
6, 2, 4, 4197851, 9, 6, 2, 4,
6, 2, 4, 4197851, 9, 6, 2, 4,
6, 4197851, 9, 6, 2, 4, 140725969483488, 4197766,
2, 4, 6, 4197851, 9, 6, 2, 4,
2, 4197851, 9, 6, 2, 4, 140725969483488, 4197766,
4, 4197851, 9, 6, 2, 4, 140725969483488, 4197766,
1
the number at the very end is what i want the program to output at the end, all the numbers above are me test printing the array to see its contents. Basically I am trying to copy a range of the array(for example (2,3,4) from (1,2,3,4,5,6)) But it gives weird numbers like 140725969483488 and 4197766 when the only numbers I input are 9 6 2 4
Variable length arrays is a C++ extension, not standard C++. If your compiler will allow them, then OK. However standard C++ would use an std::vector container which is dynamically sized at runtime, meaning you can initialise them with any size or numbers at runtime, and add anything you want at runtime.
Also note when passing an array in C++ to functions which take an array argument always (with the exception of explicitly declared sized reference to an array) gets passed as a pointer, so you can't know the size of the array once passed as an argument. So this:
void printa(long array[])
{
for (int i = 0 ; i < sizeof(array); i++) {}
// At this point of the code the sizeof(array) will return the size of
// a pointer, usually 4 or 8 bytes.
// It's a quirk that this happens, and is a holdover from C.
}
By taking an argument of std::vector you can know the size of the array. You can take the argument by value or by reference or pointer.
void printa(const std::vector<long>& array)
{
for (int i = 0 ; i < array.size(); i++)
{
cout << array[i] << ", ";
cout << "\n";
}
}
This is the better way to do it. If you want to use a C array or raw array the way you did, you will have to pass both the array and the size of the array as separate arguments.
Also, about the variable length array extension feature, I'm not sure whether it is reliable or not because I've never used the extension. Again, standard C++ requires that size of arrays are constant values, (known at compile time). Edit: actually (known at compile-time) is a bad description because:
int main()
{
int num = 6;
int myarray[num]; // In standard C++ this won't compile
//but
const int num = 6;
int myarray[num]; // Will
}
And one last thing, as SolutionMill pointed out, even if the sizeof(array) does give the right size and not the size of a pointer, it is the size given in bytes, not the number of elements, which was not you were wanting in:
for (int i = 0 ; i < sizeof(array); i++)
If the array is of 2 elements of 32 bit int, then the sizeof() operator will return size 8. A common but by no means pretty way to get the number of elements in an array is something like sizeof(array) / sizeof(array[0])

C++ Separate Positive and Negative Values From An Array

Beginner in C++ here and learning arrays. The program below is supposed to separate positive and negative numbers in an array. However, it is returning random numbers in both the splitPos and splitNeg functions.
Could someone ever so kindly advice and show me what is incorrect in the functions and what can be done to omit these random digits so that only positive and negative digits are returned respectively by the program for each function/loop? I am obviously not seeing and/or understanding what is incorrect.
Thank you so very much for your help and time in advance!!!
#include <iostream>
using namespace std;
//function prototypes
int splitNeg(int[], int[], int);
int splitPos(int[], int[], int);
void displayArr(int[], int);
int main()
{
const int SIZE = 20;
int usedPos, usedNeg;
int origArr[SIZE] = { 4, -7, 12, 6, 8, -3, 30, 7, -20, -13, 17, 6, 31, -4, 3, 19, 15, -9, 12, -18 };
int posArray[SIZE];
int negArray[SIZE];
usedPos = splitPos(origArr, posArray, SIZE);
usedNeg = splitNeg(origArr, negArray, SIZE);
cout << "Positive Values: " << endl;
displayArr(posArray, usedPos);
cout << endl;
cout << "Negative Values: " << endl;
displayArr(negArray, usedNeg);
return 0;
}
int splitPos(int origArr[], int posArray[], int SIZE)
{
int j = 0;
for (int i = 0; i < SIZE; i++ && j++)
{
if (origArr[i] >= 0)
posArray[j] = origArr[i];
}
return j;
}
int splitNeg(int origArr[], int negArray[], int SIZE)
{
int k = 0;
for (int i = 0; i < SIZE; i++ && k++)
{
if (origArr[i] < 0)
negArray[k] = origArr[i];
}
return k;
}
void displayArr(int newArray[], int used)
{
for (int i = 0; i < used; i++)
cout << newArray[i] << endl;
return;
}
If you change your for-loops a bit:
int splitPos(int origArr[], int posArray[], int SIZE)
{
int j = 0;
for (int i = 0; i < SIZE; i++)
{
if (origArr[i] >= 0)
posArray[j++] = origArr[i];
}
return j;
}
int splitNeg(int origArr[], int negArray[], int SIZE)
{
int k = 0;
for (int i = 0; i < SIZE; i++)
{
if (origArr[i] < 0)
negArray[k++] = origArr[i];
}
return k;
}
you will get the result you desire.
The counter variables of your target arrays only get increased if you find a value that matches the criterion of being less (or greater) than 0.
I honestly do not understand what you tried to achieve with a ... hmmm.. "combined" increase like i++ && j++, this goes into short circuit evaluation.
j and k must be incremented only when the correct value is copied to posArray and negArray, by definition.
If the value is the wrong sign, j and k, obviously, should remain unchanged, since the number of values with the right sign, in the corresponding output array, does not change on this iteration.
This is not what the code is doing. It is incrementing them on every iteration of the loop, except for the one where i is 0.
There is a standard algorithm made just for that. It is named std::partition.
Your code with that algorithm will look like this:
struct SplitPosAndNegResult {
std::vector<int> negatives;
std::vector<int> positives;
};
auto splitPosAndNeg(std::array<int, SIZE> orig) {
// Here `it` is the first element of the second partition (positives)
auto it = std::partition(orig.begin(), orig.end(), [](int i){ return i < 0; });
return SplitPosAndNegResult{
std::vector<int>(orig.begin(), it), // negative numbers
std::vector<int>(it, orig.end()) // positive numbers
};
}
Then, use it like that:
int main () {
auto result = splitPosAndNeg({ 4, -7, 12, 6, 8, -3, 30, 7, -20, -13,
17, 6, 31, -4, 3, 19, 15, -9, 12, -18});
for (int n : result.positives) {
std::cout << n << ' ';
}
std::cout << std::endl;
for (int n : result.negatives) {
std::cout << n << ' ';
}
std::cout << std::endl;
}
This program will output this:
7 30 8 17 6 31 6 3 19 15 12 12 4
-18 -7 -9 -4 -13 -3 -20
Here's a live example at Coliru.
All the answers in this post are good, but I'm disappointed that none of them talk about the STL algorithms!
A good c++ programmer must know the language but he have to know also the C++ library.
look the following code:
#include <iostream>
#include <array>
#include <algorithm>
#include <string>
using namespace std;
template<typename T>
void print(const string& desc, T first, T last)
{
cout << desc;
for_each(first, last,
[](const auto& i ) { cout << i << ' ';});
cout << endl;
}
int main()
{
array<int, 20> originalArray = { 4, -7, 12, 6, 8, -3, 30, 7, -20, -13, 17, 6, 31, -4, 3, 19, 15, -9, 12, -18 };
print("original array is ", begin(originalArray), end(originalArray));
auto it = partition(begin(originalArray), end(originalArray),
[](int n) { return n >= 0; });
print("now original array is ", begin(originalArray), end(originalArray));
print("positives are: ", begin(originalArray), it);
print("negatives are: ", it, end(originalArray));
return 0;
}
More generally you want partition your set with a predicate.
Look to my code do you find any if or for? It's impossible make mistakes this way!
The only thing that does matter in the whole code is auto it = partition(begin(originalArray), end(originalArray), [](int n) { return n >= 0; }); that can be read as: partition from start to finish of originalArray elements that are positive.
#include<iostream>
using namespace std;
int main(){
int a[10]={9,4,-3,-2,1,-1,5,7,-9,-5};
int low=0;
int high=10-1;
while(low<high){
while(a[low]>=0){
low++;
}
while(a[high]<=0){
high--;
}
if(low<high){
int temp=a[low];
a[low]=a[high];
a[high]=temp;
}
}
for(int i=0;i<10;i++){
cout<<a[i]<<" ";
}
}
Time Complexity: O(n)

Comparing one element of an array to multiple elements of another array

I'm writing a piece of code for a slot machine project, I have two arrays working.
I would like to compare one element of array 1 with multiple element of array 2.
This is my current piece of code, I took a swing at it but I don't think this is correct.
char arrayOne[10]{ 1, 1, 2, 2, 3, 4, 4, 5, 5 };
char arrayTwo[10]{ 1, 2, 3, 4, 5 };
if (arrayTwo[0] == arrayOne[0 - 1])
cout << "The Numbers are the same";
else
cout << "the numbers are different";
_getch();
In C++, the syntax you've written is the same as: arrayTwo[0] == arrayOne[-1], which I'm fairly sure we both agree is not what you want.
You're looking for:
((arrayTwo[0] == arrayOne[0]) and (arrayTwo[0] == arrayOne[1]))
If you want to match against an arbitrary number of elements, then you should learn about loops:
bool truthiness = true;
for (int i=0; i<10; ++i) {
truthiness = truthiness and (arrayTwo[0] == arrayOne[i]);
}
if (truthiness) {
cout << "The numbers are the same";
} else {
cout << "The numbers are different";
}
You should use a loop. I've written this small function for you...
int
array_range_compare (char *array, int compare_value, int start, int end)
{
for (int i = start; i <= end; i++) {
if (compare_value != array[i]) {
return 0;
}
}
return 1;
}
This will compare the value of compare_value to the values of keys start through end in array. For you array is arrayOne, start is 0, end is 1, and compare_value is arrayTwo[0], all of the variables but array are integers.
You can use this function like so...
char arrayOne[10] = { 1, 1, 2, 2, 3, 4, 4, 5, 5 };
char arrayTwo[10] = { 1, 2, 3, 4, 5 };
if (array_range_compare (arrayOne, arrayTwo[0], 0, 1)) {
std::cout << "The Numbers are the same";
} else {
std::cout << "the numbers are different";
}

Function to return count of duplicate numbers in sorted array

I want to return the number of duplicate values in a sorted array.
For example: a = { 1, 1, 2, 3, 4, 4 }, fratelli(n) should return 2. (They are 1, 1 and 4, 4)
I attempted to use a recursive approach, but it doesn't work. It Always give me 4.
I'm asking if someone please could help me understand better this methods of programming. Thanks a lot!
The function:
#include <iostream>
using namespace std;
int fratelli(int a[], int l, int r)
{
if (l == r) return 0;
else
{
int c = (l+r) / 2;
int n = fratelli(a, l, c) + fratelli(a, c+1, r);
if (a[l] == a[l+1]) n++;
return n;
}
}
int main()
{
const int _N = 11;
int array[_N] = { 1, 1, 2, 3, 5, 5, 7, 8, 8, 11, 12 };
cout << "\n" << fratelli(array, 0, _N-1);
return 0;
}
You have an error on this line:
if (a[l] == a[l+1]) n++;
The check should be at index c not at l. Apart from this your code seems alright to me.