C switch case REALY weird result - c

So ive tried to use the rand() command in C, in this case to generate random number between 1 to 6. that part went perfectly, but then i tried to use the switch method to count how many times each number apeared, and the results were... weird.
heres the code:
include
int main() {
int num;
int number;
int one;
int two;
int three;
int four;
int five;
int six;
printf("enter a number: ");
scanf("%d", &num);
for(int n = 1; n < num + 1; n++){
number = (rand() % 6) +1;
printf("%d", number);
switch(number){
case 1:
one++;
break;
case 2:
two++;
break;
case 3:
three++;
break;
case 4:
four++;
break;
case 5:
five++;
break;
case 6:
six++;
break;
}
}
printf("number of ones: %d\n"
"number of twos: %d\n"
"number of threes: %d\n"
"number of fours: %d\n"
"number of fives: %d\n"
"number of sixes: %d\n",
one, two, three, four, five, six);
return 0;
}
when i ran it and wrote in 10, 10 random numbers realy apeared, but these are the results:
number of ones: 1978168284
number of twos: -2
number of threes: 1307605979
number of fours: 1978192464
number of fives: 6422480
number of sixes: 6422299
I looked at the code a few times and I just have no idea how that happend... if anyone has an edvice of fixisg that, please tell me (:

Variables with automatic storage duration are not initialised to zero.
You need to do that yourself.
The behaviour of reading an uninitialised variable is undefined in C: you must initialise them.

Related

When exactly do we use "if else-if" and "case break" statements in C language? I wrote 2 codes for a problem, but the difference I don't understand

I hope the problem question is understood based on my code,
Here is the code I've written using case-break statements:
#include<stdio.h>
int main()
{
int x;
printf("Pick an integer from 1, 2 and 3: ");
scanf("%d", &x);
switch(x)
{
case 1:
printf("1 is a unique number.\n", x);
break;
case 2:
printf("2 is the smallest and the only even prime number.\n", x);
break;
case 3:
printf("3 is the first odd prime number.\n", x);
break;
default:
printf("I haven't even asked you to enter %d\n", x);
}
return 0;
}
This is the code I have written using if else-if statements:
#include<stdio.h>
int main()
{
int input;
printf("Enter any one of 1, 2, and 3 ");
scanf("%d", &input);
if(input==1)
printf("%d is a unique number", input);
else if(input==2)
printf("%d is the only even prime number", input);
else if(input==3)
printf("%d is the smallest odd prime number", input);
else
printf("I did not even ask you to enter %d", input);
return 0;
}
Thank You
If you are checking for different values of the same variable, then it's up to you whether to use switch() or else if()
If you are checking for the value of 2 or more variables (and possibly even their combinations) then you'd better use else if()

How to use a do-while loop WITHIN A SWITCH-CASE STRUCTURE in C/C++ to restart a program from the beginning?

In this multiplication game, I have to generate two random numbers and multiply them. The user has to guess the right product. After the game, the user has a choice to either restart the game or quit (along with other choices to display/reset stats). I am required to use a switch-case structure for the choices the user decides on after the game. I also know I have to use a do-while loop for restarting/quitting the game but I don't know what to put in place of the bolded comments (after cases 1 and 3). Thanks in advance for taking the time to read. Any help is much appreciated!
#include <stdio.h>
#include <stlib.h>
#include <time.h>
#include <math.h>
int main () {
//Start do-while loop
do {
//Display rules of the game to the user.
printf("Two random numbers (1-12) will be generated and displayed. The objective of this game is to correctly guess the product of the numbers.");
//Generate two random integers between 1 and 12 and display them to the user
int i;
int n1;
int n2;
srand(time(NULL));
for(i = 1; i<=12;i++)
{
n1 = 1 + rand() % 12;
n2 = 1 + rand() % 12;
printf("The two random numbers generated are : %d and %d\n", n1,n2);
}
//Prompt the user to enter the product of the two numbers
int a;
printf("Enter the product of the two numbers: ");
scanf("%d", &a);
//Determine and display if or not the answer was right
int countCorrect;
int countIncorrect;
int product = n1*n2;
if (a == product)
{
printf("Correct response!");
countCorrect++;
}
else
{
printf("Incorrect response, the correct answer is: %d\n", product);
countIncorrect++;
}
//Start switch-case structure for post-game options
int choice;
switch (choice)
{
case 1:
printf("You have chosen to play again");
**//How do I restart the program so the user can play again?**
break;
case 2:
printf("You have chosen to see statistics");
printf("The number of correct answers are: %d\n", countCorrect);
printf("The number of incorrect answers are: %d\n", countIncorrect);
break;
case 3:
printf("You have chosen to reset statistics");
countCorrect = 0;
countIncorrect = 0;
break;
case 4:
printf("You have chosen to quit");
**//How do I quit the program?**
break;
default:
printf("Invalid number! Please enter a number from 1 to 4.");
break;
}
}
Several things that need to be fixed. When declaring variables, it's good practice to initialise them at the time of decleration. Rather than int a; a = x; And to only declare variables when needed. But this can obviously come down to preference and practice. In C89 variables had to be declared at the top of the scope but I can tell you're not compiling C89. You also didn't need to loop the rand 12 times. Just two calls is enough if you want two seperate ints. Keep in mind rand isn't very good but for practice it's okay. Placing a new line after print statement can make the output neater. countCorrect and countIncorrect were declared but not initialised to 0 then later incremented. This is bad practice because you don't know the initial value of either variable and you wouldn't get an accurate count.
I'm assuming you want to only quit when the user enters 4 but keep looping otherwise?
Place the switch outside the loop then after the user guesses the product, read the choice from the user and use that value the end of the do while loop.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int guess(){
int x = 1+rand()%12;
int y = 1+rand()%12;
printf("The two random numbers generated are : %d and %d\n", x,y);
printf("Enter the product of the two numbers: ");
int z = 0;
scanf("%d", &z);
if(z == (x*y)){
printf("Correct response!\n");
return 1;
}
printf("Incorrect response, the correct answer is: %d\n", x*y);
return 0;
}
int main () {
srand(time(NULL));
printf("Two random numbers (1-12) will be generated and displayed. The objective of this game is to correctly guess the product of the numbers.\n");
int correct = 0;
int incorrect = 0;
int choice = 1;
do{
if(choice==1){
if(guess()){
++correct;
}else{
++incorrect;
}
}
printf("Enter 1 to play again\nEnter 2 to see statistics\nEnter 3 to reset statistic\nEnter 4 to quit:");
scanf("%d",&choice);
switch (choice) {
case 1:
break;
case 2:
printf("You have chosen to see statistics\n");
printf("The number of correct answers are: %d\n", correct);
printf("The number of incorrect answers are: %d\n", incorrect);
break;
case 3:
printf("You have chosen to reset statistics\n");
correct = 0;
incorrect = 0;
break;
case 4:
printf("You have chosen to quit\n");
break;
default:
printf("Invalid number! Please enter a number from 1 to 4.\n");
break;
}
}while(choice !=4);
return 0;
}

Program that displays each digit on an integer in english doesn't work with an integer beginning with "0"

I have an assignment were I have to write a program that takes an integer keyed in from the terminal and extracts and displays each digit of the integer in English. I'm not able to use arrays or recursion, we're just starting with programming.
For example:
"123" returns "one two three"
My program is working well (for the most part), but the problem is that when you enter something like "0123" in the terminal the program returns "eight three"... WTH??
This is my code:
// Program that takes an integer and displays each digit in English
#include <stdio.h>
int main (void)
{
int num, digit;
int reversed = 0, backupZero = 0;
printf("Please enter an integer:\n");
scanf("%i", &num);
if (num == 0) // In case the input is just "0"
{
printf("zero");
}
while (num > 0) // Loop to reverse the integer
{
digit = num % 10;
reversed = (reversed * 10) + digit;
if ((reversed == 0) && (digit == 0)) // If the integer finishes in zero
{
++backupZero; // Use this to add extra zeroes later
}
num /= 10;
}
while (reversed > 0)
{
digit = reversed % 10;
reversed /= 10;
switch (digit)
{
case 1:
printf("one ");
break;
case 2:
printf("two ");
break;
case 3:
printf("three ");
break;
case 4:
printf("four ");
break;
case 5:
printf("five ");
break;
case 6:
printf("six ");
break;
case 7:
printf("seven ");
break;
case 8:
printf("eight ");
break;
case 9:
printf("nine ");
break;
default:
printf("zero ");
break;
}
}
for (int counter = 0; counter < backupZero; ++counter) // Prints the extra zeroes at the end
{
printf("zero ");
--backupZero;
}
printf("\n");
return 0;
}
Probably is something on the mathematics, I admit I'm not good at it.
When you read in the number with
scanf("%i", &num);
You are letting scanf infer the base of the number. Numbers starting with 0 followed by other digits are interpreted as octal. So 0123 is not the same as 123. It is in fact, 83.
0100 = 64
020 = 16
03 = 3
---------
0123 = 83
To read the number as base 10, use
scanf("%d", &num);
If you want to handle numbers that start with '0', then I suggest that you read the user input as a string (array of characters) rather than as an integer.
In addition to that, instead of "doing a switch" on each character, you can use a simple array in order to map the correct word to each digit.
Here is one way for implementing it:
#include <stdio.h>
#define MAX_INPUT_LEN 100
const char* digits[] = {"zero","one","two" ,"three","four",
"five","six","seven","eight","nine"};
int main()
{
int i;
char format[10];
char str[MAX_INPUT_LEN+1];
sprintf(format,"%c%us",'%',MAX_INPUT_LEN); // now format = "%100s"
scanf(format,str); // will write into str at most 100 characters
for (i=0; str[i]!=0; i++)
{
if ('0' <= str[i] && str[i] <= '9')
printf("%s ",digits[str[i]-'0']);
else
printf("invalid character ");
}
return 0;
}
Oh, wow. It took me 3 or 4 hours to write following code. I'm into c only first week, so please be considerate.
Update: added working minus + some comments.
#include <stdio.h>
#include <math.h>
int main(void)
{
int num, count, user, out;
count = 0;
printf("Type in any int: ");
scanf("%d", &num);
// adding minus to the beginning if int is negative
if (num < 0)
{
num = -num;
printf("minus ");
}
user = num;
// creating a power to the future number
while (num != 0)
{
num = num / 10;
count++;
}
int i2;
i2 = count;
// main calculations: dividing by (10 to the power of counter) and subtracting from the initial number
for (int i = 0; i < i2; i++)
{
out = user / pow(10, count - 1);
user = user - out * pow(10, count - 1);
count--;
switch (out)
{
case 1:
printf("one ");
break;
case 2:
printf("two ");
break;
case 3:
printf("three ");
break;
case 4:
printf("four ");
break;
case 5:
printf("five ");
break;
case 6:
printf("six ");
break;
case 7:
printf("seven ");
break;
case 8:
printf("eight ");
break;
case 9:
printf("nine ");
break;
case 0:
printf("zero ");
break;
default:
break;
}
}
printf("\n");
return 0;
}
There are some mistakes:
if ((reversed == 0) && (digit == 0)) (incorrect)
if ((reversed == 0) || (digit == 0)) (correct)
And in the last loop you should remove
--backupZero;
And code will read numbers better

C - Issue converting a user generated number into words

So I've been working my way through Kochan's Programming in C and I've hit a snag on one of the questions which reads as follows:
"Write a program that takes an integer keyed in from the terminal and extracts and displays each digit of the integer in English. So if the user types in 932, the program should display the following: nine three two (Remember to display zero if the user types in just 0.)"
I had managed to get the program to print out the digits as words but unfortunately in reverse order. From there I thought it might be a good idea to reverse the number so to speak, but now when I run that value through my program only prints out "one one one ...." for how ever many digits long the number I enter in.
In other words, originally I managed to display 932 as "two three nine", but when I tried to reverse the number and run 239 through my program I only get "one one one".
If any one has any hints that could point me in the right direction it would be very much appreciated! My code is below:
#include <stdio.h>
int digitCount (int);
int reverseNumber (int);
int main(void)
{
//Chapter 6 Problem 6
int x, numberValue;
printf("Enter the number you'd like converted to words\n");
scanf("%i", &x);
numberValue = reverseNumber(x);
printf("The reverse is %i\n", numberValue);
do {
numberValue = numberValue % 10;
switch (numberValue) {
case 0:
printf("zero\t");
break;
case 1:
printf("one\t");
break;
case 2:
printf("two\t");
break;
case 3:
printf("three\t");
break;
case 4:
printf("four\t");
break;
case 5:
printf("five\t");
break;
case 6:
printf("six\t");
break;
case 7:
printf("seven\t");
break;
case 8:
printf("eight\t");
break;
case 9:
printf("nine\t");
break;
default:
break;
}
x = x / 10;
} while (x != 0);
return 0;
}
int digitCount (int u)
{
int cnt = 0;
do {
u = u / 10;
cnt++;
} while (u != 0);
return cnt;
}
int reverseNumber (int y)
{
int cnt, Rev;
cnt = digitCount(y); //returns number of digits
while (cnt != 0) {
Rev = Rev * 10 + y % 10;
y = y / 10;
cnt--;
}
return Rev;
}
In your reverseNumber function you have not initialized Rev. Make Rev=0
int reverseNumber (int y)
{
int cnt, Rev=0;
cnt = digitCount(y); //returns number of digits
printf("Digit count %d\n", cnt);
while (cnt != 0) {
Rev = Rev * 10 + y % 10;
y = y / 10;
cnt--;
}
return Rev;
}
In main in the do while loop use a temporary variable since you are overwriting numberValue with numberValue % 10. But the most ironic part in your program (where you complicated everything for yourself) is that there is no need to reverse the number at all. See the code here
In the way user entered - http://ideone.com/pORaP2
In reverse order - http://ideone.com/5GS8al
When you find modulo you get the number in the reverse order itself. Suppose you entered 234
First step 234%10 gives 4 prints four. And then makes 234 to 23
Second step 23%10 gives 3 prints three. And then makes 23 to 2
and then finally prints two.
Consider what the primary problem is you are dealing with, you need to process the left most digit first, then the next to the right, then the next. But the math of using modulus and division goes from right to left. So what you need is some way to either save the math processing and reverse, or have the output be delayed. Two options are available.
For an iterative approach you could utilize a FIFO queue type approach that holds the results of each digit and then prints out the queue. Could be as simple as an array with indexing:
int main(void) {
int x, i;
int result[32]; //arbitrary size
int index = 0;
printf("Enter the number you'd like converted to words\n");
scanf("%i", &x);
do {
results[index++] = x % 10;
x = x / 10;
} while( index < 32 && x != 0 );
//now print in reverse order
for(i = index-1; i >= 0; i--) {
switch (results[i]) {
case 0:
printf("zero\t");
break;
case 1:
printf("one\t");
break;
case 2:
printf("two\t");
break;
case 3:
printf("three\t");
break;
case 4:
printf("four\t");
break;
case 5:
printf("five\t");
break;
case 6:
printf("six\t");
break;
case 7:
printf("seven\t");
break;
case 8:
printf("eight\t");
break;
case 9:
printf("nine\t");
break;
default:
break;
}
}
}
There is second approach that works which is recursive. Here you delay the printing of the output until you reach the left most digit. The built in stack is used for by the recursive calls.
void printNumbers(int x);
int main(void) {
int x;
printf("Enter the number you'd like converted to words\n");
scanf("%i", &x);
printNumbers(x);
}
void printNumbers(int v) {
if( v > 9 ) {
printNumbers( v / 10 );
}
switch (v%10) {
case 0:
printf("zero\t");
break;
case 1:
printf("one\t");
break;
case 2:
printf("two\t");
break;
case 3:
printf("three\t");
break;
case 4:
printf("four\t");
break;
case 5:
printf("five\t");
break;
case 6:
printf("six\t");
break;
case 7:
printf("seven\t");
break;
case 8:
printf("eight\t");
break;
case 9:
printf("nine\t");
break;
default:
break;
}
}
Both approaches will solve the problem, but not if the input is a negative number.
My simple answer:
void printNum(int x)
{
static const char * const num[] = {
"zero ", "one ", "two " , "three ", "four ",
"five ", "six ", "seven ", "eight ", "nine "
};
if (x < 10) {
printf(num[x]);
return;
}
printNum(x / 10);
printNum(x % 10);
}

A C program does not work when input number is too large

I wrote a program in C that prints English that represents input number (digit by digit)
for example, when you enter 938, it will print out nine three eight
It doesn't work when the input gets too large (more than 9 digits).
Can anyone explain to me why this happens?
I have tried to use unsigned int instead of int for the variables, but it still does not work.
#include <stdio.h>
/**
10/17/2012
Programming in C
Ch6 no. 6
Program doesn't work when number gets too large (>9 digits)
Print english that represents input number (digit by digit)
*/
int main(void){
int digit;//use to hold digit
int number;//hold input number
int revNumber = 0; //the reversed digit of the input number
int no_zero = 0;//number of zero needed to be printed at the end
int i = 1;//hold how many digits does the number have (+1 = i*10)
printf("Please enter a number\n");
scanf("%u", &number);
int testing = number;//a copy of input number for
//counts how many digits does the number have (+1 = i*10)
for(; testing != 0;i *= 10){
testing /= 10;
}
//make the reversed number
do{
i /= 10;
digit = number % 10;
if(digit == 0)
no_zero++;
revNumber += (digit*i);
number /= 10;
}while(number != 0);
//print the result using the reversed number
do{
digit = revNumber % 10;
revNumber /= 10;
switch(digit)
{
case 0:
printf("zero ");
no_zero--; //minus zero not at the end
break;
case 1:
printf("one ");
break;
case 2:
printf("two ");
break;
case 3:
printf("three ");
break;
case 4:
printf("four ");
break;
case 5:
printf("five ");
break;
case 6:
printf("six ");
break;
case 7:
printf("seven ");
break;
case 8:
printf("eight ");
break;
default:
printf("nine ");
}
}while(revNumber != 0);
//add back the ending zero
for(;no_zero!=0;no_zero--)
printf("zero ");
return 0;
}
The standard representation of ints in C is limited. Basically, you have 8 * sizeof (int) bits available (let's say 32). Having 32 bits available, an unsigned int can be as large as 2^32 - 1 which is 4294967295 any number greater than this is not ok.
You can try with unsigned long long but this would still be limited. Or, you can try using the BigNum library.
However, for your specific problem, reading the number as a string and acting on each letter of this string should be enough.
An int can (usually) only hold a 32-bit number, so it is limited to storing numbers in the range [-2147483648, 2147483647]. So, it can work for any 9 digit number, but fails for most 10-digit numbers.
Instead of putting the number in an int, why don't you just read each digit one-at-a-time (with, e.g. getc) and process them separately? Then you can handle numbers of any size easily, without needing to use strings.
From what i gather, you don't really need to store it in a int. Store it as a string (char[]) and then display each digit.
You can infact remove the array entirely and just print the word representation of each digit while it is being entered then discard it.
An integer consists of 32 bits. If you enter a number greater than 2^32, it won't work. Try getting a string from the user instead of an integer.
You can also use unsigned long long int which is a 64-bit variable.

Resources