C programming exercise? - c

I'm reading a book on C programming and try to do the exercises:
Write a program that prints a horizontal histogram consisting of stars(*). One star for every number there can be in the interval 0 ... 70.
#include <stdio.h>
void draw_stars(int number_of_stars) {
int counter = 0;
for(counter = 0; counter < number_of_stars; counter++) {
printf("*");
}
printf("\n");
}
int main(void) {
int counter1, counter2, ones, tens, zero, one, two, three, four, five, six, seven, eight, nine = 0;
for(tens = 0; tens < 7; tens++) {
if(tens == 0)
zero = zero + 1;
if(tens == 1)
one = one + 10;
if(tens == 2)
two = two + 10;
if(tens == 3)
three = three + 10;
if(tens == 4)
four = four + 10;
if(tens == 5)
five = five + 10;
if(tens == 6)
six = six + 10;
if(tens == 7)
seven = seven + 10;
for(ones = 0; ones < 9; ones++) {
if(ones == 0)
zero++;
if(ones == 1)
one++;
if(ones == 2)
two++;
if(ones == 3)
three++;
if(ones == 4)
four++;
if(ones == 5)
five++;
if(ones == 6)
six++;
if(ones == 7)
seven++;
if(ones == 8)
eight++;
if(ones == 9)
nine++;
}
}
draw_stars(zero);
draw_stars(one);
draw_stars(two);
draw_stars(three);
draw_stars(four);
draw_stars(five);
draw_stars(six);
draw_stars(seven);
draw_stars(eight);
draw_stars(nine);
}
For some reason my program enters a infinite loop printing stars. But I can't find out why?
I haven't been able to come up with any other solution, but I still think it's ugly and bloated. How would a real C programmer solve this?
Edit:
After reading and understanding the chapter about arrays in the book, I was able to write a more clean version of the program. I'm posting it here as it might help other beginners understand the use of arrays. Writing an identical program in terms of output, but using different functionality of the language is a great learning experience.
#include <stdio.h>
#define TENS 7
void draw_stars(int stars) {
int star_counter = 0;
for (star_counter = 0; star_counter < stars; star_counter++)
printf("%c", '*');
}
int main(void) {
int number_array[10];
int tens_counter, ones_counter;
for (ones_counter = 0; ones_counter < 10; ones_counter++)
number_array[ones_counter] = 0;
for (tens_counter = 0; tens_counter < TENS; tens_counter++) {
if (tens_counter != 0)
number_array[tens_counter] += 10;
else
number_array[tens_counter] += 1;
for (ones_counter = 0; ones_counter < 10; ones_counter++)
number_array[ones_counter]++;
}
for (ones_counter = 0; ones_counter < 10; ones_counter++) {
draw_stars(number_array[ones_counter]);
printf("\n");
}
}

Initialize all variables:
int counter1=0, counter2=0, ones=0, tens=0, zero=0, one=0..
BTW, for better performance,
replace if with else if except the first one in the block. Why do you want to check all if conditions when you already know only one is true?
FYI, when a condition is true in Else if, all other ifs are skipped.

If you wanted to initialize all ints to zero, you should write:
int counter1=0, counter2=0, ...
Now only nine is init by 0, other variables contain rubbish - arbitrary values.

in main() you have to initialize all variable with zero like
int counter1=0,counter2=0 and so on
otherwise it take garbage value and perform operation with those values and then output will be like
********
*****************
*****************
*****************
*****************
*****************
*****************
*******
*******

Related

How can I correctly format these loops in C how my professor wants it?

For my lab project I have to
For each integer 0 < n <= 100, find all of the integers between one and n which divide n without a remainder.
I have worked out the code but I am unsure how to format it in the way he wants.
Format: number(# of factors): factors
Examples:
2:( 2) 1,2
3:( 2) 1,3
4:( 3) 1,2,4
What the current output looks like:
1: 1
2: 1
2: 2
3: 1
3: 3
4: 1
4: 2
4: 4
5: 1
5: 5
6: 1
6: 2
6: 3
6: 6
7: 1
7: 7
8: 1
8: 2
8: 4
8: 8
9: 1
9: 3
9: 9
10: 1
10: 2
10: 5
10: 10
#include <stdio.h>
int main() {
int ini[100], i, j, d, n = 0;
for (i = 1; i <= 100; i++){
n = n+1;
ini[i] = n;
for (d = 1; d <= n; d++){
if (ini[i] % d == 0)
printf("%d: %d\n", ini[i], d);
}
}
}
Aw, c'mon, let's have a little fun here. Everyone else is suggesting the "usual" way. But Back In The Day (tm) we didn't have memory to waste on things like keeping track of stuff. We just used the paper as our memory! :-)
I suggest looping over the values to be tested (1 - 100), then inside the first loop have another loop which counts from from 1 to n, printing the divisor values which give a remainder of zero. At the end of the loop I'd overprint the n value and then add in the number of factors found, then loop back for the next value.
In code this looks a lot like:
#include <stdio.h>
int main()
{
int n, d, i;
int factor_count;
for (n = 1 ; n <= 100 ; n += 1)
{
printf("%3d( ): ", n);
factor_count = 0;
for (d = 1 ; d <= n ; d += 1)
{
if (n % d == 0)
{
printf("%c%d", (factor_count > 0 ? ',' : ' '), d);
factor_count += 1;
}
}
printf("\r%3d(%3d)\n", n, factor_count);
}
}
This code takes advantage of the fact that \r returns the print carriage (or the cursor on video terminals) to the left margin without advancing the roller (or the cursor - really, the cursor is far too busy and needs a rest! :-) to the next line, in order to avoid having to keep an array to store the factors in. It would be a lot of fun to watch run on an old ASR-33 Teletype - anybody got one to test with?
:-)
Before adapting your solution to generate the desired output, it would help to see the wood for the trees by removing the redundancy from your current solution:
In this solution, n == i is invariant so n is redundant, and the array ini[] is entirely redundant, because you only ever read/write ini[i] and ini[i] == i is invariant, so all instances of n and ini[i] can be replaced with i. j is just unused. Then neither i nor d are used before or after the loops they control, so can be localised by declaring them in the loop thus minimising the scope (just good practice).
Then your code reduces to the following equivalent:
int main() {
for( int i = 1; i <= 100; i++){
for( int d = 1; d <= i; d++){
if (i % d == 0)
printf("%d: %d\n", i, d);
}
}
return 0 ;
}
Now to obtain the required output, you don't know the number of factors until you have determined the list of factors, so the solution is to generate the list first while counting, then print the output.
That can be done in a second loop printing an array of stored factors, or even a second loop that recalculates the factors a second time - but those answers have already been given. Instead you could directly generate the list string as you go, then append it to the number/count output:
#include <stdio.h>
int main()
{
for( int i = 1; i <= 100; i++ )
{
char factor_list_out[80] = "" ;
int factor_count = 0 ;
int factor_out_index = 0 ;
for( int d = 1; d <= i; d++)
{
if( i % d == 0)
{
factor_count++ ;
factor_out_index += sprintf( &factor_list_out[factor_out_index], "%d,", d ) ;
}
}
factor_list_out[factor_out_index - 1] = 0 ; // remove trailing comma
printf( "%3d:(%2d) %s\n", i, factor_count, factor_list_out ) ;
}
return 0 ;
}
Output:
1:( 1) 1
2:( 2) 1,2
3:( 2) 1,3
4:( 3) 1,2,4
5:( 2) 1,5
6:( 4) 1,2,3,6
7:( 2) 1,7
8:( 4) 1,2,4,8
9:( 3) 1,3,9
10:( 4) 1,2,5,10
11:( 2) 1,11
12:( 6) 1,2,3,4,6,12
13:( 2) 1,13
14:( 4) 1,2,7,14
15:( 4) 1,3,5,15
16:( 5) 1,2,4,8,16
17:( 2) 1,17
18:( 6) 1,2,3,6,9,18
19:( 2) 1,19
20:( 6) 1,2,4,5,10,20
21:( 4) 1,3,7,21
22:( 4) 1,2,11,22
23:( 2) 1,23
24:( 8) 1,2,3,4,6,8,12,24
25:( 3) 1,5,25
26:( 4) 1,2,13,26
27:( 4) 1,3,9,27
28:( 6) 1,2,4,7,14,28
29:( 2) 1,29
30:( 8) 1,2,3,5,6,10,15,30
31:( 2) 1,31
32:( 6) 1,2,4,8,16,32
33:( 4) 1,3,11,33
34:( 4) 1,2,17,34
35:( 4) 1,5,7,35
36:( 9) 1,2,3,4,6,9,12,18,36
37:( 2) 1,37
38:( 4) 1,2,19,38
39:( 4) 1,3,13,39
40:( 8) 1,2,4,5,8,10,20,40
41:( 2) 1,41
42:( 8) 1,2,3,6,7,14,21,42
43:( 2) 1,43
44:( 6) 1,2,4,11,22,44
45:( 6) 1,3,5,9,15,45
46:( 4) 1,2,23,46
47:( 2) 1,47
48:(10) 1,2,3,4,6,8,12,16,24,48
49:( 3) 1,7,49
50:( 6) 1,2,5,10,25,50
51:( 4) 1,3,17,51
52:( 6) 1,2,4,13,26,52
53:( 2) 1,53
54:( 8) 1,2,3,6,9,18,27,54
55:( 4) 1,5,11,55
56:( 8) 1,2,4,7,8,14,28,56
57:( 4) 1,3,19,57
58:( 4) 1,2,29,58
59:( 2) 1,59
60:(12) 1,2,3,4,5,6,10,12,15,20,30,60
61:( 2) 1,61
62:( 4) 1,2,31,62
63:( 6) 1,3,7,9,21,63
64:( 7) 1,2,4,8,16,32,64
65:( 4) 1,5,13,65
66:( 8) 1,2,3,6,11,22,33,66
67:( 2) 1,67
68:( 6) 1,2,4,17,34,68
69:( 4) 1,3,23,69
70:( 8) 1,2,5,7,10,14,35,70
71:( 2) 1,71
72:(12) 1,2,3,4,6,8,9,12,18,24,36,72
73:( 2) 1,73
74:( 4) 1,2,37,74
75:( 6) 1,3,5,15,25,75
76:( 6) 1,2,4,19,38,76
77:( 4) 1,7,11,77
78:( 8) 1,2,3,6,13,26,39,78
79:( 2) 1,79
80:(10) 1,2,4,5,8,10,16,20,40,80
81:( 5) 1,3,9,27,81
82:( 4) 1,2,41,82
83:( 2) 1,83
84:(12) 1,2,3,4,6,7,12,14,21,28,42,84
85:( 4) 1,5,17,85
86:( 4) 1,2,43,86
87:( 4) 1,3,29,87
88:( 8) 1,2,4,8,11,22,44,88
89:( 2) 1,89
90:(12) 1,2,3,5,6,9,10,15,18,30,45,90
91:( 4) 1,7,13,91
92:( 6) 1,2,4,23,46,92
93:( 4) 1,3,31,93
94:( 4) 1,2,47,94
95:( 4) 1,5,19,95
96:(12) 1,2,3,4,6,8,12,16,24,32,48,96
97:( 2) 1,97
98:( 6) 1,2,7,14,49,98
99:( 6) 1,3,9,11,33,99
100:( 9) 1,2,4,5,10,20,25,50,100
Since the requirement are to indicate the number of factors before listing them, you will need two passed - one for counting the factors, and one for printing the factors.
Also note that this implementation does not take advantage of the ini vector, which (since for every element ini[i] = i, so there is no need for many of the declared variables.
#include <stdio.h>
int main() {
for (int i = 1; i <= 100; i++){
// First Pass: Counting
int count = 0;
for (int d=1 ; d<=i ; d++) {
if ( i%d == 0 ) count++ ;
} ;
printf("%d: (%d)", i, count) ;
// Second pass: Printing
for (int d=1 ; d<=i ; d++) {
if ( i%d == 0 ) printf(" %d", d) ; ;
} ;
printf("\n") ;
}
}
Put all the divisors in an array. Then print the elements of the array in the format required. You can also count the number of divisors as you're finding them.
#include <stdio.h>
int main() {
for (int i = 1; i <= 100; i++){
int divisors[100];
int counter = 0;
for (int d = 1; d <= i; d++){
if (i % d == 0) {
divisors[counter] = d;
counter++;
}
}
printf("%d (%d): ", i, counter);
for (int j = 0; j < counter; j++) {
printf("%s%d", (j == 0 ? "" : ","), divisors[j]);
}
printf("\n");
}
}

Trying to find prime numbers

I'm a first year student in a programming university and my first assignment is to find the sum of prime numbers between 3990000000 and 4010000000. The problem is everything I do, when I run the program it says the sum is 0 with a return value of 25. I've been trying to debug this code but with no luck, could someone help me?
My code is:
#include <stdio.h>
#define STARTNUMBER 3990000000
#define ENDNUMBER 4010000000
int main() {
unsigned int num;
int j, c, flag, sum = 0;
flag = 1;
c = 5;
j = 7;
for (num = STARTNUMBER; num <= ENDNUMBER; num++) {
if (num % 2 == 0) { /*if number mod 2 equals zero go to next number*/
flag = 0;
break;
}
if (num % 3 == 0) { /*if number mod 3 equals zero go to next number*/
flag = 0;
break;
} else
/*check if number is prime with the sequences 5+6+6...<=sqrt(number) and 7+6+6..<=sqrt(number)*/
while (c * c <= num && j * j <= num && flag == 1) {
if (num % c == 0 || num % j == 0) {
flag = 0;
break;
}
c += 6;
j += 6;
}
if (flag == 1)
sum++;
}
printf("There are %d prime numbers", sum);
}
You are asking for the sum of the prime number, even if your code is just printing how many they are. Assuming you've misunderstood the exercise, I try to show a possible problem of your original question, glimpsing a possible trick in your exercise since the interval is very close to 232.
Assuming also you are on a 64-bit environment, if there are at least two prime numbers in that inteval, the sum is going to be greater than INT_MAX (231 - 1). An int is not sufficient to store a value, and also unsigned int is not sufficient since UINT_MAX is 232 - 1.
Finally, assuming you've solved your problems with the break statements already described in the comments, try to store your sum variable into a unsigned long int, and replace the last part of the loop with
if (flag==1)
sum += num;

'if' statement in C not executing even though conditions are met

I'm a first time programmer trying to complete a simple command line program as part of the first assignment for an online course I am taking, but I seem to have hit a roadblock that I can't figure out with GDB or my own research.
After hours of rewrites, and hours of debugging, I finally got the code below to compile. The program is supposed to take a credit card number as an input, and then check whether it's valid per the specifications of the assignment. I used a test number from here: PayPal Test Credit Cards
The odd thing is, when I enter an AMEX card number, it correctly produces the text "AMEX", but when I try a Visa or a Master Card, it prints "INVALID".
In GDB I broke at the Verify function and it seems to incorrectly skip these two if/else if statements without proceeding to the Checksum function even though conditions appear to be met.
if (firstDigit == 4 && totalDigits == (13 | 16) && Checksum(cardNumber, totalDigits) == 0) // checks for a valid Visa.
...
else if (firstDigit == 5 && secondDigit == (1 | 2 | 3 | 4 | 5) && totalDigits == 16 && Checksum(cardNumber, totalDigits) == 0) // checks for a valid Mastercard.
...
The AMEX line of code that correctly executes is:
else if (firstDigit == 3 && secondDigit == (4 | 7) && totalDigits == 15 && Checksum(cardNumber, totalDigits) == 0) // checks for a valid American Express.
The arguments for all three lines seem to be formatted exactly the same. That is far as I could get in GDB though. I would print totalDigits, firstDigit, and secondDigit in GDB right before stepping through the above two non-executing lines and everything looked correct. So I'm stumped, why is the AMEX line executing, but not the others?
Thanks in advance everyone. This is the first program after hello.c that I've tried to write, so I am open to absolutely any criticism or suggestions if it looks like I'm doing something weird/wrong.
Full code:
checker.c
#include <stdio.h>
#include <stdlib.h>
int MAX = 16;
int* DigitSort(unsigned long long x, int* array);
int Verify(int* array);
int main (void)
{
int* output = malloc (sizeof(int) * (MAX + 2)); // creates a blank array for the individual digits of the card number.
unsigned long long userInput = 0;
do
{
printf("Please enter a credit card number:\n");
scanf("%lld", &userInput);
}
while (userInput <= 0); // checks to make sure the user entered a number.
switch(Verify(DigitSort(userInput, output))) // sorts the user's input into individual digits and verifies the card type and validity.
{
case 1 :
printf("VISA\n");
break;
case 2 :
printf("MASTERCARD\n");
break;
case 3 :
printf("AMEX\n");
break;
case 0 :
printf("INVALID\n");
break;
default :
printf("INVALID\n");
}
free(output);
return 0;
}
int Verify(int* array) // verifies whether or not a card number is valid. Must pass the function a sorted array of individual digits.
{
int* cardNumber = array;
int firstDigit = cardNumber[0];
int secondDigit = cardNumber[1];
int totalDigits = 0;
int Checksum(int* cardNumber, int totalDigits);
int i = 0;
while (firstDigit >= 1 && cardNumber[i] >= 0) // this step counts the number of digits in the array.
{
totalDigits = totalDigits + 1;
i++;
}
if (firstDigit == 4 && totalDigits == (13 | 16) && Checksum(cardNumber, totalDigits) == 0) // checks for a valid Visa.
{
return 1;
}
else if (firstDigit == 5 && secondDigit == (1 | 2 | 3 | 4 | 5) && totalDigits == 16 && Checksum(cardNumber, totalDigits) == 0) // checks for a valid Mastercard.
{
return 2;
}
else if (firstDigit == 3 && secondDigit == (4 | 7) && totalDigits == 15 && Checksum(cardNumber, totalDigits) == 0) // checks for a valid American Express.
{
return 3;
}
else // if the card number doesn't match any of the above conditions or fails the checksum, an 'I' for Invalid is returned.
{
return 0;
}
}
int* DigitSort(unsigned long long x, int* array) // takes a long long as input and sorts it into individual digits
{
int* arrayReversed = malloc (sizeof(int) * (MAX + 2)); // creates a new array to hold the reversed order of digits.
int i = 0;
arrayReversed[0] = 0;
if (i < (MAX - 1) && x >= 10)
{
do
{
arrayReversed[i] = x % 10;
x = x / 10;
i++;
}
while (i < (MAX -1) && x >= 10);
}
if (i < MAX && x >= 1 && x <= 9)
{
arrayReversed[i] = (int) x;
x = (x - x);
}
if (x == 0)
{
int j = 0;
do
{
array[j] = arrayReversed[i]; // sorts the digits from the reversed array and places them into the sorted array.
j++;
i--;
}
while (j < MAX && i >= 0);
array[j] = -1;
}
free(arrayReversed);
return array;
}
int Checksum(int* cardNumber, int totalDigits)
{
int sum1 = 0;
int sum2 = 0;
int i = (totalDigits - 2);
int j = (totalDigits - 1);
while (i >= 0)
{
sum1 = ((cardNumber[i] * 2)%10) + ((cardNumber[i] * 2)/10) + sum1;
i -= 2;
}
while (j >= 0)
{
sum2 = (cardNumber[j] + sum2);
j -= 2;
}
if (((sum1 + sum2) % 10) == 0)
{
return 0;
}
else
{
return 1;
}
}
Your first problem is here:
if (firstDigit == 4 && totalDigits == (13 | 16) && ...
You need to write:
if (firstDigit == 4 && (totalDigits == 13 || totalDigits == 16) && ...
Your first check is looking for 0x1D == 29 as the number of digits (because, as paisanco points out in a comment, the | operator is the bitwise OR operator), and no credit card needs 29 digits (yet, and not for a long time to come). Note the extra parentheses for clarity and accuracy. Don't mess around risking removing them — the code won't work properly again. And in general, be explicit if your condition has both && and || operators and use parentheses to group terms explicitly.
You have similar problems elsewhere. As it happens, (4 | 7) is the same value as 7, so the condition works when the second digit is 7 (but not when it is 4). But it doesn't mean what you intended it to mean.
Computer languages don't work the same as human languages. Get used to writing out the condition somewhat more verbosely. Some other languages provide shorthands for these conditions; C is not such a language.

Array Iteration for a program [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have a project yet my teacher hasn't taught us about arrays. We need to output =<> signs corresponding to the comparison of one number to another. IE the main number is 1234 and I put in 2315, the output would be <<<> where the signs do not go in the order of the numbers but by this order =, <, >.
I have an idea and that to use an array then to use some code that would read out the whole array and apply rules to it, however I do not know how to implement this. I have been googling for awhile now and nothing I found really helps.
Just to let you know the program has way more steps than just this, all of which I have already completed, I just can't figure out this part. I do not want just the answer, I just want someone to point me in the right direction.
Thanks
EDIT:: The example 1234 and 2315 are bad examples. To give a more definitive idea without giving away too much of the problem so I have work to do is listing num1 and num2 (corresponding to 1234 and 2315) from least to greatest or greatest to least and compare that way. So another example would be 4751 is the main number and I put in 1294. The output would be ==<>. Thanks for the help guys so far. I am learning a lot.
EDIT2:: Thanks guys for the help. I learned a lot. I don't want any more submissions at least until I can upload my code.
Taking you at your word that you've already successfully completed most of your assignment, and by giving you code that you'll have to work through and understand to figure it out and adapt it to your needs, this will do what you want. The fact that you don't have to output the signs in the same order as the numbers themselves is what makes this easier.
#include <stdio.h>
int main(void) {
int num1 = 1234;
int num2 = 2315;
int lt = 0, gt = 0, eq = 0;
while ( num1 > 0 && num2 > 0 ) {
int op1 = num1 % 10;
int op2 = num2 % 10;
if ( op1 < op2 ) {
++lt;
} else if ( op1 > op2 ) {
++gt;
} else {
++eq;
}
num1 /= 10;
num2 /= 10;
}
for ( int i = 0; i < eq; ++i ) {
putchar('=');
}
for ( int i = 0; i < lt; ++i ) {
putchar('<');
}
for ( int i = 0; i < gt; ++i ) {
putchar('>');
}
putchar('\n');
return 0;
}
and outputs:
paul#MacBook:~/Documents/src/scratch$ ./eq
<<<>
paul#MacBook:~/Documents/src/scratch$
This code lets you get the nth digits you can compare and make a count of each symbol you need to return
char nthdigit(int x, int n)
{
while (n--) {
x /= 10;
}
return (x % 10) + '0';
}
And this is how you get the length of a number, check this post
As promised here is the rest of my code. It fixes the issue pointed out in the question but I have another issue. It is probably pretty noticeable but I wanted to post my code so I don't forget again.
#include<stdio.h>//standard inputs and outputs
#include<stdlib.h>//for compare, qsort, srand, and rand function
#include<time.h>//for random numbers at different times
#include<unistd.h>//for fun at the end
int main(void){
int guess, gdig1, gdig2, gdig3, gdig4, random, rdig1, rdig2, rdig3, rdig4;//variables for main
int lt, gt, eq, i, q, temp, holder;//this is for the hints
int g[3],r[3];
printf("Give the computer a few seconds to come up with a super secret passcode.\n");
do{//figuring out a random code
unsigned int iseed = (unsigned int)time(NULL);
srand (iseed);//using an unassigned integer
random = rand()%9000+1000;//generating a random number but limiting it
rdig4 = random%10;
rdig3 = (random/10)%10;
rdig2 = (random/100)%10;
rdig1 = (random/1000)%10;//figuring out the individual digits of the code
} while ((rdig1 == rdig2)||(rdig1 == rdig3)||(rdig1 == rdig4)||(rdig2 == rdig3)||(rdig2 == rdig4)||(rdig3 == rdig4)||(rdig1 == 0)||(rdig2 == 0)||(rdig3 == 0)||(rdig4 == 0));
//^^ some crazy boolean expression making sure the random integer doesnt have any of the same digits.
printf("\nThe actual passcode is:%d.\n",random);//testing in beginning comment out ********
do{
do{
printf("\nEnter in your guess for the passcode: ");
scanf("%d",&guess);//inputting and reading the guessed code
// printf("You entered:%d\n",guess);//just to check comment out at end**
gdig4 = guess%10;
gdig3 = (guess/10)%10;
gdig2 = (guess/100)%10;
gdig1 = (guess/1000)%10;//figuring out the individual digits of the guess code using modulus operator
if (guess > 9999){//the starting loop statement to make sure number is valid. this one is if it is greater than 4 digits
printf("\nPlease use a four digit number for the passcode.\n");
}
else if (guess < 1000){//this one is if it is less than 4 digits
printf("\nPlease use a four digit number for the passcode.\n");
gdig1 = 1;
gdig2 = 1;//used so the computer still loops
gdig3 = 1;
gdig4 = 1;
}
if ((gdig1 == 0) || (gdig2 == 0) || (gdig3 == 0) || (gdig4 == 0)){
break;
}
if ((rdig1 == gdig1) && (rdig2 == gdig2) && (rdig3 == gdig3) && (rdig4 == gdig4)){//to skip this codeblock and move onto next
break;
}
if (guess > 9999){
break;
}
if (guess < 1000){
break;
}
printf("\n%d %d %d %d\n",rdig1,rdig2,rdig3,rdig4); //used to testing comment out at end
printf("\n%d %d %d %d\n",gdig1,gdig2,gdig3,gdig4);
while (guess > 0){
g[i++] = guess % 10;
guess /=10;
}
do{//took a long long LONG time to get
for(i = 0; i<3;i++){
if(g[i] > g[i+1]){
holder = g[i+1];
g[i]=g[i+1];
g[i+1] = holder;
}
}
}while (i == 1);
for(i = 0;i<4;i++){
printf("%d",g[i]);
}
while (random > 0){
r[i++] = random % 10;
random /=10;
}
do{//took a long long LONG time to get
for(i = 0; i<3;i++){
if(r[i] > r[i+1]){
temp = r[i+1];
r[i]=r[i+1];
r[i+1] = temp;
}
}
}while (i == 1);
for(i = 0;i<4;i++){
printf("%d",r[i]);
}
/* for(digit=0;digit<4;digit++){
for(tmp=guess;tmp>0;tmp/=10){
if(tmp%10==digit){
printf("%d",digit);
g[i++]=digit;
}
}
}
printf("\n");
for(i=0;i<4;i++){
printf("%d",g[i]);
}//just to check
//this is for sorting the random
for(digit=0;digit<4;digit++){
for(tmp=random;tmp>0;tmp/=10){
if(tmp%10==digit){
printf("%d",digit);
r[i++]=digit;
}
}
}
for(i=0;i<4;i++){
printf("%d",r[i]);
}//just to check
*/
//this is for hints
rdig1=r[0];//redefining the random and guess digits so it is easier later
rdig2=r[1];
rdig3=r[2];
rdig4=r[3];
gdig1=g[0];
gdig2=g[1];
gdig3=g[2];
gdig4=g[3];
q = 0;
eq = 0;
lt = 0;
gt = 0;
if (random > 0){//loop that always holds true
if (gdig1 == rdig1){
eq++;
}else if (gdig1 < rdig1){
lt++;
}else if (gdig1 > rdig1){
gt++;
}
if (gdig2 == rdig2){
eq++;
}else if (gdig2 < rdig2){
lt++;
}else if (gdig2 > rdig2){
gt++;
}
if (gdig3 == rdig3){
eq++;
}else if (gdig3 < rdig3){
lt++;
}else if (gdig3 > rdig3){
gt++;
}
if (gdig4 == rdig4){
eq++;
}else if (gdig4 < rdig4){
lt++;
}else if (gdig4 > rdig4){
gt++;
}
}
for (q = 0; q < eq; q++){//counting step for the = <> no problems here^^
putchar('=');
}
for (q = 0; q < lt; q++){
putchar('<');
}
for (q = 0; q < gt; q++){
putchar('>');
}
//everything below is correct do not mess with *******************************************************************************************
} while (gdig1 > 0);//to loop inputs until they input correctly
if ((gdig1 == 0) || (gdig2 == 0) || (gdig3 == 0) || (gdig4 == 0)){//a nested if statement to check each digit if it is a 0
printf("\nYou have entered the Super Secret Code!!!!!\nThe actual passcode is:%d.\n",random);
break;
}
if ((rdig1 == gdig1) && (rdig2 == gdig2) && (rdig3 == gdig3) && (rdig4 == gdig4)){//to skip this codeblock and move onto next
break;
}
} while (((rdig1 != gdig1) && (rdig2 != gdig2) && (rdig3 != gdig3) && (rdig4 != gdig4)));//to loop inputs until they got it
//everything below is correct do not mess with *******************************************************************************************
if ((rdig1 == gdig1) && (rdig2 == gdig2) && (rdig3 == gdig3) && (rdig4 == gdig4)){
printf("\nCorrect Code inputted.");
sleep(1);
printf("\nImplementing unlocking procedures...\n");
for (i=0;i<=4;i++){//for fun cause why not. if you spend hours on code might as well have some fun :)
int p =25*i ;
printf("%d%% complete................\n",p);
sleep(1);
}
printf("Stand back!!! The vault is now opening.\n");
}
return 0;
}

Extracting individual digits from a long in C

I'm doing a homework assignment for my course in C (first programming course).
Part of the assignment is to write code so that a user inputs a number up to 9 digits long, and the program needs to determine whether this number is "increasing"/"truly increasing"/"decreasing"/"truly decreasing"/"increasing and decreasing"/"truly decreasing and truly increasing"/"not decreasing and not increasing". (7 options in total)
Since this is our first assignment we're not allowed to use anything besides what was taught in class:
do-while, for, while loops, else-if, if,
break,continue
scanf, printf ,modulo, and the basic operators
(We can't use any library besides for stdio.h)
That's it. I can't use arrays or getchar or any of that stuff. The only function I can use to receive input from the user is scanf.
So far I've already written the algorithm with a flowchart and everything, but I need to separate the user's input into it's distinct digits.
For example, if the user inputs "1234..." i want to save 1 in a, 2 in b, and so on, and then make comparisons between all the digits to determine for example whether they are all equal (increasing and decreasing) or whether a > b >c ... (decreasing) and so on.
I know how to separate each digit by using the % and / operator, but I can't figure out how to "save" these values in a variable that I can later use for the comparisons.
This is what I have so far:
printf("Enter a positive number : ");
do {
scanf ("%ld", &number);
if (number < 0) {
printf ("invalid input...enter a positive integer: ");
continue;
}
else break;
} while (1);
while (number < 0) {
a = number % 10;
number = number - a;
number = number / 10;
b = a;
}
Why not scan them as characters (string)? Then you can access them via an array offset, by subtracting the offset of 48 from the ASCII character code. You can verify that the character is a digit using isdigit from ctype.h.
EDIT
Because of the incredibly absent-minded limitations that your professor put in place:
#include <stdio.h>
int main()
{
int number;
printf("Enter a positive number: ");
do
{
scanf ("%ld", &number);
if (number < 0)
{
printf ("invalid input...enter a positive integer: ");
continue;
}
else break;
} while (1);
int a = -1;
int b = -1;
int c = -1;
int d = -1;
int e = -1;
int f = -1;
int g = -1;
int h = -1;
int i = -1;
while (number > 0)
{
if (a < 0) a = number % 10;
else if (b < 0) b = number % 10;
else if (c < 0) c = number % 10;
else if (d < 0) d = number % 10;
else if (e < 0) e = number % 10;
else if (f < 0) f = number % 10;
else if (g < 0) g = number % 10;
else if (h < 0) h = number % 10;
else if (i < 0) i = number % 10;
number /= 10;
}
/* Printing for verification. */
printf("%i", a);
printf("%i", b);
printf("%i", c);
printf("%i", d);
printf("%i", e);
printf("%i", f);
printf("%i", g);
printf("%i", h);
printf("%i", i);
return 0;
}
The valid numbers at the end will be positive, so those are the ones you validate to meet your different conditions.
Since you only need to compare consecutive digits, there is an elegant way to do this without arrays:
int decreasing = 2;
int increasing = 2;
while(number > 9)
{
int a = number % 10;
int b = (number / 10) % 10;
if(a == b)
{
decreasing = min(1, decreasing);
increasing = min(1, increasing);
}
else if(a > b)
decreasing = 0;
else if(a < b)
increasing = 0;
number /= 10;
}
Here, we walk through the number (by dividing by 10) until only one digit remains. We store info about the number up to this point in decreasing and increasing - a 2 means truly increasing/decreasing, a 1 means increasing/decreasing, and a 0 means not increasing/decreasing.
At each step, a is the ones digit and b is the tens. Then, we change increasing and decreasing based on a comparison between a and b.
At the end, it should be easy to turn the values of increasing and decreasing into the final answer you want.
Note: The function min returns the smaller of its 2 arguments. You should be able to write your own, or replace those lines with if statements or conditionals.
It's stupid to ask you to do loops without arrays --- but that's your teacher's fault, not yours.
That being said, I would do something like this:
char c;
while (1) {
scanf("%c", &c);
if (c == '\n') /* encountered newline (end of input) */
break;
if (c < '0' || c > '9')
break; /* do something to handle bad characters? */
c -= '0';
/*
* At this point you've got 0 <= c < 9. This is
* where you do your homework :)
*/
}
The trick here is that when you type numbers into a program, you send the buffer all at once, not one character at a time. That means the first scanf will block until the entire string (i.e. "123823" or whatever) arrives all at once, along with the newline character ( '\n' ). Then this loop parses that string at its leisure.
Edit For testing the increasing/decreasing-ness of the digits, you may think you need to store the entire string, but that's not true. Just define some additional variables to remember the important information, such as:
int largest_digit_ive_seen, smallest_digit_ive_seen, strict_increasing_thus_far;
etc. etc.
Let us suppose you have this number 23654
23654 % 10000 = 2 and 3654
3654 % 1000 = 3 and 654
654 % 100 = 6 and 54
54 % 10 = 5 and 4
4
This way you can get all the digits. Of course, you have to know if the number is greater than 10000, 1000, 100 or 10, in order to know the first divisor.
Play with sizeof to get the size of the integer, in order to avoid a huge if...else statement
EDIT:
Let us see
if (number>0) {
// Well, whe have the first and only digit
} else if (number>10) {
int first_digit = number/10;
int second_digit = number % 10;
} else if (number>100) {
int first_digit = number/100;
int second_digit = (number % 100)/10;
int third_digit = (number % 100) % 10;
} ...
and so on, I suppose
// u_i is the user input, My homework asked me to extract a long long, however, this should also be effective for a long.
int digits = 0;
long long d_base = 1;
int d_arr[20];
while (u_i / d_base > 0)
{
d_arr[digits] = (u_i - u_i / (d_base * 10) * (d_base * 10)) / d_base;
u_i -= d_arr[digits] * d_base;
d_base *= 10;
digits++;
}
EDIT: the extracted individual digit now lives in the int array d_arr. I'm not good at C, so I think the array declaration can be optimized.
Here's a working example in plain C :
#include <stdio.h>
unsigned long alePow (unsigned long int x, unsigned long int y);
int main( int argc, const char* argv[] )
{
int enter_num, temp_num, sum = 0;
int divisor, digit, count = 0;
printf("Please enter number\n");
scanf("%d", &enter_num);
temp_num = enter_num;
// Counting the number of digits in the entered integer
while (temp_num != 0)
{
temp_num = temp_num/10;
count++;
}
temp_num = enter_num;
// Extracting the digits
printf("Individual digits in the entered number are ");
do
{
divisor = (int)(alePow(10.0, --count));
digit = temp_num / divisor;
temp_num = temp_num % divisor;
printf(" %d",digit);
sum = sum + digit;
}
while(count != 0);
printf("\nSum of the digits is = %d\n",sum);
return 0;
}
unsigned long alePow(unsigned long int x, unsigned long int y) {
if (x==0) { return 0; }
if (y==0||x==1) { return 1; }
if (y==1) { return x; }
return alePow(x*x, y/2) * ((y%2==0) ? 1 : x);
}
I would suggest loop-unrolling.
int a=-1, b=-1, c=-1, d=-1, e=1, f=-1, g=-1, h=-1, i=-1; // for holding 9 digits
int count = 0; //for number of digits in the given number
if(number>0) {
i=number%10;
number/=10;
count++;
}
if(number>0) {
h=number%10;
number/=10;
count++;
}
if(number>0) {
g=number%10;
number/=10;
count++;
}
....
....
/* All the way down to the storing variable a */
Now, you know the number of digits (variable count) and they are stored in which of the variables. Now you have all digits and you can check their "decreasing", "increasing" etc with lots of if's !
I can't really think of a better soltion given all your conditions.

Resources