12 Days Of Christmas C Program in Functions - c

A C program that contains a function that outputs the lyrics of the traditional Christmas song “Twelve Days of Christmas.” Do not print the entire lyrics manually.
So I made a code and there were errors but I finally fixed it. My Twelve Days of Christmas Song prints well with the looping.
But I have another problem. Is my code possible to be separated or dissected as functions?
The instruction says, "Your function will just be invoked in the main() function and will not return anything." So I guess I'll be using void? In what way?
#include <stdio.h>
#include <conio.h>
int main() // Main Function
{
int days, counter, num;
printf("\n\t\t* * * TWELVE DAYS OF CHRISTMAS * * *\n");
printf("\t\t_____________________________________\n\n\n");
for (counter=1; counter<=12; counter++) {
printf("\tOn the ");
switch(counter){
case 1:
printf("1st");
break;
case 2:
printf("2nd");
break;
case 3:
printf("3rd");
break;
default:
printf("%dth", counter);
break;
}
printf(" day of Christmas my true love sent to me\n\n");
switch(counter) {
case 12: printf("\t\tTwelve Drummers Drumming\n\n");
case 11: printf("\t\tEleven Pipers Piping\n\n");
case 10: printf("\t\tTen Lords a Leaping\n\n");
case 9: printf("\t\tNine Ladies Dancing\n\n");
case 8: printf("\t\tEight Maids a Milking\n\n");
case 7: printf("\t\tSeven Swans a Swimming\n\n");
case 6: printf("\t\tSix Geese a Laying\n\n");
case 5: printf("\t\tFive Golden Rings\n\n");
case 4: printf("\t\tFour Calling Birds \n\n");
case 3: printf("\t\tThree French Hens\n\n");
case 2: printf("\t\tTwo Turtle Doves\n\n");
case 1: printf("\t\t");if (counter > 1 ) printf("And ");printf("A Partridge in a Pear Tree\n\n");
// case 1: printf("\t\tA Partridge in a Pear Tree\n\n");
}
}
getchar(); return 0; }
Tried executing this and works fine with the printing. Do you have any suggestions to imporove my code? Having trouble with functions.

It just means all the work should be done in a void function, which is then called in main:
void doTheWork(void); // function declaration
int main(void)
{
doTheWork();
return 0;
}
#include <stdio.h>
// function definition
void doTheWork(void)
{
// put the implementation here
}

Use a void function.
void print12DaysOfChristmas(void)
{
// Paste all your code here
}
int main(void) // Main Function
{
print12DaysOfChristmas();
return 0;
}
Notes:
About the function signatures in C, see this answer.
If the function were not defined before main, you would need to use a forward declaration.

It means that you should create a void function to do the job :
#include <stdio.h>
// Function Implementation
void yourFunction(void)
{
int days, counter, num;
printf("\n\t\t* * * TWELVE DAYS OF CHRISTMAS * * *\n");
printf("\t\t_____________________________________\n\n\n");
for (counter=1; counter<=12; counter++) {
printf("\tOn the ");
switch(counter){
case 1:
printf("1st");
break;
case 2:
printf("2nd");
break;
case 3:
printf("3rd");
break;
default:
printf("%dth", counter);
break;
}
printf(" day of Christmas my true love sent to me\n\n");
switch(counter) {
case 12: printf("\t\tTwelve Drummers Drumming\n\n");
case 11: printf("\t\tEleven Pipers Piping\n\n");
case 10: printf("\t\tTen Lords a Leaping\n\n");
case 9: printf("\t\tNine Ladies Dancing\n\n");
case 8: printf("\t\tEight Maids a Milking\n\n");
case 7: printf("\t\tSeven Swans a Swimming\n\n");
case 6: printf("\t\tSix Geese a Laying\n\n");
case 5: printf("\t\tFive Golden Rings\n\n");
case 4: printf("\t\tFour Calling Birds \n\n");
case 3: printf("\t\tThree French Hens\n\n");
case 2: printf("\t\tTwo Turtle Doves\n\n");
case 1: printf("\t\t");if (counter > 1 ) printf("And ");printf("A Partridge in a Pear Tree\n\n");
// case 1: printf("\t\tA Partridge in a Pear Tree\n\n");
}
}
}
int main(void)
{
yourFunction(); // Call your function
getchar();
return 0;
}
With a live example.

On your program you need to suppress all magic number (cf: http://en.wikipedia.org/wiki/Magic_number_%28programming%29)
Also, i optimize a bit your code as following:
#include <stdio.h>
#include <string.h>
#define FIRST_DAY "1st"
#define SECOND_DAY "2nd"
#define THIRD_DAY "3rd"
#define N_DAY "th"
#define ONLY_ONE_SENTENCE 0
#define LAST_DAY 1
#define NUMBER_OF_DAYS 12
#define BUFFER_SIZE 5
#define FIRST_ANNOUNCE "\tOn the %s day of Christmas my true love sent to me\n\n"
const char *sentences[] = {
"\t\tA Partridge in a Pear Tree\n\n",
"\t\tAnd A Partridge in a Pear Tree\n\n",
"\t\tTwo Turtle Doves\n\n",
"\t\tThree French Hens\n\n",
"\t\tFour Calling Birds \n\n",
"\t\tFive Golden Rings\n\n",
"\t\tSix Geese a Laying\n\n",
"\t\tSeven Swans a Swimming\n\n",
"\t\tEight Maids a Milking\n\n",
"\t\tNine Ladies Dancing\n\n",
"\t\tTen Lords a Leaping\n\n",
"\t\tEleven Pipers Piping\n\n",
"\t\tTwelve Drummers Drumming\n\n"};
void print12DaysOfChristmas();
int main() { // Main Function
print12DaysOfChristmas();
return 0;
}
void print12DaysOfChristmas() {
int days, counter, num, index;
char buffer[BUFFER_SIZE];
char *day;
printf("\n\t\t* * * TWELVE DAYS OF CHRISTMAS * * *\n");
printf("\t\t_____________________________________\n\n\n");
for (counter=1; counter <= NUMBER_OF_DAYS; counter++) {
switch (counter) {
case 1:
day=FIRST_DAY;
break;
case 2:
day=SECOND_DAY;
break;
case 3:
day=THIRD_DAY;
break;
default:
snprintf(buffer, BUFFER_SIZE,"%d",counter);
day=strcat(buffer, N_DAY);
break;
}
printf(FIRST_ANNOUNCE, day);
for (index=counter; index > 0; index--) {
// If there is only one sentence
if (counter == LAST_DAY) {
printf(sentences[ONLY_ONE_SENTENCE]);
} else {
printf(sentences[index]);
}
}
}
getchar();
}

Related

Changing an integer grade into a character grade using a switch statement

Using the switch statement, write a program that converts a numerical grade into a letter
grade:
Enter numerical grade: 84
Letter grade: B
Use the following grading scale:
A = 90-100, B = 80-89, C = 70-79, D = 60-69, F = 0-59.
Print an error message if the grade is larger than 100 or less than 0.
Hint: Break the grade into two digits, then use a switch statement to test the ten's digit.
How can I change the code to let 100 become A? I input 100 and the output was F.
#include <stdio.h>
int main(void)
{
int front_number, back_number;
printf("Enter numerical grade: ");
scanf("%1d%1d", &front_number, &back_number);
printf("Letter grade: ");
switch (front_number){
case 0: case 1: case 2: case 3: case 4: case 5:
printf("F");
break;
case 6:
printf("D");
break;
case 7:
printf("C");
break;
case 8:
printf("B");
break;
case 9:
printf("A");
break;
}
return 0;
}
In a real world program you would likely create a struct per grade, then search through a table of read-only elements. Example:
#include <stdio.h>
typedef struct
{
int low_limit;
int high_limit;
char grade;
} grade_t;
int main (void)
{
const grade_t grade[] =
{
{ 0, 59, 'F' },
{ 60, 69, 'D' },
{ 70, 79, 'C' },
{ 80, 89, 'B' },
{ 90, 100, 'A' },
};
int input = 82;
for(size_t i=0; i<sizeof grade/sizeof *grade; i++)
{
if(input <= grade[i].high_limit)
{
printf("%d gives %c", input, grade[i].grade);
break;
}
}
}
This is a naive linear search method but since the amount of items is so limited, it's likely quite efficient. Alternatively you could use standard C bsearch, in case you have a larger amount of sorted data.
Notably, we don't even need to know the lower limit since that's implicit by the previous item in the array.
It is better to not read two digits, because:
This tries to read the input and process this input in one step, while these are separate processes.
If the input is 100, it will leave the last 0 character in the input stream.
The cases 10 and 100 are indistinguishable.
The hint to "break the grade into two digits" is misleading for similar reasons.
The (probably) intended solution
Here is, what I assume to be, more or less the intended solution. It reads the entire (unsigned) integer, and uses a switch for its value divided by 10. The one not-so-elegant part is the default case (more of an "else" here) which has to distinguish between valid 3-digit input (i.e. 100 and invalid input.
Technically, part of the input is now being handled by an if-statement instead of a switch, but this is the most sensible solution given the problem statement. A bit better would be to catch the edge case grade == 100 at the top of function and leave the default case to only return an error value.
#include <stdio.h>
#include <stdlib.h>
char gradeUintToChar(unsigned int grade);
int main(void)
{
printf("Enter numerical grade: ");
fflush(stdout);
unsigned int gradeUint;
if (scanf("%u", &gradeUint) != 1)
{
fprintf(stderr, "Invalid input\n");
exit(EXIT_FAILURE);
}
char gradeChar = gradeUintToChar(gradeUint);
if (gradeChar == 0)
{
fprintf(stderr, "gradeUintToChar: Invalid parameter\n");
exit(EXIT_FAILURE);
}
printf("Letter grade: %c\n", gradeChar);
}
char gradeUintToChar(unsigned int grade)
{
switch (grade / 10U)
{
case 0: case 1: case 2: case 3: case 4: case 5:
return 'F';
case 6:
return 'D';
case 7:
return 'C';
case 8:
return 'B';
case 9:
return 'A';
default:
if (grade == 100U)
return 'A';
else
return (char) 0; // Indicates failure
}
}
The GNU case ranges solution
There is a GNU extension called case ranges which allows for this to be implemented rather directly using a switch. Since this is non-standard C, this is generally not a recommended method.
Code example:
#include <stdio.h>
#include <stdlib.h>
char gradeUintToChar(unsigned int grade);
int main(void)
{
printf("Enter numerical grade: ");
fflush(stdout);
unsigned int gradeUint;
if (scanf("%u", &gradeUint) != 1)
{
fprintf(stderr, "Invalid input\n");
exit(EXIT_FAILURE);
}
char gradeChar = gradeUintToChar(gradeUint);
if (gradeChar == 0)
{
fprintf(stderr, "gradeUintToChar: Invalid parameter\n");
exit(EXIT_FAILURE);
}
printf("Letter grade: %c\n", gradeChar);
}
char gradeUintToChar(unsigned int grade)
{
switch (grade)
{
case 0 ... 59:
return 'F';
case 60 ... 69:
return 'D';
case 70 ... 79:
return 'C';
case 80 ... 89:
return 'B';
case 90 ... 100:
return 'A';
default:
return (char) 0; // Indicates failure
}
}

Why does my program skip a switch instruction?

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.

print an int and char with the same identifier in C

I'm trying to do a simple code but I'm having hard time while trying to make it work.
I want to get an int from stdin between 1 and 50.
if the number is 1 then to print A
if the number is 11 then to print J
if the number is 12 then to print Q
if the number is 13 then to print K
Edit: If its none of them, then just return the number.
i tried to use %c but it wont work for numbers from 10 and above
then i managed to do it by using switch but the default part is not working for me. the only thing i managed to do is to make 50 case's for each number but that's just look horrible.
any help would be appreciated.
#include <stdio.h>
main() {
int number;
scanf("%d", &number);
char* card = NULL;
switch (number)
{
case 1:
card = "A";
break;
case 11:
card = "J";
break;
case 12:
card = "Q";
break;
case 13:
card = "K";
break;
default:
card = //Dont know what to write here//;
}
printf("%s\n", card);
return 0;
}
As far as I can see, this code should work:
#include <stdio.h>
#include <string.h>
#include <limits.h>
#define MAX_STRING_SIZE (sizeof(int)*CHAR_BIT/3 + 3)
int main(int argc, char **argv) {
int number = 0;
scanf("%d", &number);
char card[MAX_STRING_SIZE] = {0};
switch (number)
{
case 1:
strcpy(card, "A");
break;
case 11:
strcpy(card, "J");
break;
case 12:
strcpy(card, "Q");
break;
case 13:
strcpy(card, "K");
break;
default:
sprintf(card, "%d", number);
}
printf("%s\n", card);
return 0;
}
Note that you cannot assign strings with: card = "whatever", you must use strcpy() found in the string.h library. For the default part of your code, I assumed you were trying to convert the card input which was not 1, 11, 12, or 13. In which case, you can use sprintf() to convert the integer value to a string.
I hope this helps!
#define MINCARD 1
#define MAXCARD 50
const char *num2card(int n)
{
static char buf[3];
assert(n >= MINCARD && n <= MAXCARD && "Inval card no.");
switch (num) {
case 1:
return "A";
case 11:
return "J";
case 12:
return "Q";
case 13:
return "K";
default:
snprintf(buf, 3, "%d", num);
}
return buf;
}
Use an array of char. Each numerical "case" will correspond to an index in the array, and the element at that index will be the appropriate "card".
As for what the "default" value should be - that is a requirements question. What is the purpose of this application?
you can try sprintf, but you still have to add in logic for what happens if the number is larger than 50.
#include <stdio.h>
#include <stdlib.h>
int main() {
int number;
scanf("%d", &number);
char* card = malloc(8);
switch (number)
{
case 1:
card = "A";
break;
case 11:
card = "J";
break;
case 12:
card = "Q";
break;
case 13:
card = "K";
break;
default:
sprintf (card , "%i" , number );
}
printf("%s\n", card);
return 0;
}

How do I get switch() to loop multiple times in C?

I have created this fruit machine game. However I would like to loop the output several times before printing a final output that is then scored. To simulate the moving nature of a real slot machine. When I try and loop my switch() statements no output is produced. How would I go about doing this?
#include <stdio.h>
#include <unistd.h>
int main ()
{
int firstReel, secondReel, thirdReel, loop;
// Generating three random numbers
srand(time(NULL));
int rndOne = rand () %4;
int rndTwo = rand () %4;
int rndThree = rand () %4;
// Assigning random numbers to clearer var names
firstReel = rndOne;
secondReel = rndTwo;
thirdReel = rndThree;
// Switch statements for each reel
switch(firstReel){
case 0:
printf("Bell ");
break;
case 1:
printf("Cherry ");
break;
case 2:
printf("Orange ");
break;
case 3:
printf("Horseshoe ");
break;
}
switch(secondReel){
case 0:
printf("Bell ");
break;
case 1:
printf("Cherry ");
break;
case 2:
printf("Orange ");
break;
case 3:
printf("Horseshoe ");
break;
}
switch(thirdReel){
case 0:
printf("Bell\n");
break;
case 1:
printf("Cherry\n");
break;
case 2:
printf("Orange\n");
break;
case 3:
printf("Horseshoe\n");
break;
}
// Win/lose conditions
if (firstReel == secondReel || firstReel == thirdReel || secondReel == thirdReel)
printf("Congratulations! You win!\n");
else
{
printf("Sorry, you lose. Play again? (Y/N)\n");
}
}
use some sort of counter/ looping statement
int i=0;
while(i< 10){
//Your switch statements
i++;
}
As a better programming practice please do include default case/scenario too when the switch input doesn't satisfy any of the cases.. helps in keeping the code structured and avoids any confusion also showing that other values have been taken care of. For ex:
default:
printf("Invalid value entered");
break;
Try using a loop as shown below :
Here I am running the loop for some x number of times.You can run the loop for any number of times you wish to.
int main ()
{
int firstReel;
int i=0;
// Generating three random numbers
srand(time(NULL));
// Assigning random numbers to clearer var names
while(i<7)
{
firstReel = rand () %4;
// Switch statements for each reel
switch(firstReel){
case 0:
printf("Bell ");
break;
case 1:
printf("Cherry ");
break;
case 2:
printf("Orange ");
break;
case 3:
printf("Horseshoe ");
break;
}
i++;
}
}
This will show the reels spinning and slowing to the final pattern (in a console).
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SYMBOLS 4
#define REELS 3
#define SPINS 20
char *symbol [SYMBOLS] = {" Bell ", " Cherry ", " Orange ", "Horseshoe "};
int reel [REELS];
int main(int argc, char **argv)
{
int s, r, elap, tix, counts;
srand ((unsigned)time(NULL));
for (s=SPINS; s>0; s--) {
printf ("\r");
for (r=0; r<REELS; r++) {
reel [r] = rand() % SYMBOLS;
printf ("%s", symbol [reel [r]]);
}
tix = clock();
counts = CLOCKS_PER_SEC / s;
do {
elap = clock() - tix;
}
while (elap < counts);
}
printf ("\n");
for (r=1; r<REELS; r++)
if (reel [r] != reel [r-1])
break;
if (r < REELS)
printf ("You lost!\n");
else
printf ("You won!\n");
return 0;
}

Removing contents of variable in C

I want to delete the contents of an int variable when it gets to an else statement.
The program requests a number between 1 and 5 using scanf and the number is stored in the int variable and if the number isn't between 1 and 5 then the user is directed to an else statement and I have used a goto statement to take it back to the start and I was wondering how I removed the contents of the variable during the else statement so I don't create a continuos loop.
With getchar it's fpurge(stdin). I'm running Mac OS X.
BELOW IS THE CODE:
#include <stdio.h>
int main (int argc, const char * argv[])
{
int code;
start:
puts("Please type your error code.");
puts("Range 1-5: ");
scanf("%d", &code);
switch(code)
{
case 1:
printf("INFORMATION\n");
case 2:
printf("INFORMATION\n");
case 3:
printf("INFORMATION\n");
case 4:
printf("INFORMATION\n");
case 5:
printf("INFORMATION\n");
default:
printf("INFORMATION\n");
goto start;
}
}
Just set the int value to something else, eg:
theValue = 0;
You are probably looking for a do...while loop
Edit Don't forget your break statements!!
do
{
puts("Please type your error code.");
puts("Range 1-5: ");
scanf("%d", &code);
switch(code)
{
case 1:
printf("INFORMATION\n");
break;
case 2:
printf("INFORMATION\n");
break;
case 3:
printf("INFORMATION\n");
break;
case 4:
printf("INFORMATION\n");
break;
case 5:
printf("INFORMATION\n");
break;
default:
printf("INVALID CODE\n");break;
}
} while(code<1 || code> 5);

Resources