Weird Array Outputs - c

Okay what am I doing wrong here?
This program is supposed to read 20 integers and then output an array of the integers that are not duplicates (Output each integer only once).
//Program to read 20 integers and return each integer only once (no duplicates).
#include <stdio.h>
int main()
{
int a, b, count=0, temp, array1[20];
printf("Enter 20 array elements between 1 and 10 inclusive\n");
for (a=0; a<20; a++) //Loop to enter 20 elements
{
scanf("%d", &temp);
for (b=0; b<=20; b++) //Loop to test each new element against all previous entered elements
{
if (array1[b] == temp) //If duplicate increment count
{
count++;
}
else if (count == 0 && b == 20) //If there have been no duplicates and 20 numbers have been tested... add entered number to the array
{
array1[a] = temp;
}
}
}
for (a=0; a<20; a++)
{
printf("%d\t", array1[a]);
}
return 0;
}

There are the following things wrong here.
In the inner loop, during the first check, you are comparing against 20 elements. On receiving the first element you do not have any elements to compare against. I have added a variable size to indicate the size of the array. size is initialized to 0.
The if (count == 0 && b == 20) should be moved outside the for loop and can be simplified to if (count == 0)
When an element is added to the array it is added at array1[size] and size is incremented.
You need to reinitialize count at every outer for loop as shown below.
The printing will print size elements that are non duplicate.
Code is below.
//Program to read 20 integers and return each integer only once (no duplicates).
#include <stdio.h>
int main()
{
int a, b, count=0, temp, array1[20];
int size = 0;
printf("Enter 20 array elements between 1 and 10 inclusive\n");
for (a=0; a<20; a++) //Loop to enter 20 elements
{
scanf("%d", &temp);
count = 0;
for (b=0; b<size; b++) //Loop to test each new element against all previous entered elements
{
if (array1[b] == temp) //If duplicate increment count
{
count++;
}
}
if (count == 0) //If there have been no duplicates and 20 numbers have been tested... add entered number to the array
{
array1[size] = temp;
size++;
}
}
for (a=0; a<size; a++)
{
printf("%d ", array1[a]);
}
return 0;
}
This code will accept 20 elements and store and display as many as were non duplicate (which can be 1-20). If you want to store 20 non duplicate elements (entering possibly many more than 20) it can be easily modified.

You have multiple reads of uninitialized variables which is undefined behavior. You also access the array out of range.
for (b=0; b<=20; b++)
^^
This will result in b in the range [0..20]
{
if (array1[b] == temp) //If duplicate increment count
^^^^^^^^^
array1[b] is uninitialized
and when b is 20 you access out of range
Further you only write to the array when count is 0 and b is 20
else if (count == 0 && b == 20)
{
array1[a] = temp;
}
Notice that you never reset count so after the first match you'll never write the array again
BTW - you print:
Enter 20 array elements between 1 and 10 inclusive
but you never perform any check of the input value to be in that range.

Related

Why %d is showing 0 in my c program output?

The program is to find the largest number amongst all the entered integers. It asks the user to enter a number 10 times or press 0 to quit, whichever is earlier. But, the output is not as expected. I will appreciate it if you can help a newbie.
#include <stdio.h>
int main()
{
int num[10];
int max, a;
for (a = 0; a < 10; a++)
{
printf("Enter the integer: ");
scanf("%d", &num[a]);
if (num[a] == 0)
break;
}
for(a = 0; a < 10; a++)
{
num[0] = max;
if(max < num[a])
{
num[a] = max;
}
}
printf("This is the largest integer: %d", max); //The output is coming wrong here.
return 0;
}
Don't use num[0], you are overwriting it with max variable which is not initialized, so it is 0.
Use max to the minimum type variable (INT_MIN with limits.h header file) or initalize it to max = num[0] after input is captured.
#include <limits.h>
int max = INT_MIN;
Also you need to change your second for loop as follows so as to update the max variable as you iterate, and not the num[] variables. Loop variable starts with 1 if you already assumed max to be first element before, else loop variable will start with 0.
for(a = 1; a < 10; a++) // a=0 if max was initialized to INT_MIN above
{
if(num[a]>max)
{
max = num[a];
}
}
You never assign the max variable.
What you want to do is to check if the value entered is greater than each one you've previously entered, so you would need to use the following condition:
if (num[a] > max)
max = num[a];
You also need to initialize max to some value (let's say, if you expect to have only positive integers, it could be 0, but have a look at Jigsaw answer for a better solution): int max = 0;.
And eventually add an if-condition that checks if max is 0, that way you know if no values have been entered:
if(max == 0)
printf("No values have been entered.");
else printf("This is the largest integer: %d", max);
Notice that you can assign the elements of num and update max in the same for loop, therefore the second for becomes completely useless and you can remove it:
#include <stdio.h>
int main()
{
int num[10];
int max = 0, a;
for (a = 0; a < 10; a++)
{
printf("Enter the integer: ");
scanf("%d", &num[a]);
if (num[a] == 0)
break;
if (num[a] > max)
max = num[a];
}
if(max == 0)
printf("No values have been entered.");
else printf("This is the largest integer: %d", max);
return 0;
}
I suggest you to turn on your compilers warning, especially -Wall and -Wextra, so you would notice problems like these:
<source>: In function 'main':
<source>:17:16: warning: 'max' may be used uninitialized [-Wmaybe-uninitialized]
17 | num[0] = max;
| ~~~~~~~^~~~~
<source>:6:9: note: 'max' was declared here
6 | int max, a;
| ^~~
For starters this for loop
for (a = 0; a < 10; a++)
{
printf("Enter the integer: ");
scanf("%d", &num[a]);
if (num[a] == 0)
break;
}
can enter less than 10 elements in the array num due to the condition
if (num[a] == 0)
break;
So the next loop has to traverse exactly a elements of the array not 10. So in the next loop you have to use another variable for the index as for example
for( int i = 0; i < a; i++)
The variable max was not initialized
int max, a;
So this for loop invokes undefined behavior where the variable max is assigned to elements of the array or where it is compared with elements of the array.
for(a = 0; a < 10; a++)
{
num[0] = max;
if(max < num[a])
{
num[a] = max;
}
}
Moreover the variable max is not changed within the for loop. So the loop in whole does not make sense.
Pay attention to that the user can enter 0 at once. So the array will not contain any valid values. In this case the array does not have a maximum value.
Your program can look for example the following way
#include <stdio.h>
int main( void )
{
enum { N = 10 };
int num[N];
int i = 0;
do
{
printf( "Enter the integer (0 - stop): " );
scanf( "%d", &num[i] );
} while ( num[i] != 0 && ++i < N );
int max_i = 0;
for ( int j = 1; j < i; j++ )
{
if ( num[max_i] < num[j] )
{
max_i = j;
}
}
if ( i == 0 )
{
puts( "You have not entered numbers unequal to zero." );
}
else
{
printf("This is the largest integer: %d", num[max_i] );
}
return 0;
}
You neither initialise nor ever write any value at all to the variable max. Using uninitialised variables is undefined behaviour.
You seem to know how to write 0 into a. But for max you seem to have it reversed. Remember that with = the value on the right of it goes into the variable on the left of it.
To fix the problem, turn any something = max; which occurs in your code into max = something;.

Pythagorean triplets program

I have written a program that should be rather simple but on execution, it is not giving the wanted results. Even when debugging the program, I guess I found the error (getting stuck in the first if condition) but I'm not able to solve it (my inexperience perhaps). Anyways, this program, which should have been frugal, took 3 days whereas I expected it to take mere hours. Please help me with guiding me where I'm going wrong and how to solve it.
Here is the code
/*WAP to read pre entered no. of ints. consider only +ve and print the pythagorean triplets in them.*/
#include <stdio.h>
int main(){
int c,p,pp,count=0,a;
printf("How many entries to accept?\n");
scanf("%d",&a);
printf("Enter the nos.\n");
for (int i = 0; i < a; i++)
{
scanf("%d",&c);
if (c<0) //skip -ve nos.
{
continue;
}
if (count==0)
{
pp=c;
count++;
}
else if (count==1)
{
p=c;
count++;
}
else if ((pp*pp)+(p*p)==(c*c)) //Tracking count not necesarry after first three
{
printf("Pythagorean triplet found\n");
printf("%d %d %d",pp,p,c);
pp=p;
p=c;
}
}
return 0;
}
The main objective is to first scan a no. to signify the inputs to be read. Then scan the inputs, separated by a space or enter, in a loop which will only accept the no. of inputs stated before. It should neglect any -ve entries. It should print out the Pythagorean triplet if it encounters one, in a consecutive manner i.e. the triplet should appear one after the other & not randomly. We have to do the task without using arrays.
sample input is (you can consider any)(all given through the terminal)
(no. of entries)
6
1 -1 3 4 -4 5
(Here it will ignore -1 & -4)
expected output will be
Pythagorean triplet found
3 4 5
I am still learning so sorry for the elaborate program.
Thank you in advance.
since I cant see the input file I dont know if the values are sorted, since we need to identify which is the hypotenuse, makes it a bit more fiddly.
Also not clear what 'skip negatives' means. Does it mean
that we might see 3 -6 4 5 and say 'yes 3,4,5' is a triple
that we might see 3 -4 5 and say yes 3 4 5
or that we might see 3 -4 5 and simply ignore the whole set
I have assumed the first one
#include <stdio.h>
int main() {
printf("How many entries to accept?\n");
int a;
if (scanf("%d", &a) != 1) {
printf("bad input\n");
return (-1);
}
printf("Enter the nos.\n");
for (int i = 0; i < a; i++)
{
int sides[3] = { 0 };
int max = 0; // longest side length -> hypot
for (int j = 0; j < 3; j++)
{
int c;
if (scanf("%d", &c) != 1) {
printf("bad input\n");
return (-1);
}
if (c < 0) //skip -ve nos.
j--; // try again
else {
if (c > max) {
max = c;
}
sides[j] = c;
}
}
int hyp = max * max; // hypotenuse squared
int adjTot = 0; // adj sides squared total
for (int j = 0; j < 3; j++)
{
if (sides[j] == max)
continue;
adjTot += sides[j] * sides[j];
}
if (adjTot == hyp)
printf("%d %d %d is py\n", sides[0], sides[1], sides[2]);
else
printf("%d %d %d isnt py\n", sides[0], sides[1], sides[2]);
}
return 0;
}
Since you say you are reading from a file it just exits if there is non numeric data

size of array in dynamic allocation problem

I have to solve this problem: "Write a program that reads from the keyboard a sequence of 10 integers, and writes the same sequence in reverse order, dividing by 2 the even elements of the sequence."
I want to know the size of the array p to print it in the reverse order but when I try to get the size of array with "l = sizeof(p)/sizeof(p[0])" the for loop below doesn't works.
int main(){
int n,i;
int *p;
int l;
printf("How long the array? ");
scanf("%d",&n);
p = malloc(n*sizeof(int));
if(p != NULL){
for(i=0;i<n;i++){
printf("Insert number in index (%d) of array: ",i);
scanf("%d",p+i);
}
l = sizeof(p)/sizeof(p[0]);
for (i=n;i == 0;i--){
if(p[i] % 2 == 0){
printf("%d ",p[i]/2);
}
else{
printf("%d",p[i]);
}
}
}
else{
printf("ERROR!!");
}
return 0;
}
The return value of sizeof will be a size in bytes - not of the array, but the pointer, which is an integer in this case. What you want is the length. You have the length stored in n.
Your for-loop is a bit confusing. Try using n - 1 (the length of the array) in order to start the loop by accessing the last index value of the array. Also, the printf inside the else block doesn't space the output correctly. Try the following code:
for (i = n - 1; i >= 0; --i)
{
if (p[i] % 2 == 0)
{
printf("%d ", p[i] / 2);
}
else
{
printf("%d ", p[i]);
}
}
when I try to get the size of array with l = sizeof(p)/sizeof(p[0]) the for loop below doesn't works.
This fails as p is a pointer, not an array. The size of p is something like 4 or 8.
I want to know the size of the array p
p is not an array. Simply use the n as used in the allocation.

Keyboard input of array of bits

I want to make a program that applies some logic gates (AND, OR, XOR) to elements of two arrays of 1 and 0. But I am having problems with the user input of these arrays. I don't know how to make the arrays store only 1 and 0, for example if I type 5 I want the program to tell me it's neither 0 nor 1 and start over, I tried something but it's not working:
int v1[50],v2[50],i,j,n;
printf("Number of elements in arrays : ");
scanf("%d",&n);
printf("Introduce elements of first array :\n");
for(i=0;i<n;i++)
if(v1[i] == 0 || v1[i]==1)
scanf("%d",&v1[i]);
else (i'll make it a function and I want it to repeat if the elements given are not 1 and 0)
for(i=0;i<n;i++)
printf("%d",v1[i]);
In your first for loop, where you are reading the input, you should read the input first, and then decide whether you want to have the user try the input again. So, the first few lines of your for loop should look like this:
for (i = 0; i < n; i++) {
scanf("%d", &v1[i]);
if (!(v1[i] == 0 || v1[i] == 1)) {
printf("Invalid input, please try again");
//Ask for another input, but do not advance i
}
}
This code will tell the user if they inputted a bad character, but it will not update the array correctly. To do this, all you need to do is decrement i once. This will make the previous "bad" value in v1 get overwritten.
for (i = 0; i < n; i++) {
scanf("%d", &v1[i]);
if (!(v1[i] == 0 || v1[i] == 1)) {
printf("Invalid input, please try again");
i--;
}
}
We are not done, however. In your original code, you defined v1 to be an array of 50 elements. What if someone wants to input 51 elements? You would eventually end up with accessing an array index that is out of bounds, which could lead to some very big issues. So, you need to do some dynamic memory allocation using malloc
int *v1, i, n;
printf("How many elements will be in the bit array? ");
scanf("%d", &n);
//Dynamically allocate enough memory for an integer array of length n
v1 = (int *) malloc(n * sizeof(int));
You can read more about malloc here.
So, the whole code would look like this:
#include <stdlib.h>
#include <stdio.h>
int main() {
int *v1, i, n;
printf("How many elements will be in the bit array? ");
scanf("%d", &n);
//Dynamically allocate enough memory for an integer array of length n
v1 = (int *) malloc(n * sizeof(int));
printf("Input the elements of the first array (separated by newlines):\n");
for (i = 0; i < n; i++) {
scanf("%d", &v1[i]);
if (!(v1[i] == 0 || v1[i] == 1)) {
printf("Invalid input, please try again");
i--;
}
}
Suppose you have an array consisting of 50 elements:
int v1[50];
If you want to fill it with values only of 0 and 1 you should set up a while loop, until the user puts in correct data:
int iter, result;
for (iter = 0; iter < 50; iter++)
{
while ((result = scanf("%d", &v1[iter])) != 1 // no number was found
|| (v1[iter] != 0 && v1[iter] != 1)) // OR it was and it wasn't 0 or 1
{
if (result != 1)
scanf("%*s"); // case 1: dispose of bad input
else
printf("Please, use only values 0 or 1\n"); // case 2: remind the user
}
}
}

How to find the largest and smallest number in an array in c

I have to find a way to display the Maximum and Minium number in an array, the size of the array is 100 and will not exceed that and there is not need for input validation. The program will keep asking for input until 0 is encountered and it too will get added to the array.
I have everything figured out except how to keep track which is the largest and smallest value. I'd appreciate it if someone can fix my code or show me.Another problem I'm having is getting the loop to terminate and do max/min calculation within the while loop when the input is equal to 0.
/*
============================================================================
Name : test.c
Author :
Version :
Copyright : Your copyright notice
Description : Hello World in C, Ansi-style
============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#define n 100
int main(void){
int numbers[n];
int i = 1;
int j;
int input;
int maxvalue;
int minvalue;
printf("Enter the next array element>");
input = scanf("%d", &numbers[100]);
while (input != 0){
numbers[i] = input;
i++;
printf("Enter the next array element, while loop>");
input = scanf("%d", &numbers[n]);
if (input == 0){
printf("Enter the next array element, if loop");
numbers[i] = 0;
for (j =2;j <= i; j++){
minvalue = numbers[1];
j++;
if (numbers[j] > minvalue){
maxvalue = numbers[j] ;
}
else{
minvalue = numbers[j] ;
}
}
}
}
printf("%f\t", maxvalue);
printf("%f\n", minvalue);
}
EDIT: I took all off your suggestions and edited my code. This is my code below. However, it's output isnt what I'm expecting.
#include <stdio.h>
#include <stdlib.h>
#define N 100
int main(void){
int numbers[N];
int i = 0;
int j;
int input;
int maxvalue;
int minvalue;
printf("Enter the next array element>");
scanf("%d", &input);
while (input != 0){
numbers[i] = input;
i++;
if (input == 0){
i++;
numbers[i] = 0;
minvalue = numbers[0];
maxvalue = numbers[0];
for (j=0;j<=i-1;j++){
if (minvalue >= numbers[j]){
minvalue = numbers[j];
}else if (maxvalue <= numbers[j]){
maxvalue = numbers[j];
}
}
/* min = value of first array element
max = value of first array element
begin loop for each array element, index = 0 to (n-1)
--- if array element value is less than min, set min to this value
--- if array element value is more than max, set max to this value
increment index and repeat loop til last index is completed
average = sum / number of elements (n).
max and min will hold their correct values.*/
}
printf("Enter the next array element, while loop>");
scanf("%d", &input);
}
printf("%d\t", maxvalue);
printf("%d", minvalue);
}
This is the output, I'm getting! Can someone solve this for me.
Enter the next array element>1
Enter the next array element, while loop>2
Enter the next array element, while loop>3
Enter the next array element, while loop>0
12190144 l6Press [Enter] to close the terminal
FINAL EDIT: I SOLVED THIS ON MY OWN. I put the min/max checking outside the master WHILE loop, this allowed the input of 0 to be entered in the array.
#include <stdio.h>
#include <stdlib.h>
#define N 100
int main(void){
int numbers[N];
int i = 0;
int j;
int input;
int maxvalue =1;
int minvalue = 1;
printf("Enter the next array element>");
scanf("%d", &input);
minvalue = input;
maxvalue = input;
while (input != 0){
numbers[i] = input;
++i;
printf("Enter the next array element>");
scanf("%d", &input);
if (input == 0){
numbers[i] = 0;
++i;
}
}
for (j =0;j<i;j++){
if (numbers[j] >= maxvalue){
maxvalue = numbers[j];
}
if(numbers[j] < minvalue){
minvalue = numbers[j];
}
}
printf("%d\t", maxvalue);
printf("%d\n", minvalue);
}
First of all, you're assigning input to the return value of scanf(). This is the number of items assigned by the call, and since you say the input will always be correct, this value will always be 1.
Secondly, you're writing past the end of the numbers[] array with the line:
input = scanf("%d", &numbers[100]);
(you should do scanf("%d, &input) instead, and assign numbers[i] to input in your loop.
Finally, you don't need to recalculate maxvalue and minvalue by iterating through numbers[] every iteration of your loop. Instead, just compare them to input and assign them accordingly.
Hopefully this puts you on the right track.
It looks like your central problem is that you compare each number only against minvalue. That's fine for deciding whether to replace the current minvalue, but obviously it doesn't tell you anything about the relationship of each element to maxvalue.
Another problem: it makes sense to initialize minvalue from the first element, but not if you do it in the loop. That just invalidates all your prior work.
You need to do the same initialization with maxvalue as well. You should initialize that number to the first value.
You should also make a decision about calculating the min and max as you accumulate the data or in a pass through the data when done. What you don't want to do, however, is loop through past elements with every new one. That gives your program quadratic time complexity for no benefit.
Finally, don't tolerate crummy formatting. Debugging always involves studying the code and you will want it to always be perfectly formatted both to be professional about things and also to facilitate reading your own work.
You are asking two questions, about the strategy for the min / max computation and for the loop. Don't do that (to yourself) but solve one problem at a time. So first put something like
signed int input[] = { 8, -5 , /* some more values */ };
size_t const n = sizeof input/ sizeof input[0];
at the start and forget about your scanf problems.
Then wrap your min/max detection in the appropriate loop instruction.
Then compile your code with warnings on: e.g -Wall for gcc, but this might vary for your compiler.
Mine the tells me something:
test-numbers.c:21: warning: 'maxvalue'
may be used uninitialized in this
function test-numbers.c:22: warning:
'minvalue' may be used uninitialized
in this function
This tells you that you are doing something very wrong in not considering the starting point of your algorithm well.
I've reindented your code and replaced lots of it with `/* ...PLACEHOLDER... */
#include <stdio.h>
#include <stdlib.h>
#define N 100
int main(void) {
int numbers[N];
int i = 0;
int input;
int maxvalue;
int minvalue;
printf("Enter the next array element>");
scanf("%d", &input);
while (input != 0) {
numbers[i] = input;
i++;
if (input == 0) {
/* ...PLACEHOLDER... */
}
printf("Enter the next array element, while loop>");
scanf("%d", &input);
}
printf("%d\t", maxvalue);
printf("%d", minvalue);
}
Hopefully you can see what happens when you enter 1, or 2, or 3 and when you enetr 0.
Hint: maxvalue and minvalue values are never changed.
Another hint: how many times does the while() line execute?
Edit with example run
For this example run, code is on the left side, what happens is on the left side
printf("Enter the next array element>"); |
scanf("%d", &input); | Enter 42
|
while (input != 0) { | input is 42, so you do the loop
numbers[i] = input; | numbers[0] = 42
i++; | i = 1
|
if (input == 0) { | input != 0; skip placeholder
/* ...PLACEHOLDER... */ |
} |
printf("Enter the next ...>"); |
scanf("%d", &input); | enter 3
} |
while (input != 0) { | input is 3
numbers[i] = input; | numbers[1] = 3
i++; | i = 2
|
if (input == 0) { | input != 0; skip placeholder
/* ...PLACEHOLDER... */ |
} |
printf("Enter the next ...>"); |
scanf("%d", &input); | enter 0
} |
while (input != 0) { | input is 0, skip while body
/* ...PLACEHOLDER... */ |
} |
printf("%d\t", maxvalue); | maxvalue hasn't been initialized
printf("%d", minvalue); | minvalue hasn't been changed
int cmp(const void *a,const void *b)
{
return *(const int*)a-*(const int*)b;
}
...
qsort( numbers, 100, sizeof(numbers[0]), cmp );
printf("\nmin: %d\nmax: %d",numbers[0],numbers[99]);

Resources