Pinpoint each digit within a given number of any length - c

I am trying to find each digit of a number entered by the user.
The length of the number is up to the user.
So far I have:
managed to limit what the user enters by using long long card, meaning they cannot enter more than about 18 or 19 characters and only numbers are accepted.
managed to get the first and last digit of that number, as well as the count of the number.
Now I wanted to:
specifically ask for no more than 16 digits max - > but it keeps saying undeclared identifier and am not sure where I go wrong
be able to identify each digit, i.e.:
53689
1st digit:5
2nd digit:3
3rd digit:6
etc.
I learned about modulus but I can't figure out how to tell it to stop at the 2nd last/3rd last digit.
I feel it's something really simple but how? especially if I don't know if the user enters 5 numbers or 15, otherwise I could say (repeat modulus x-1 times) or something like that.
Just for now, my code in case you see anything for #1.
Before I tried to limit the entry-conditions, it worked fine showing me card, card length and 1st,last digit.
#include <cs50.h>
#include <stdio.h>
//finding first 2 numbers and last number and checking what card type
int main(void)
{
int count = 0;
do
{
long long card = get_long_long("Enter your card number: ");
}
while (card ! = 0)
{
card = card / 10;
count++;
}
printf("Card number: %llu\n", card);
printf("Number of digits: %d \n", count);
firstdigit = card;
while (firstdigit >= 20)
{
firstdigit = firstdigit / 10;
}
printf("First digit = %d \n", firstdigit);
lastdigit = card % 10;
printf("Last digit= %d \n", lastdigit);
return 0;
}
info: Yes it is from CS50 credit, I can't understand the full exercise yet so I decided to take it apart and only learn how to write a program that analyses the number for first 2 digits and tells me what card type it is. To do so I'm trying to learn how to count every number on any given number length for practice, for me to actually understand this slowly, so please don't share a full answer to the credit problem.
I also haven't learned arrays or more complex solutions yet either.

As others have advised, "break the problem down into smaller pieces".
Here's an example of that approach. Instead of dealing with a massive number all at once, this 'segments' the number into the typical 4 sections embossed into a credit card. This might give you a start toward a solution...
int main() {
int count = 0;
long long card = get_long_long("Enter your card number: ");
long long cpy = card;
int blk4 = cpy % 10000; // 4 rightmost digits as int
cpy = cpy / 10000; // shift right
int blk3 = cpy % 10000; // next 4 digits as int
cpy = cpy / 10000; // shift right
int blk2 = cpy % 10000; // next 4 digits as int
cpy = cpy / 10000; // shift right
int blk1 = cpy % 10000; // leftmost 3-4 digits as int
printf( "Card number: %04d %04d %04d %04d\n", blk1, blk2, blk3, blk4 );
return 0;
}
Having shown that, please be advised that a credit card "number" is not a "number" in the usual sense. It is a string made-up only of digits. Trying to solve this CV50 problem with "integers" is going to lead to tears. It's time to learn about arrays of characters (even if every character is an ASCII digit)...

Related

is there a way to use Arrays in this C problem?

I am doing this problem:
"We have a huge decimal number N. Write a program to determine the followings:
The number of digits in N.
Is N an even number?
The number of zeros in it.
Is N a multiple of 11? Note that we can determine if N is a multiple of 11 by checking the difference between the sum of the odd positioned digits and the sum of the even positioned digits. For example, 82375 is not a multiple of 11 because the sum of the even positioned digits is 2 + 7 = 9, and the sum of the odd positioned digits is 8 + 3 + 5 = 16, and the difference between 9 and 16 is 7, which is not a multiple of 11.
We will give you the number one digit per line. For example, if you get digits ‘1’, ‘2’, ‘3’, ’4’, ‘0’ in order, then the number is 12340. The number will not start with 0.
Input Format
The input has several lines. Each line has a digit. EOF indicates the end of input.
Output Format
Output the four answers above line by line. If the number is even output a 1; otherwise a 0. If the number is a multiple of 11 output a 1; otherwise output a 0.
Subtask
10 points: you can store the decimal number in an integer without overflow
10 points: the number of digits is no more than 32768, so you can store digits in an array
80 points: you will get MLE if you use array"
my code is:
#include <stdio.h>
#include <stdbool.h>
int digit(long n);
int is_even(int n);
int count_zeros(long n);
int is_multiple(long n);
int main() {
int digits = 0;
long x;
scanf("%ld", &x);
digit(x);
int even = is_even(x);
printf("%d\n", even);
printf("%ld\n",count_zeros(x));
printf("%ld\n", is_multiple(x));
}
int digit(long n)
{
int digits = 0;
while (n > 0) {
n /= 10;
digits++;
}
printf("%ld\n", digits);
}
int is_even(int n)
{
if (n % 2 == 0)
return true;
else
return false;
}
int count_zeros(long n)
{
int count = 0;
while (n > 0) {
n /= 10;
if (n %10 == 0)
count++;
}
return count;
}
int is_multiple(long n)
{
if (n % 11 == 0) {
return true;
}
else
return false;
}
Basically i dont know how to meet the problem's requirement, so I made a simpler version of the problem. Any clue on how to do this?
If you comment on this, please be nice, I am a beginner and people was rude in the past,if you have nothing important to say, do not be mean/do not comment.
Well, the first problem with your current version is it only reads one integer. However problem states that each digit is on a separate line. The first approach may be to just replace that scanf with a loop and keeping multiplying by 10 and accumulating until end of file. Then the rest of the program would work fine.
A more advanced approach will be to use an array to store the digits. An integer can hold a very limited number of digits whereas you are only bounded with the size of available memory using array.
So in the reading loop rather than storing digits in an integer, you can store digits in an array (which could be fixed size because an upper limit is given). But for the rest of the program you should change the calculation to use digits in the array instead of the regular integer arithmetic.

C code stops when it suppose to run scanf line

I wrote a code which is supposed to count how many active bits (1s) are in a binary number that it gets from the user, considering the input is a correct binary number.
every time the code supposed to run the scanf() in main() it just get stuck , it does not stops running, it just feels like its thinking indefinitly and does not give any error
this is the code i wrote which in this situation prints "Please enter a binaric number: " and then it will get stuck
#include <stdio.h>
void count_bits(long int UserNum){
int cnt=0;
while(UserNum>0)
{
if (UserNum%10==1)
{
cnt++;
}
}
printf("there are %d active bits\n",cnt);
}
int main(){
long int UserNum=0;
printf("Please enter a binaric number: ");
scanf("%ld" , &UserNum);
count_bits(UserNum);
return 1;
}
if i write the scanf() first like this it won't even print:
scanf("%ld" , &UserNum);
printf("Please enter a binaric number: ");
what am i doing wrong here?
edit:
examples
input: 1101100
output:there are 4 active bits
input: 0110100111
output:there are 6 active bits
basically count how many ones there are in the number
I assume you want to interpret the decimal number entered by the user as a binary number. Your code does not check if your input follows this convention. If you enter a number that contains digits other than 0 or 1, every digit that is not 1 will be interpreted as 0. (UserNum%10==1)
Because of this assumption I don't discuss the fact that you normally would have to test bits with UserNum % 2 or UserNum & 1. (If you want to know how to enter or print a binary number instead of a decimal number, ask a separate question.)
Note that you may easily run in overlow issues if you enter a number that has too many digits.
Main problem: You have an endless loop in function count_bits because you don't update UserNum.
You can change it like this:
void count_bits(long int UserNum){
int cnt=0;
while(UserNum>0)
{
if (UserNum%10==1)
{
cnt++;
}
UserNum /= 10;
}
printf("there are %d active bits\n",cnt);
}
With this change the code works for me as expected.
Please enter a binaric number: 0110100111
there are 6 active bits
Example of a number that is too big. (I added a line printf("You entered %ld\n", UserNum);.)
Please enter a binaric number: 10110111011110111110
You entered 9223372036854775807
there are 0 active bits
If you swap the printf and scanf in main (with the endless loop in count_bits), the message "Please enter a binaric number: " is not printed because it does not contain a newline and the output is line-buffered by default. Apparently scanf leads to flushing the output.
If you change it to print a trailing newline like
printf("Please enter a binaric number:\n");
it should get printed before entering count_bits (with the endless loop).
As pointed out in multiple comments UserNum>0 stays always true, and thereforethe loop never stops.
But anyway, the count_bits function is wrong alltogether. Doing modulo 10 operations for counting bits is pointless.
You want this:
void count_bits(long int UserNum) {
int cnt = 0;
while (UserNum > 0)
{
if (UserNum % 2) // if UserNum is odd, then bit no. 0 is 1
cnt++;
UserNum = UserNum / 2; // division by 2 shifts bits to the right
}
printf("there are %d active bits\n", cnt);
}
As we are working on a bit level, it would be more idiomatic to use bit shift and bit mask operartions though:
void count_bits(long int UserNum) {
int cnt = 0;
while (UserNum > 0)
{
if (UserNum & 1) // mask all bits but bit no. 0
cnt++;
UserNum = UserNum >> 1; // shift bits to the right
}
printf("there are %d active bits\n", cnt);
}
There is still room for improvement though. Especially negative numbers won't work properly (I didn't test though, find out yourself).
There are more sophisticated methods for counting bits such as described here: How to count the number of set bits in a 32-bit integer?

how to iterate over a number to get every other digit

For a homework program we are asked to check if credit card numbers are valid.
While I am fairly sure about how I want to solve this problem I am stuck with iterating over a creditcard number and getting every second digit.
I already know that I need to use modulo and division and I do get the second to last number, but I am lost at how to iterate over the rest of the numbers.
In the code is the code I used to check that I did indeed get the second to last number, and after that some code I tried to use to iterate over the complete number. Hope somebody could show me in the right direction!
long number = 378282246310005;
int digit;
int cc_number;
cc_number = number % 10;
digit = cc_number / 10;
printf("%i\n", digit);
while (number > 0)
{
digit += number % 10;
number /= 10;
printf("%li", number);
}
printf("\n");
Before your while loop you reversed the last digit and the remaining number.
number % 10 is the last digit, number / 10 is the remaining number.
Adding to digit doesn't make sense if the variable is intended to contain a single digit. (You may need to add the digits for a validity check.)
Example code to extract all digits and their positions:
#include <stdio.h>
int main(void)
{
long number = 378282246310005;
int digit;
int position = 0;
printf("%li\n", number);
while (number > 0)
{
digit = number % 10;
number /= 10;
printf("(%i) %i ", position, digit);
position++;
}
printf("\n");
return 0;
}
This prints
378282246310005
(0) 5 (1) 0 (2) 0 (3) 0 (4) 1 (5) 3 (6) 6 (7) 4 (8) 2 (9) 2 (10) 8 (11) 2 (12) 8 (13) 7 (14) 3
To select every other digit you could check position % 2 or toggle a variable between 0 and 1 in every loop cycle.
Edit:
Explanation as requested in ron_g's comment: "Why's it printing out the digits in reverse?"
The loop separates the last digit from the remaining part of the number, so it prints the last digit first. Then it repeats the same with the remaining part as long as the remaining number is not 0.
The answer keeps the original implementation from the question which is based on storing the number as a long int. In this case it is easier to start with the last digit. When the number would be stored as a string it would be easier to start with the first digit.
/* number is initially the whole number or the remaining part */
while (number > 0)
{
/* remainder of division by 10 is the last digit */
digit = number % 10;
/* division by 10 is the remaining part after cutting off the last digit */
number /= 10;
printf("(%i) %i ", position, digit);
position++;
}

Why am I getting outputs of huge numbers with this program?

I am trying to make a program that allows the user to input a positive integer, and the program will output the sum of each digit added together. For example, if the user inputs 54, the program will output 9. For some reason, the program is outputting outrageously huge numbers. When 54 is the input, the output will read something like 5165451 or 2191235. I'm new to C programming, but I don't see a single thing wrong with this code..
//This program takes a positive integer
//from the user, and adds all the digits
//of the number together.
#include <stdio.h>
int main() {
system("clear");
int given, add, hold, i;
printf("Enter a positive integer (up to 10 digits): ");
scanf("%d", &given); //User input
for (i = 0; i < 10; i++) { //Loop to add digits
hold = (given % 10);
given = (given / 10);
add = (add + hold);
}
printf("Sum of the digits is %d\n", add); //Output
}
int given, add, hold, i;
You haven't initialized add, so it contains unspecified data, aka garbage. Using its value while it is unspecified is undefined behaviour.
Insert add = 0; before the loop to see if that helps.
I think the for loop is wrong
The loop will run 10 times whereas scanf will only take the input upto the limit of int data type i.e 32768.
You should make given a long data type.
and make the for loop as
for(;given!=0;)
{
hold = (given % 10);
given = (given / 10);
add = (add + hold);
}
and of course initialize add to zero.

Write a program that sums the sequence of integers, as well as the smallest in the sequence

Write a program that sums the sequence
of integers as well as the smallest in
the sequence. Assume that the first
integer read with scanf specifies the
number of values remaining to be
entered. For example the sequence
entered:
Input: 5 100 350 400 550 678
Output: The sum of the sequence of
integers is: 2078
Input: 5 40 67 9 13 98
Output: The smallest of the integers
entered is: 9
This is a daily problem I am working on but by looking at this, Isnt 5 the smallest integer? I have no idea how to write this program. Appreciate any help
First thing, the 5 is not considered part of the list, it's the count for the list. Hence it shouldn't be included in the calculations.
Since this is homework, here's the pseudo-code. Your job is to understand the pseudo-code first (run it through your head with sample inputs) then turn this into C code and try to get it compiling and running successfully (with those same sample inputs).
I would suggest the sample input of "2 7 3" (two items, those being 7 and 3) as a good start point since it's small and the sum will be 10, smallest 3.
If you've tried to do that for more than a day, then post your code into this question as an edit and we'll see what we can do to help you out.
get a number into quantity
set sum to zero
loop varying index from 1 to quantity
get a number into value
add value to sum
if index is 1
set smallest to value
else
if value is less than smallest
set smallest to value
endif
endif
endloop
output "The sum of the sequence of integers is: ", sum
output "The smallest of the integers entered is: ", smallest
Stack Overflow seems to be divided into three camps, those that will just give you the code, those that will tell you to push off and do your own homework and those, like me, who would rather see you educated - by the time you hit the workforce, I hope to be retired so you won't be competing with me :-).
And before anyone picks holes in my algorithm, this is for education. I've left at least one gotcha in it to help train the guy - there may be others and I will claim I put them there intentionally to test him :-).
Update:
Robert, after your (very good) attempt which I've already commented on, this is how I'd modify your code to do the task (hand yours in of course, not mine). You can hopefully see how my comments modify the code to reach this solution:
#include <stdio.h>
int main (int argCount, char *argVal[]) {
int i; // General purpose counter.
int smallNum; // Holds the smallest number.
int numSum; // Holds the sum of all numbers.
int currentNum; // Holds the current number.
int numCount; // Holds the count of numbers.
// Get count of numbers and make sure it's in range 1 through 50.
printf ("How many numbers will be entered (max 50)? ");
scanf ("%d", &numCount);
if ((numCount < 1) || (numCount > 50)) {
printf ("Invalid count of %d.\n", numCount);
return 1;
}
printf("\nEnter %d numbers then press enter after each entry:\n",
numCount);
// Set initial sum to zero, numbers will be added to this.
numSum = 0;
// Loop, getting and processing all numbers.
for (i = 0; i < numCount; i++) {
// Get the number.
printf("%2d> ", i+1);
scanf("%d", &currentNum);
// Add the number to sum.
numSum += currentNum;
// First number entered is always lowest.
if (i == 0) {
smallNum = currentNum;
} else {
// Replace if current is smaller.
if (currentNum < smallNum) {
smallNum = currentNum;
}
}
}
// Output results.
printf ("The sum of the numbers is: %d\n", numSum);
printf ("The smallest number is: %d\n", smallNum);
return 0;
}
And here is the output from your sample data:
pax> ./qq
How many numbers will be entered (max 50)? 5
Enter 5 numbers then press enter after each entry:
1> 100
2> 350
3> 400
4> 550
5> 678
The sum of the numbers is: 2078
The smallest number is: 100
pax> ./qq
How many numbers will be entered (max 50)? 5
Enter 5 numbers then press enter after each entry:
1> 40
2> 67
3> 9
4> 13
5> 98
The sum of the numbers is: 227
The smallest number is: 9
pax> ./qq
How many numbers will be entered (max 50)? 0
Invalid count of 0.
[fury]$ ./qq
How many numbers will be entered (max 50)? 51
Invalid count of 51.
By the way, make sure you always add comments to your code. Educators love that sort of stuff. So do developers that have to try to understand your code 10 years into the future.
Read:
Assume that the first integer read
with scanf specifies the number of
values remaining to be entered
so it's not part of the sequence...
for the rest, it's your homework (and C...)
No. 5 is the number of integers you have to read into the list.
Jeebus, I'm not doing your homework for you, but...
Have you stopped to scratch this out on paper and work out how it should work? Write some pseudo-code and then transcribe to real code. I'd have thought:
Read integer
Loop that many times
** Read more integers
** Add
** Find Smallest
IF you're in C look at INT_MAX - that will help out finding the smallest integer.
Since the list of integers is variable, I'd be tempted to use strtok to split the string up into individual strings (separate by space) and then atoi to convert each number and sum or find minimum on the fly.
-Adam
First you read the number of values (ie. 5), then create an array of int of 5 elements, read the rest of the input, split them and put them in the array (after converting them to integers).
Then do a loop on the array to get the sum of to find the smallest value.
Hope that helps
wasn[']t looking for you guys to do the work
Cool. People tend to take offense when you dump the problem text at them and the problem text is phrased in an imperative form ("do this! write that! etc.").
You may want to say something like "I'm stuck with a homework problem. Here's the problem: write a [...]. I don't understand why [...]."
#include <stdio.h>
main ()
{
int num1, num2, num3, num4, num5, num6, i;
int smallestnumber=0;
int sum=0;
int numbers[50];
int count;
num1 = 0;
num2 = 0;
num3 = 0;
num4 = 0;
num5 = 0;
num6 = 0;
printf("How many numbers will be entered (max 50)? ");
scanf("%d", &count);
printf("\nEnter %d numbers then press enter after each entry: \n", count);
for (i=0; i < count; i++) {
printf("%2d> ", i+1);
scanf("%d", &numbers[i]);
sum += numbers[i];
}
smallestnumber = numbers[0];
for (i=0; i < count; i++) {
if ( numbers[i] < smallestnumber)
{
smallestnumber = numbers[i];
}
}
printf("the sum of the numbers is: %d\n", sum);
printf("The smallest number is: %d", smallestnumber);
}

Resources