How to identify the digit 7 between the given number - c

I want my code to print "YES" if there is digit 7 in the entered number, and otherwise print "NO".
When I use while(T != 0) for test cases, my code prints "YES" for all the numbers - even for number 45. Without while(T != 0) my code runs perfectly.
Where is my mistake?
#include <stdio.h>
int main() {
int T;
scanf("%d", &T);
while (T != 0) {
int X;
scanf("%d", &X);
int flag, result;
while (X != 0) {
result = X % 10;
if (result == 7) {
flag = 1;
}
X = X / 10;
}
if (flag == 1) {
puts("YES");
} else {
puts("NO");
}
T--;
}
return 0;
}

After trying out your code, the main issue was not with the "while" test. Rather, in the code your test flag was not being reset so once the a value was found to have the digit "7" in it, all subsequent tests were noted as being "YES". With that, following is a refactored version of your code.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int T;
printf("How many numbers to test: "); /* Clarifies what the user is being asked for */
scanf("%d", &T);
while (T != 0)
{
int X;
printf("Enter a number to be tested: "); /* Again, lets the user know what to enter */
scanf("%d", &X);
int flag = 0, result;
while (X != 0)
{
result = X % 10;
if (result == 7)
{
flag = 1;
}
X = X / 10;
}
if (flag == 1)
{
puts("YES");
}
else
{
puts("NO");
}
flag = 0; /* Needs to be reset after being set and before next check */
T--;
}
return 0;
}
Some things to note.
Although not really needed, verbiage was added as prompts to clarify to the user what needed to be entered for values.
Most importantly, the flag variable gets initialized to zero and then subsequently gets reset to zero after each test has been completed.
With those bits addressed, following is some sample terminal output.
#Vera:~/C_Programs/Console/Seven/bin/Release$ ./Seven
How many numbers to test: 4
Enter a number to be tested: 3987
YES
Enter a number to be tested: 893445
NO
Enter a number to be tested: 8445
NO
Enter a number to be tested: 58047
YES
Give that a try and see if it meets the spirit of your project.

Related

Certain values give incorrect results for prime number checking function

I recently wrote a program in C for a calculator. To produce a function that checks if the user input is a prime number or not (amongst other functions).
I essentially used this code (excluding all other functions):
#include <stdio.h>
#include <math.h>
int testForPrime(int);
int main(void) {
int ioperand1 = 0;
printf("\nEnter the value to check if prime (positive integer): ");
scanf("%d", &ioperand1);
if (testForPrime(ioperand1) != 0)
printf("\nThis number is prime.\n");
else
printf("\nThis number is not prime.\n");
return 0;
}
int testForPrime(int operand1) {
int i = 0;
for (i = 2; i <= sqrt(operand1); i++) {
if (operand1 == 0 || operand1 == 1)
return 0;
else if (operand1 % i == 0)
return 0;
else
return 1;
}
}
^
This code above produces the errors
I am not sure why the code produces an error for the value 9 (I fixed that above by adding the condition: if (operand1 == 9), but I don't understand why 9 is seemingly the only value that results in an incorrect solution (It would say 9 was prime, but not any other number give an incorrect result).
One other bug that I remidied with an extra condition statement was the value of 2.
Before adding the extra conditional statement in the main function: if (ioperand1 == 2), the value 2 would always come up as a non prime number.
I originally found this solution to check for prime numbers online, and I still don't understand why the for loop starts from 2.
#include <stdio.h>
#include <math.h>
int testForPrime(int);
int main(void) {
int ioperand1 = 0;
printf("\nEnter the value to check if prime (positive integer): ");
scanf("%d", &ioperand1);
if (testForPrime(ioperand1) != 0 || ioperand1 == 2)
printf("\nThis number is prime.\n");
else
printf("\nThis number is not prime.\n");
return 0;
}
int testForPrime(int operand1) {
int i = 0;
for (i = 2; i <= sqrt(operand1); i++) {
if (operand1 == 0 || operand1 == 1 || operand1 == 9)
return 0;
else if (operand1 % i == 0)
return 0;
else
return 1;
}
}
^This code above fixed the problem, though I don't undesttand why the problem existed in the first place.
TL;DR:
I don't know why this code doesn't work without the extra conditional statements:
if (operand1 == 9) in function definition,
and
if (ioperand1 == 2) in main function.
If anyone could help clear this up, I'd appreciate it.
It is because your prime checking loop does not iterate. It always returns on the first iteration. It must run to completion, and then the number will be prime. So
int testForPrime(int operand1) {
if(operand1 < 2) {
return 0;
}
int sr = (int)round(sqrt(operand1));
for(int i = 2; i <= sr; i++) {
if (operand1 % i == 0) {
return 0;
}
}
return 1;
}

Counting the number of zero in an integer

The program would ask the user an integer input.
and it counts how many zero the int has.
constraints: use while loop
ex:
input: 2400
count: 2
now I have no problem in that part, only when the user would input a zero.
supposed it counts 1.
ex:
input 0
count: 1
but then the program returns count 0.
here's the code:
int main(){
int n, counter = 0;
printf("Enter the number: ");
scanf("%d", &n);
while(n != 0){
if(n % 10 == 0){
counter ++;
n=n/10;
}else{
break;
}
}
printf("%d", counter);
return 0;
}
Use functions.
int countZeroes(int x)
{
int result = !x; // if x == 0 then result = 1
while(x)
{
result += !(x % 10);
x /= 10;
}
return result;
}
int main(void)
{
printf("%d\n", countZeroes(0));
printf("%d\n", countZeroes(1000));
printf("%d\n", countZeroes(-202020));
}
https://godbolt.org/z/91hKr46eo
You have while(n != 0) this does so when you enter just 0 it doesn't run. So the counter that you have set to 0 at the beginning is still 0
Here is what I would have done :
int main()
{
int num, count = 0;
scanf("%d",&num);
if (num == 0) {
printf("1");
return 0;
}
while(num != 0) //do till num greater than 0
{
int mod = num % 10; //split last digit from number
num = num / 10; //divide num by 10. num /= 10 also a valid one
if(mod == 0) count ++;
}
printf("%d\n",count);
return 0;
}
Just don't forget to consider everything that can happen with a condition that you set
**Fixed it
A different version that prints the integer as a string, and looks for '0' characters in it. Tested.
#include <stdio.h>
#include <string.h>
int main(void)
{
int input = 0;
int zeroes = 0;
char *foundpos, teststring[100];
scanf("%d", &input);
sprintf(teststring, "%d", input);
foundpos = strchr(teststring, '0');
while (foundpos != NULL) {
++zeroes;
foundpos = strchr(foundpos + 1, '0');
}
printf("%d contains %d zeroes", input, zeroes);
}
Just count the zero digits you get between \n chars.
#include <stdio.h>
int main()
{
int ndigs = 0, c;
while ((c = getchar()) != EOF) {
switch (c) {
case '0': ndigs++;
break;
case '\n': printf(" => %d zero digs", ndigs);
ndigs = 0;
break;
}
putchar(c);
}
}
sample output:
$ ./a.out
123001202010
123001202010 => 5 zero digs
^D
$ _
No need to convert digits to a number, to convert it back to decimal digits. You can improve the program counting digits until a nondigit is detected, then output. But there's no need to convert a decimal representation of a number (in base 10) to internal representation to then get the digits you have destroyed (in the conversion) back again to count them.
As earlier mentioned, the problem is with the loop:
while(n != 0){
if(n % 10 == 0){
counter ++;
n=n/10;
}else{
break;
}
}
It doesnt do anything in case n == 0. But replacing it with n > 0 is not a good solution because ints can be negative too.
You should use do{}while() construction instead, it will always do one iteration of loop no matter what condition you put there. Notice that no matter what you get as a number, it is still a number so you can do one iteration of loop either way.
Just do as follows:
do{
if(n % 10 == 0){
counter ++;
n=n/10;
}else{
break;
}
} while( n != 0 );
This should work(if i didnt mess up the braces/semicolumns).

How to add the numbers inside the scanf in loop?

Is there some way to add all the numbers in a scanf loop? The loop would stop if the input number is negative. The problem is that the negative must also be included in the sum.
Here, I managed to get the sum of all the positive scanf values repeated in the loop, but the negative number is still not included in the sum of all the numbers.
#include <stdio.h>
main()
{
int z, x;
printf("Enter a number:\n");
z = 0;
scanf("%d", &x);
do
{
z += x;
scanf(" %d", &x);
} while (x >= 0);
printf("Sum = %d ", z);
return 0;
}
A simple rearrangement of the order of statements in your do ... while loop (and removal of the preceding scanf call) will do the trick:
#include<stdio.h>
int main() // You are returning "0" so declare "int" as return type
{
int x = 0, z = 0; // Easier to initialize at the same time as declaration.
printf("Enter a number:\n");
// scanf ("%d", &x); // Don't read here - do that inside the loop.
do {
int test = scanf(" %d", &x); // Read as the FIRST statement in the loop ...
if (test != 1) { // If the "scanf" call failed, we need to clear the input stream ...
int c;
while ((c = getchar()) != '\n' && c != EOF)
; // Clear any offending input
if (c == EOF) break; // Probably can't recover from an EOF, so exit the while loop
}
else z += x; // ... then we can add X even if it's negative
} while (x >= 0); // But end the loop when it IS negative anyway
printf("Sum = %d ", z);
return 0;
}
Note that I have added a test variable to makes sure that the scanf operation succeeded. If the usser enters foo (as mentioned in the comment by William Pursell), then the input buffer is cleared, the addition is skipped, and the read will be attempted again.
I'm not sure if you want to handle an input stream that does not contain a negative value as an error, but you could simply do:
#include <stdio.h>
#include <stdlib.h>
int
main(void)
{
int sum = 0, x, rv;
while( 1 == (rv = scanf ("%d", &x)) ){
sum += x;
if( x < 0 ){
break;
}
}
if( rv == 0 ){
fprintf(stderr, "Invalid input\n");
} else {
printf("Sum = %d\n", sum);
}
return rv == 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
I think the following behavior is reasonable:
$ echo 4 5 8 5| ./a.out
Sum = 22
$ echo 4 5 -1 5| ./a.out
Sum = 8
$ echo 4 5 not-an-integer 5| ./a.out
Invalid input
Inverting the lines inside the loop should do it:
int z, x;
int ch;
printf("Enter a number:\n");
z = 0;
do
{
if (scanf("%d", &x) == 1) // checking if parsing was successful
{
z += x; // if so, perform the sum
}
else
{
puts("Bad input"); // if user inputs a bad value
while((ch = getchar()) != '\n' && ch != EOF){} // you clear the input buffer
}
} while (x >= 0);
printf("Sum = %d ", z);
Note that I also removed the first scanf ouside the loop, which becomes unneeded.

Need help fixing Segmentation Fault

I had this working a second ago but accidentally broke it. Can anyone help me fix it? I'm getting a Segmentation Fault so I assume I messed up the pointers at some point. It's supposed to generate a bunch of random numbers depending on user input.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
unsigned int mySeed; // creates our variables
unsigned int taps[2];
unsigned int temp[2];
unsigned int myToggle;
FILE *fp;//opens the file
fp = fopen("random.txt", "w");//sets the file to open equal to this file
int TapInputs = 1;
int count = 0;
int tap;
int myNewNumber = 0;
mySeed = atoi(argv[1]);
if(atoi(argv[1]) > 0) //Error checking for negative inputs.
{
printf("Please enter the taps you'd like to use : ");//prompts user to input the taps and then makes sure theyre in range
while(TapInputs)
{
scanf("%d",&tap);
if((tap > 0)&&(tap < 33))
{
*(taps+count)=tap;
}
else if(tap == -1) // when we find -1 we do this
{
TapInputs = 0;
}
else if(tap > 32)
{
exit(0);
}
count++;
}
printf("How many numbers do you want to generate: "); //prompts user to input the number of numbers to use
scanf("%d", &myNewNumber);
while (myNewNumber < 0)// error checking for positive inputs
{
printf("How many numbers do you want to generate: ");
scanf("%d", &myNewNumber);
}
printf("\nRandom Numbers:");
while(myNewNumber)//creates number equal to the user input number in the previous step
{
temp[0] = mySeed; // makes temp1 the seed
temp[1] = mySeed; // makes temp2 the seed
temp[0] = (temp[0] >> taps[0]) & 1; // checks and sets the bit
temp[1] = (temp[1] >> taps[1]) & 1; // checks and sets the bit
myToggle = (temp[0] ^ temp[1]); // here we xor the temp1 and 2
mySeed = (mySeed << 1) ^ myToggle; // use bittoggle to shift the seed and generate a new number
fprintf(fp, "%d\r\n", mySeed); // wrties the generated number into the file
printf("\n%d", mySeed); // prints the number
myNewNumber -= 1;
}
fclose(fp); // closes file, creates a new line and returns 0 to the fucntion
printf("\n");
return 0;
}
else
{ // if the number the user input was 0 we will end our program
exit(0);
}
}
The fault happens immediately upon execution.
This piece of code :
while(TapInputs)
{
scanf("%d",&tap);
if((tap > 0)&&(tap < 33))
{
*(taps+count)=tap;
}
else if(tap == -1) // when we find -1 we do this
{
TapInputs = 0;
}
else if(tap > 32)
{
exit(0);
}
count++;
}
is executed until you find TapInputs to be false, or in other words 0. This will happen only if you give -1 as an input to scanf("%d", &tap). Until then, you will keep reading and also incrementing count.
But some lines above, you have declared
unsigned int taps[2];
and in your while loop you do
*(taps+count)=tap;
So, if you have read tap enough times and keep finding it between 0 and 33, until you find it -1, count will have increased enough to get your array out of bounds.
I think problem is in this line , mySeed = atoi(argv[1]);
you have to do something like this,
you can put the code from that in an if condition ,
if(agrc>1)
{
mySeed = atoi(argv[1]);
---------------------
--------------------
}
I have tested...it is working
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
unsigned int mySeed; // creates our variables
unsigned int taps[2];
unsigned int temp[2];
unsigned int myToggle;
FILE *fp;//opens the file
fp = fopen("random.txt", "w");//sets the file to open equal to this file
int TapInputs = 1;
int count = 0;
int tap;
int myNewNumber = 0;
if(agrc>1)
{
mySeed = atoi(argv[1]);
if(atoi(argv[1]) > 0) //Error checking for negative inputs.
{
printf("Please enter the taps you'd like to use : ");//prompts user to input the taps and then makes sure theyre in range
while(TapInputs)
{
scanf("%d",&tap);
if((tap > 0)&&(tap < 33))
{
*(taps+count)=tap;
}
else if(tap == -1) // when we find -1 we do this
{
TapInputs = 0;
}
else if(tap > 32)
{
exit(0);
}
count++;
}
printf("How many numbers do you want to generate: "); //prompts user to input the number of numbers to use
scanf("%d", &myNewNumber);
while (myNewNumber < 0)// error checking for positive inputs
{
printf("How many numbers do you want to generate: ");
scanf("%d", &myNewNumber);
}
printf("\nRandom Numbers:");
while(myNewNumber)//creates number equal to the user input number in the previous step
{
temp[0] = mySeed; // makes temp1 the seed
temp[1] = mySeed; // makes temp2 the seed
temp[0] = (temp[0] >> taps[0]) & 1; // checks and sets the bit
temp[1] = (temp[1] >> taps[1]) & 1; // checks and sets the bit
myToggle = (temp[0] ^ temp[1]); // here we xor the temp1 and 2
mySeed = (mySeed << 1) ^ myToggle; // use bittoggle to shift the seed and generate a new number
fprintf(fp, "%d\r\n", mySeed); // wrties the generated number into the file
printf("\n%d", mySeed); // prints the number
myNewNumber -= 1;
}
fclose(fp); // closes file, creates a new line and returns 0 to the fucntion
printf("\n");
return 0;
}
else
{ // if the number the user input was 0 we will end our program
exit(0);
}
}
}

How to show the digits which were repeated in c?

The question is that show the digits which were repeated in C.
So I wrote this:
#include<stdio.h>
#include<stdbool.h>
int main(void){
bool number[10] = { false };
int digit;
long n;
printf("Enter a number: ");
scanf("%ld", &n);
printf("Repeated digit(s): ");
while (n > 0)
{
digit = n % 10;
if (number[digit] == true)
{
printf("%d ", digit);
}
number[digit] = true;
n /= 10;
}
return 0;
}
But it will show the repeated digits again and again
(ex. input: 55544 output: 455)
I revised it:
#include<stdio.h>
int main(void){
int number[10] = { 0 };
int digit;
long n;
printf("Enter a number: ");
scanf("%ld", &n);
printf("Repeated digit(s): ");
while (n > 0)
{
digit = n % 10;
if (number[digit] == 1)
{
printf("%d ", digit);
number[digit] = 2;
}
else if (number[digit] == 2)
break;
else number[digit] = 1;
n /= 10;
}
return 0;
}
It works!
However, I want to know how to do if I need to use boolean (true false), or some more efficient way?
To make your first version work, you'll need to keep track of two things:
Have you already seen this digit? (To detect duplicates)
Have you already printed it out? (To only output duplicates once)
So something like:
bool seen[10] = { false };
bool output[10] = { false };
// [...]
digit = ...;
if (seen[digit]) {
if (output[digit])) {
// duplicate, but we already printed it
} else {
// need to print it and set output to true
}
} else {
// set seen to true
}
(Once you've got that working, you can simplify the ifs. Only one is needed if you combine the two tests.)
Your second version is nearly there, but too complex. All you need to do is:
Add one to the counter for that digit every time you see it
Print the number only if the counter is exactly two.
digit = ...;
counter[digit]++;
if (counter[digit] == 2) {
// this is the second time we see this digit
// so print it out
}
n = ...;
Side benefit is that you get the count for each digit at the end.
Your second version code is not correct. You should yourself figured it out where are you wrong. You can try the below code to print the repeated elements.
#include<stdio.h>
int main(void){
int number[10] = { 0 };
int digit;
long n;
printf("Enter a number: ");
scanf("%ld", &n);
printf("Repeated digit(s): ");
while (n > 0)
{
digit = n % 10;
if (number[digit] > 0)
{
number[digit]++;;
}
else if (number[digit] ==0 )
number[digit] = 1;
n /= 10;
}
int i=0;
for(;i<10; i++){
if(number[i]>0)
printf("%d ", i);
}
return 0;
}
In case you want to print the repeated element using bool array (first version) then it will print the elements number of times elements occur-1 times and in reverse order because you are detaching the digits from the end of number , as you are seeing in your first version code output. In case you want to print only once then you have to use int array as in above code.
It is probably much easier to handle all the input as strings:
#include <stdio.h>
#include <string.h>
int main (void) {
char str[256] = { 0 }; /* string to read */
char rep[256] = { 0 }; /* string to hold repeated digits */
int ri = 0; /* repeated digit index */
char *p = str; /* pointer to use with str */
printf ("\nEnter a number: ");
scanf ("%[^\n]s", str);
while (*p) /* for every character in string */
{
if (*(p + 1) && strchr (p + 1, *p)) /* test if remaining chars match */
if (!strchr(rep, *p)) /* test if already marked as dup */
rep[ri++] = *p; /* if not add it to string */
p++; /* increment pointer to next char */
}
printf ("\n Repeated digit(s): %s\n\n", rep);
return 0;
}
Note: you can also add a further test to limit to digits only with if (*p >= '0' && *p <= '9')
output:
$./bin/dupdigits
Enter a number: 1112223334566
Repeated digit(s): 1236
Error is here
if (number[digit] == true)
should be
if (number[digit] == false)
Eclipse + CDT plugin + stepping debug - help you next time
As everyone has given the solution: You can achieve this using the counting sort see here. Time complexity of solution will be O(n) and space complexity will be O(n+k) where k is the range in number.
However you can achieve the same by taking the XOR operation of each element with other and in case you got a XOR b as zero then its means the repeated number. But, the time complexity will be: O(n^2).
#include <stdio.h>
#define SIZE 10
main()
{
int num[SIZE] = {2,1,5,4,7,1,4,2,8,0};
int i=0, j=0;
for (i=0; i< SIZE; i++ ){
for (j=i+1; j< SIZE; j++){
if((num[i]^num[j]) == 0){
printf("Repeated element: %d\n", num[i]);
break;
}
}
}
}

Resources