No values returned from function in C - c

I was trying to write a function that checks if an array has consecutive numbers (not necessarily in order), return 0 if not and 1 if yes.
For example:
24, 21, 22, 23
The return value would be 1.
22,22,22
Would return 0.
The problem is that it return 1 for something like:
22,22,22
I could really use the help looking into it.
This is the main function (no need to check it or anything, it's fine):
#include <stdio.h>
#include <stdlib.h>
/* Function declarations */
void Ex1();
void Ex2();
void Ex3();
void Ex4();
void Ex5();
/* Declarations of other functions */
int f3(int *, int);
/* ------------------------------- */
//
int main() {
int select = 0, i, all_Ex_in_loop = 0;
printf("Run menu once or cyclically?\n"
"(Once - enter 0, cyclically - enter other number) ");
if (scanf_s("%d", &all_Ex_in_loop) == 1)
do {
for (i = 1; i <= 5; i++)
printf("Ex%d--->%d\n", i, i);
printf("EXIT-->0\n");
do {
select = 0;
printf("please select 0-5 : ");
scanf_s("%d", &select);
} while ((select < 0) || (select > 5));
switch (select) {
case 1: Ex1(); break;
case 2: Ex2(); break;
case 3: Ex3(); break;
case 4: Ex4(); break;
case 5: Ex5(); break;
}
} while (all_Ex_in_loop && select);
return 0;
}
and this is the function (UPDATED):
void Ex3() {
int n, i, res;
printf("Enter the size of the Array: ");
scanf_s("%d", &n);
int *arr = (int *)malloc(n * sizeof(int));
if (!arr) {
printf("ERROR - not enough memory.");
exit(1);
}
printf("Enter an Array >>> ");
for (i = 0; i < n; i++)
scanf_s("%d", &arr[i]);
res = f3(arr, n);
printf("res = %d\n", res);
free(arr);
}
int f3(int *arr, int size) {
int i, min = arr[0], max = arr[0];
for (i = 1; i < size; i++) {
if (arr[i] < min)
min = arr[i];
if (arr[i] > max)
max = arr[i];
}
int *CounterArray = (int *)calloc(max + 1, sizeof(int));
if (!CounterArray) {
printf("ERROR - not enough memory.");
exit(1);
}
for (i = 0; i < size; i++) {
CounterArray[arr[i]]++;
}
for (i = min; i <= max; i++)
if (CounterArray[i] == 0)
return 0;
free(CounterArray);
return 1;
}

There are multiple problems in your code:
in function f3() you allocate an array of max + 1 integers. This would be a problem is all numbers in the array are negative. You should instead check that max - min + 1 is exactly the size of the array and allocate size elements.
you reject the array if and only if an element in the range has a 0 count. You should instead check that all elements have a 1 count. This explains why the function fails for 22,22,22.
Here is a modified version:
int f3(const int *arr, int size) {
int result = 1;
if (size <= 0)
return 1;
int i, min = arr[0], max = arr[0];
for (i = 1; i < size; i++) {
if (min > arr[i])
min = arr[i];
if (max < arr[i])
max = arr[i];
}
if (max - min + 1 != size)
return 0;
unsigned char *CounterArray = calloc(size, sizeof(*CounterArray));
if (!CounterArray) {
printf("ERROR - not enough memory.");
exit(1);
}
for (i = 0; i < size; i++) {
// increment the count of this element
if (CounterArray[arr[i] - min]++) {
// if the count was already non zero, the test fails.
result = 0;
break;
}
}
free(CounterArray);
return result;
}

You return zero under the condition that
if (CounterArray[i] == 0)
but in your test case of 22,22,22 you have min and max both equal 22 and CounterArray[22] equal 3, not 0.
You need to re-think the condition...

Related

Remove all digits from array

Write a function remove_digits that receives two arrays of type int. The first array contains a number of integers, and the second array is an array of digits. It is necessary to remove all digits from second array which are present in first array.
The function returns 1 if the ejection was successful.The function returns 1 if the eject was successful, and 0 if the array of digits is incorrect for some reason, if the array contains a value less than 0 or greater than 9, or if one of the members is repeated.
EXAMPLE 1:
int first[2]={12345, -12345},second[2]={3,5};
OUTPUT: 124 -124
EXAMPLE 2:
int first[5]={25, 235, 1235, 252, 22552255},second[3]={2,3,5};
OUTPUT: 0 0 1 0 0
My algorithm:
check if digit in second array is less than 0 or grater than 9 or digit is repeated, and in that case return 0 (finish program)
for negative numbers make them positive and in the end of first (for) loop make them negative
in the second (while) loop break number into digits, and for every number check if it's present in second array
if it is present, remove last digit
continue to the rest of elements
Code:
#include <stdio.h>
#include <stdlib.h>
int sum_of_digits(int n) {
int i, sum = 0;
while (n > 0) {
sum++;
n /= 10;
}
return sum;
}
int divide(int n) {
int num_of_digits = sum_of_digits(n);
switch (num_of_digits) {
case 1:
break;
case 2:
break;
case 3:
n /= 10;
break;
case 4:
n /= 100;
break;
case 5:
n /= 1000;
break;
case 6:
n /= 1000;
break;
case 7:
n /= 10000;
break;
case 8:
n /= 100000;
break;
case 9:
n /= 1000000;
default:
break;
}
return n;
}
int remove_digits(int *first, int n, int *second, int vel) {
// first - removing digits from second
// second - searching for digits
int i, j, num, digit, neg = 0;
for (i = 0; i < vel; i++) {
// invalid digit
if (second[i] < 0 || second[i] > 9)
return 0;
for (j = i + 1; j < vel; j++)
// repeated digit
if (second[j] == second[i])
return 0;
}
for (i = 0; i < n; i++) {
// negative case
if (first[i] < 0) {
first[i] = abs(first[i]);
neg = 1;
}
num = first[i];
while (num > 0) {
digit = num % 10;
for (j = 0; j < vel; j++)
if (second[j] == digit)
// remove last digit
first[i] = divide(first[i]) - digit;
num /= 10;
}
if (first[i] <= 0)
first[i] = 0;
if (neg == 1)
first[i] *= -1;
}
return 1;
}
int main() {
int first[2] = {12345, 12345}, second[2] = {3, 5}, i;
remove_digits(first, 2, second, 2);
for (i = 0; i < 2; i++)
printf("%d ", first[i]);
return 0;
}
MY OUTPUT: 4 4
Could you help me to modify my algorithm to work correctly?
simplified approach for your problem would be as follows,
#include <stdio.h>
#include <stdlib.h>
int removeDigit(int src, int digit){
int neg = (src < 0)?-1:1;
int num = abs(src);
src = 0;
//remove digit
while(num){
int num_digit = num%10;
if(num_digit != digit){
src = src * 10 + num_digit;
}
num /= 10;
}
//reverse number
while(src){
num = num * 10 + src%10;
src /=10;
}
return num*neg;
}
int remove_digits(int *first, int n, int *second, int m) {
// first - removing digits from second
// second - searching for digits
int i, j;
for (i = 0; i < m; i++) {
// invalid digit
if (second[i] < 0 || second[i] > 9)
return 0;
for (j = i + 1; j < m; j++)
// repeated digit
if (second[j] == second[i])
return 0;
}
for (i = 0; i < n; ++i) {
for(j =0; j<m; ++j){
first[i]= removeDigit(first[i],second[j]);
}
}
return 1;
}
int main() {
{
printf("Test 1\n");
int first[] = {12345, 12345}, second[] = {3, 5}, i;
remove_digits(first, sizeof(first)/sizeof(first[0]), second, sizeof(second)/sizeof(second[0]));
for (i = 0; i < sizeof(first)/sizeof(first[0]); i++)
printf("%d ", first[i]);
}
{
printf("\n\nTest 2\n");
int first[] = {25, 235, 1235, 252, 22552255}, second[] = {2,3,5}, i;
remove_digits(first, sizeof(first)/sizeof(first[0]), second, sizeof(second)/sizeof(second[0]));
for (i = 0; i < sizeof(first)/sizeof(first[0]); i++)
printf("%d ", first[i]);
}
return 0;
}

How to check if array elements are perfect numbers?

I'm trying to make a program where the array size is not entered by the user,but the elements are, until 0 is entered.Now I want to check for each element which one is a perfect number,for that I have to do the sum of the divisors.Problem is I can't manage to do the sum of divisors for each element in the array,instead it adds all the divisors of all the elements in the array.
#include <stdio.h>
int main()
{
int n = 1000, i, j, sum = 0;
int v[n];
for (i = 1; i < n; i++)
{
scanf("%d", &v[i]);
if (v[i] == 0)
{
break;
}
for (j = 1; j < v[i]; j++)
{
if (v[i] % j == 0)
{
printf("%d", j);
sum = sum + j;
}
}
}
printf("\n%d",sum);
return 0;
}
OUTPUT
Brut force check can be very expensive. It is faster to build the table of perfect numbers using Euclides formula and then simple check if the number is perfect.
static unsigned long long getp(int x)
{
return (2ULL << (x - 2)) * ((2ULL << (x - 1)) - 1);
}
int isperfect(unsigned long long x)
{
const int primes[] = {2, 3, 5, 7, 13, 17, 19, 31};
static unsigned long long array[sizeof(primes) / sizeof(primes[0])];
int result = 0;
if(!array[0])
{
for(size_t index = 0; index < sizeof(primes) / sizeof(primes[0]); index++)
{
array[index] = getp(primes[index]);
}
}
for(size_t index = 0; index < sizeof(primes) / sizeof(primes[0]); index++)
{
if(x == array[index])
{
result = 1;
break;
}
}
return result;
}
The array of perfect numbers is build only one time on the first function call.
And some usage (your code a bit modified)
int main(void)
{
size_t n = 1000, i;
unsigned long long v[n];
for (i = 1; i < n; i++)
{
scanf("%llu", &v[i]);
if (v[i] == 0)
{
break;
}
printf("%llu is %s perfect number\n", v[i], isperfect(v[i]) ? "" : "not");
}
return 0;
}
https://godbolt.org/z/exMs345xb

How to fix C2109:subscript requires array or pointer type

I'm having problem with some homework here. I'm totally newbie in programming, so anything should be helpful. I don't know how to fix C2109 error in C.
As you see, I have a float array that I have to sort, and look for the number 55.5
#include <stdio.h>
#include <conio.h>
#include <math.h>
main() {
float mr1[30], pom = 0;
int i, indeks = -1, j, n, start, end, mid;
printf("Enter length of array n<=30:\n");
scanf("%d", &n);
printf("Enter numbers of array mr1:\n");
for (i = 0; i < n; i++) {
scanf("%f", &mr1[i]);
}
for (i = 0; i <n - 1; i++) {
for (j = i + 1; j < n; j++)
if (mr1[i] > mr1[j]) {
mr1[i] = pom;
mr1[i] = mr1[j];
mr1[j] = mr1[i];
}
}
start = 0;
end = n - 1;
do {
mid = (start + end) / 2
if (mr1[mid] == 55.5) {
indeks = mid;
} else {
if (mr1[mid] < 55.5) {
start = mid + 1;
} else {
kraj = mid - 1;
}
}
} while (poc <= kraj && indeks < 0);
printf("Number 55.5 is on indeks:\n");
printf("%d", indeks);
}
There are multiple issues in the code:
The swapping code is incorrect. It should read:
pom = mr1[i];
mr1[i] = mr1[j];
mr1[j] = pom;
you did not translate all poc as start and kraj as end.
There is a missing ; after mid=(start+end)/2
main() is an obsolete prototype for the main function, you should specify the return type int.
the do / while loop will not handle an empty array correctly. You should use a while loop instead. As a rule of thumb, do / while loop are very often incorrect, sometimes in subtile ways.
Here is a corrected version:
#include <stdio.h>
int main() {
float mr1[30];
int n, i, j, index, start, end, mid;
printf("Enter length of array n<=30:\n");
if (scanf("%d", &n) != 1 || n < 0 || n > 30) {
printf("invalid length\n");
return 1;
}
printf("Enter numbers of array mr1:\n");
for (i = 0; i < n; i++) {
if (scanf("%f", &mr1[i]) != 1) {
printf("invalid input\n");
return 1;
}
}
/* sort the array with simplistic swap sort */
for (i = 0; i < n - 1; i++) {
for (j = i + 1; j < n; j++) {
if (mr1[i] > mr1[j]) {
/* swap entries */
float pom = mr1[i];
mr1[i] = mr1[j];
mr1[j] = pom;
}
}
}
/* try and locate 55.5 with binary search */
index = -1;
start = 0;
end = n - 1;
while (start <= end) {
mid = (start + end) / 2;
if (mr1[mid] == 55.5) {
index = mid;
break;
} else {
if (mr1[mid] < 55.5) {
start = mid + 1;
} else {
end = mid - 1;
}
}
}
if (index >= 0) {
printf("Number 55.5 is at index %d\n", index);
} else {
printf("Number 55.5 is not present\n");
}
return 0;
}
Note also that 55.5 happens to have an exact representation as a float, but comparing floating point values with == may yield surprising results when the approximate value is not exactly identical to the expected value.

Finding the second largest element in array without sorting

I know about the single traversal method initialising two variables to INT_MIN. But my question is why do we initialise two variables to INT_MIN and also what is the purpose of INT_MIN here?
Why can't we initialise two variables to its first element like I have done in the code below? Because when I hand-checked the code manually, I found nothing wrong. So why doesn't the code run properly?
#include <stdio.h>
int main(void) {
int x[10];
int i, n;
int first = x[0];
int second = x[0];
printf("Input the size of array :");
scanf("%d", &n);
printf("Input %d elements in the array :\n", n);
for (i = 0; i < n; i++) {
printf("x[%d]: ", i);
scanf("%d", &x[i]);
}
for (i = 0; i < n; ++i) {
if (first < x[i]) {
second = first;
first = x[i];
} else
if (x[i] > second && x[i] != first) {
second = x[i];
}
}
if (second == first)
printf("There is no second largest element\n");
else
printf("\nThe Second largest element in the array is: %d", second);
return 0;
}
There are several problems in your code:
the array x is defined with a length of 10, but uninitialized when you set first and second to the value of its first element.
you do not test the return value of scanf(), leading to undefined behavior in case of input failure.
you do not test of n is in less or equal to 10 before reading values into x.
you need to special case n <= 0 as no values will be read into x.
Here is a modified version:
#include <stdio.h>
int main(void) {
int x[10];
int i, n, first, second;
printf("Input the size of array :");
if (scanf("%d", &n) != 1 || n < 0 || n > 10) {
printf("invalid input\n");
return 1;
}
if (n <= 0) {
first = second = 0;
} else {
printf("Input %d elements in the array:\n", n);
for (i = 0; i < n; i++) {
printf("x[%d]: ", i);
if (scanf("%d", &x[i]) != 1) {
printf("invalid input\n");
return 1;
}
}
first = second = x[0];
for (i = 1; i < n; ++i) {
if (first < x[i]) {
second = first;
first = x[i];
} else
if (x[i] > second && x[i] != first) {
second = x[i];
}
}
}
if (second == first)
printf("There is no second largest element\n");
else
printf("\nThe Second largest element in the array is: %d\n", second);
return 0;
}
Regarding an alternative implementation where first and second are initialized to INT_MIN and the loop starts at i = 0, the trick is INT_MIN is the smallest possible int value, so first will compare <= to all values of the array and therefore will not shadow a smaller value. It is also a good default return value for a function that finds the maximum value in an array when passed an empty array.
For your case study, the INT_MIN approach is does not work and the algorithm would fail on an array with a single repeated value: at the end of the scan, first would be set to that value and second would still be INT_MIN.
testing first == second would yield a second largest value equal to INT_MIN, which is incorrect.
testing second == INT_MIN to determine if all values are identical would be incorrect too as an array with values { 1, INT_MIN } would indeed have a second largest value equal to INT_MIN.
Your approach works correctly and the alternative would need to be written differently, with an extra variable. Indeed the solution presented in this article is incorrect, and so is this one, this one, this one and countless more random code across the Internet.
I've added some comments where I saw some problems. Hopefully I caught all the problems. Code below.
#include <stdio.h>
int main(void) {
// int x[10]; I moved this to under where you ask the user for the array size.
int i, n;
// int first=x[0]; This should be written after the user has inputted their numbers. Because what is in x[0]? user hasn't entered anything yet
// int second=x[0]; Same reason as ^
printf("Input the size of array :");
scanf("%d",&n);
int x[n]; // This should be here because you asked the user what the size of the array is.
printf("Input %d elements in the array :\n",n);
for(i=0; i<n; i++)
{
printf("x[%d]: ", i);
scanf("%d", &x[i]);
}
// You should put your first and second int's here
int first=x[0];
int second=x[0];
for (i=0; i<n ; ++i)
{
if (first<x[i])
{
second = first;
first = x[i];
}
else if (x[i] > second && x[i] != first)
{
second = x[i];
}
}
if (second == first)
printf("There is no second largest element\n");
else
printf("\nThe Second largest element in the array is: %d", second);
return 0;
}
int first=x[0];
int second=x[0];
x isn't initialized yet.
Prints -1 if no second largest element is found.
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int findNotSame(long long int a[],long int n)
{
long long int temp = a[0];
int flag = 0;
long int i;
for(i=0;i<n;i++)
{
if(a[i]!=temp)
return 1;
}
return 0;
}
long long int findMax(long long int a[],long int n)
{
long int i;
long long int max = a[0];
for(i=0;i<n;i++)
{
if(a[i]>max)
max = a[i];
}
return max;
}
int main() {
long int i,j,n;
scanf("%ld",&n);
long long int a[n];
if(n<2) //There cannot be scond largest if there;s only one(or less) element.
{
printf("-1");
return 0;
}
for(i=0;i<n;i++) //Read elements.
scanf("%lld",&a[i]);
if (!findNotSame(a,n)) //Check if all the elements in array are same if so, then -1.
{
printf("-1");
return 0;
}
long long int max = findMax(a,n); //Find maximum element(first).
long long int max2 = -999999999999999; //Initialize another max which will be the second maximum.
for(i=0;i<n;i++) //Find the second max. element.
{
if(a[i]>max2 && a[i] != max)
max2 = a[i];
}
if(max == max2) //Incase if second max(largest) is same as maximum
max2 = -1;
printf("%lld",max2);
return 0;
}
All solution is better, but some fail when the same items available in the array
like,
int arr[] = {56, 41, 19, 33, 13, 23, 25, 56};
56 available in two times,
so for this solution,
int arr[] = {56, 41, 19, 33, 13, 23, 25,56};
var max = arr[0];
var secMax=-1;
var size = arr.length;
for(var l = 1; l < size; l++) {
if (max < arr[l]) {
secMax = max;
max = arr[l];
} else if (secMax < arr[l] && arr[l] != max) {
secMax = arr[l];
}
}
System.out.println("Second largest number :-" + secMax);
import ast
input_str = input()
input_list = ast.literal_eval(input_str)
if len(input_list)<2:
print("not present")
else:
i=input_list[0]
j=i
for index_val in input_list[1:]:
if i<index_val:
j=i
i=index_val
elif index_val>j and index_val!=i:
j=index_val
elif i==j and index_val<j:j=index_val
if i==j:
print("not present")
else:
print(j)
This works,
val arr=Array(4,1,2,4,5,5,7,18,10,5,7)
var firstAndSecondIndex:(Int,Int)=null
for(indexVal <- 2 to (arr.size -1))
firstAndSecondIndex match {
case null =>
println("0,0")
firstAndSecondIndex=(0,1)
case value =>
value match {
case value if arr(indexVal) == arr(value._1) || arr(indexVal) == arr(value._2) =>
println("equals")
case value if arr(indexVal) > arr(value._1) =>
println("1,0")
value match {
case value if arr(indexVal) > arr(value._2) && arr(value._1) > arr(value._2) =>
firstAndSecondIndex=(indexVal,value._1)
case value if arr(indexVal) > arr(value._2) && arr(value._1) < arr(value._2) =>
firstAndSecondIndex=(indexVal,value._2)
case value if arr(indexVal) < arr(value._2) =>
firstAndSecondIndex=(indexVal,value._2)
}
case value if arr(indexVal) < arr(value._1) =>
println("1,1")
value match {
case value if arr(indexVal) > arr(value._2) =>
firstAndSecondIndex=(indexVal,value._1)
case value if arr(indexVal) < arr(value._2) =>
println("not greater")
}
}
}
val secondLargest= arr(firstAndSecondIndex._1) < arr(firstAndSecondIndex._2) match {case true => arr(firstAndSecondIndex._1) case false => arr(firstAndSecondIndex._2)}
int arr[] = {56, 41, 19, 33, 13, 23, 25};
int max = 1;
int secondMax = 0;
for (int i = 0; i < arr.length; i++) {
int getValue = arr[i];
if (max == 1) {
max = getValue;
secondMax = arr[1];
} else {
if (max < getValue) {
secondMax = max;
max = getValue;
} else if (secondMax < getValue) {
secondMax = getValue;
} else {
// Nothing Do
}
}
}
System.out.println("" + secondMax);
Java code to find the largest and second largest number in an array without sorting and using a single loop:
package programs;
import java.util.Scanner;
public class Demo {
public static void main(String[] args) {
int largest = -1;
int secondlargest = -1;
int numberPos = -1;
int numberPos1 = -1;
int[] arr = {22, 33, 9000, 70, 9000, -1, -10, -3, 22, 99, 100, 10000};
for (int i = 0; i < arr.length; i++) {
if (arr[i] > largest) {
numberPos = i;
largest = arr[i];
}
}
for (int i = 0; i < arr.length; i++) {
if (secondlargest < arr[i] && secondlargest < largest && arr[i] != largest) {
secondlargest = arr[i];
numberPos1 = i;
}
}
System.out.println("Largest number is "+largest+" with position "+numberPos);
System.out.println("Second largest is "+secondlargest+" with position "+numberPos1);
}
}

Not reading anything past scanf()

I am new to C and wondering why I am not getting any kind of output. I am trying to get my program to convert a hexadecimal number to binary.
#include <stdio.h>
#include <stdlib.h>
int* hex2binary(int hex_array[], int input_array_size, int* return_array_size) {
int hex_size = input_array_size;
int binary_array_size = 4 * hex_size;
int *binary_array = (int*) malloc(binary_array_size * sizeof(int));
int hex_index, binary_index;
for (hex_index = 0; hex_index < hex_size; hex_index++) {
int hex_num = hex_array[hex_index];
binary_index = hex_index * 4;
int bit_count;
for (bit_count = 3; bit_count <= 0; bit_count--) {
binary_array[binary_index + bit_count] = hex_num % 2;
hex_num = hex_num / 2;
}
hex_index++;
}
*return_array_size = binary_array_size;
return binary_array;
}
int main() {
char baseString[11];
int count = 0;
int i, j;
int original, wanted;
int size;
printf("Welcome to use this number base converter program.\n");
printf("Please input the original base: ");
scanf("%d", &original);
printf("Please input a base-%d number with more more than 10 digits: ",
original);
scanf("%s", baseString);
while (baseString[count] != '\0')
count++;
int *baseNumber = (int*) malloc(count * sizeof(int));
for (i = 0; i < count; i++) {
baseNumber[i] =
baseString[i] <= '9' ? baseString[i] - '0' : baseString[i] - 'A' + 10;
}
int* result_array;
printf("Please input the target base: ");
scanf("%d", &wanted); //doesn't read anything past this point
printf("Target base: %d", wanted);
if (original == 16) {
if (wanted == 2) {
result_array = hex2binary(baseNumber, count, size);
for (j = 0; j < size; j++) {
printf("Result: %d", result_array[j]);
}
}
}
}
I know it can't be something to difficult, but I can't seem to figure out why it isn't even producing some kind of output.
This line
result_array = hex2binary(baseNumber, count, size);
is incorrect because this function needs a pointer argument
int* hex2binary(int hex_array[], int input_array_size, int* return_array_size)
So it should be called like this
result_array = hex2binary(baseNumber, count, &size); // note the &
Then the subsequent loop
for (j = 0; j < size; j++)
will no longer be using the uninitialised variable size.

Resources