Why does my program skip a switch instruction? - c

I am trying to write a program, where after 7 floats inputted by the user; they get stored into an array, then get printed out like this:
DAY VALUE ISTOGRAM
1 37.8 ***
2 40.6 ******
where the number of * in the Istogram column is given by value - 34.
I've written this code:
#include <stdio.h>
#define OBSERVATION 7
#define MEDIAN 34
int main() {
float temp[OBSERVATION] = {0};
printf("Insert the patient's temperature over the course of 7 days: ");
for(int i = 1; i <= OBSERVATION; i++){
scanf("%f", &temp[i]);
}
printf("DAY\tVALUE\tISTOGRAM\n");
for(int i = 1; i <= OBSERVATION; i++){
printf("%6d\t%6g\n", i, temp[i]);
}
for(int i = 1; i <= OBSERVATION; i++){
switch ((int)temp[i] - MEDIAN) {
case 0: break;
case 1: printf("\t\t\t\t*");
break;
case 2: printf("\t\t\t\t**");
break;
case 3: printf("\t\t\t\t***");
break;
case 4: printf("\t\t\t\t****");
break;
case 5: printf("\t\t\t\t*****");
break;
case 6: printf("\t\t\t\t******");
break;
case 7: printf("\t\t\t\t*******");
break;
case 8: printf("\t\t\t\t********");
break;
case 9: printf("\t\t\t\t*********");
break;
case 10: printf("\t\t\t\t*********");
break;
case 11: printf("\t\t\t\t**********");
break;
case 12: printf("\t\t\t\t***********");
break;
}
printf("\n");
}
return 0;
}
The code compiles fine and outputs the first two columns correctly, but completely skips the switch statement. I've already tried to check if it erroneously assigns 0 to temp[i] when it gets cast to an int, but it doesn't do that. It simply skips the switch.
Also do you have a more "compact" way on how to print out the * column without using a switch?

I would rewrite your code like this:
#include <stdio.h>
#include "math.h"
#define OBSERVATION 7
#define MEDIAN 34
int main() {
float temp[OBSERVATION] = {0};
int iDifference = 0;
printf("Insert the patient's temperature over the course of 7 days: \n");
for(int i = 0; i < OBSERVATION; i++){
scanf("%f", &temp[i]);
}
then print the headers:
printf("DAY\tVALUE\tISTOGRAM\n");
start the row loop:
for(int i = 0; i < OBSERVATION; i++){
// calculate the difference integer
iDifference = round(temp[i] - MEDIAN);
// don't add stars if the temperature diff is lower than 0
if(iDifference < 0) iDifference = 0;
// print the first two columns, notice that the new line isn't added yet
printf("%6d\t%6.2f\t", i, temp[i]);
// print the stars
vDrawStars(iDifference);
// then write the newline character
printf("\n");
}
return 0;
}
then the drawing stars routine:
void vDrawStars(int prm_iCount){
int p = 0;
// I didn't understand the case for it but
// printf("\t\t\t\t");
// then draw the needed stars
for(p = 0; p < prm_iCount; p++)
{
printf("*");
}
// no new lines, still on the same line.
}
Here's a demo here: https://onlinegdb.com/BJPyvDJRX

Your code works incorrectly, because you access the array temp out of bounds. Array indexes start with zero, so you should index with for(int i = 0; i < OBSERVATION; i++).
The switch:
switch ((int)temp[i] - MEDIAN) {
case 0: break;
case 1: printf("\t\t\t\t*");
break;
case 2: printf("\t\t\t\t**");
break;
case 3: printf("\t\t\t\t***");
break;
case 4: printf("\t\t\t\t****");
break;
case 5: printf("\t\t\t\t*****");
break;
case 6: printf("\t\t\t\t******");
break;
case 7: printf("\t\t\t\t*******");
break;
case 8: printf("\t\t\t\t********");
break;
case 9: printf("\t\t\t\t*********");
break;
case 10: printf("\t\t\t\t*********");
break;
case 11: printf("\t\t\t\t**********");
break;
case 12: printf("\t\t\t\t***********");
break;
}
may be optimized just to:
const int val = (int)temp[i] - MEDIAN;
if (1 <= val && val <= 12) { // make sure it's between 1 and 12
printf("\t\t\t\t%.*s", val, "***********");
}
The printf format modifier "%.*s" takes two parameters - length of the string to print and the string itself
We print val length of "**********" characters.

Related

How can we update the value of a global variable using switch statement in C?

int mmak = 0;
int main(void)
{
int marks[3] [3] = {{0,5,6}, {1,5,9}, {2,9,5}};
for (int k = 0; k < 3; k++)
{
int sunk = marks[k] [0];
switch (sunk)
{
case '0': mmak++;
break;
case '1': mmak++;
break;
case '2': mmak++;
break;
}
}
printf("%i\n", mmak);
}
I want to update the value of global variable mmak. but the output I am still geting is 0. Can anyone help?
Even if the issue is solved by removing single quoting of the clauses of your switch, I'd like to enrich this by adding some remarks:
You should always consider a default case in a switch statement that covers unexpected situations.
When you are printing an int you should use '%d' instead of '%i' for the reason explained here: ...difference between %d and %i ....
Always end your main with a return [int]; statement.
#include <stdio.h>
int mmak = 0;
int main(void)
{
int marks[3] [3] = {{0,5,6}, {1,5,9}, {2,9,5}};
int sunk;
for (int k = 0; k < 3; k++)
{
sunk = marks[k] [0];
switch (sunk)
{
case 0:
mmak++;
break;
case 1:
mmak++;
break;
case 2:
mmak++;
break;
default:
printf("No value found\n");
break;
}
}
printf("%d\n", mmak);
return 0;
}
case '2':
This case compares to the ASCII '2' (int 50), which is not the same as int 2. Instead use:
case 2:
The additional advice from comments for falling through cases will help when the same operation will be performed for more than one case:
case 0:
case 1:
case 2: mmak++;
break;
case 3: mmak+=2;

Why didn't I get the output of the array?

Why didn't I get the output of the array? I want to save the value to array,m[10], by switch case,but i can't print out the value of array.
#include <stdio.h>
/******************************************
* 公元年分非4的倍數,為平年。
* 公元年分為4的倍數但非100的倍數,為閏年。
* 公元年分為100的倍數但非400的倍數,為平年。
* 公元年分為400的倍數為閏年。
*****************************************/
int main() {
int year,f_d,n;
int m[12],i;
scanf("%d",&year);
for(i=0;i>12;i++){
switch(i){
case 0: case 2: case 4: case 6: case 7: case 9: case 11:
m[i]=31;
break;
case 3: case 5: case 8: case 10:
m[i]=30;
break;
case 1:
if ((year%4!=0)||
((year%100==0)&&(year%400!=0)))
m[i]=28;
else
m[i]=29;
break;
default:
m[i]=0;
}
}
for(i=0;i>12;i++)
printf("%d/n",m[i]);
return 0;
}
The very first loop
for(i=0;i>12;i++)
does not do what you want: when i is set to 0, it is not greater than 12 so the whole loop is skipped.
replace for (i = 0; i > 12; i++) to for (i = 0; i < 12; i++) will work.

C case-switch statement not running through full loop

Trying to solve a problem on kattis.com called "Bela", which requires some character comparison, but when i run my code the scanf() function does not get called the last couples time for the last couple iterations of the loop.
here is my code:
#include <stdio.h>
int main( void ) {`
char dom;
int n;
scanf("%d %c", &n, &dom);
n*=4;
int sum = 0;
for (int i = 0; i < n; i++) {
char num;
char suit;
scanf("%c%c", &num, &suit);
switch (num) {
case 'A':
sum += 11;
break;
case 'K':
sum += 4;
break;
case 'Q':
sum += 3;
break;
case 'J':
if (suit == dom) { sum +=20;}
else { sum += 2;}
break;
case 'T':
sum+=10;
break;
case '9':
if (suit == dom){sum+=14;}
break;
case '8':
break;
case '7':
break;
default:
continue;
}
}
printf("%d", sum);
return 0;
}
and when i run the with this test case program i get this:
:~$ ./a.out
^V
2 S
TH
9C
KS
QS
JS
TD3
AD
JH
:~$ TD
TD: command not found
:~$ AD
AD: command not found
:~$ JH
JH: command not found
why is the for loop not executing completely? Is there anyhting inherently wrong with my code that the switch case statement does not evaluate "TD", "AD", "JH"?
why is the for loop not executing completely?
Add printf("\nEnter:"); before second scanf check it. The loop execute fully but the scanf catches spaces.
So,
Add
while((ch=getchar()!='\n')&&ch!=EOF);
Before the second scanf or change second scanf to
scanf(" %c%c", &num, &suit);
^
This statements are ignore spaces(' ','\n',...)

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);
}

Resources