Making a mad libs game - c

I am trying to make a mad libs game but every time I test the first two scanf functions work, but the fgets function is not working how it should be.
it keeps printing the same things I want it to but it's showing the mad libs text before the user has a chance to type in the fgets input
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char color[20];
char COL2[20];
printf("Enter a color: ");
scanf("%s", color);
printf("Enter a another color: ");
scanf("%s", COL2);
printf("Enter a celebrity name: \n");
char celebrity[15];
fgets(celebrity, 15, stdin);
printf("Roses are %s", color);
printf("Violets are %s", COL2);
return 0;
}

fscanf(stdin, "%15s", celebrity);
It worked on my laptop, so it should be fine.
Also fscanf is better and safer usually from what I've heard. Because it checks for end of line.

Related

I'm new to C and am stuck with many issues, I have fixed them but I wonder if there are better ways

I'm new to C just coming out of my second university class that explained structs and string functions. I tried running the code we had written in the lesson and ban, one segmentation error, "gets" suddenly is banned by my compiler and I have spent the last couple of hours trying to make it work with rubber band solutions of bread-crumbs I found online.
As luck would have it I made it work, yet I would like to learn more: better solutions, other options, etc. I really would like a little guidance even if just to resources.
It's a simple code that ask for an int, then a string and a float, and loops around until the int is 0.
A problem that I couldn't fix is how to remove the new line "fgets" adds to get the style that I put the output in class, I don't know if I ask Google the wrong answer or if it isn't ask much because it is to obvious.
And before the recommendations of leaving the university come up, I'll ask the teacher about this, and hopefully he will give a good reason why he taught us like this.
Class code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CLEAR system("cls||clear")
typedef struct a
{
int id;
char *name;
float avarage;
} student;
int main()
{
student stud;
printf("\n Input ID: ");
scanf("%d", &stud.id);
while (stud.id != 0)
{
fflush(stdin);
printf("\n input the name: ");
gets(stud.name);
fflush(stdin);
printf("\n input the avarage: ");
scanf("%f", &stud.avarage);
CLEAR;
printf ("\n ID: %d | Name: %s | Avarage: %.2f", stud.id, stud.name, stud.avarage);
printf("\n\n Input ID: ");
scanf("%d" , &stud.id);
}
CLEAR;
return 0;
}
First I found fgets I put it in and it struck me with a segmentation error, Google what that was, then I used malloc to allocate memory space to the stud.name pointer, then it didn't blow up but i couldn't type anything in stud.name, spent 1 hour searching why, until I discover that it is because of the input buffer that is storing a new line from the first scanf (and the last by proxy) and that is what the fgets is reading, tried fflush(stdin): doesn't work, and then I find that getchar() stores this new line and it let me finally write in stud.name. Then, it finally worked.
My code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CLEAR system("cls||clear")
typedef struct a
{
int id;
char *name;
float avarage;
} student;
int main()
{
student stud;
stud.name = (char *) malloc(sizeof(char) * 30);
printf("\n Input ID: ");
scanf("%d", &stud.id);
getchar();
while (stud.id != 0)
{
printf("\n input the name: ");
fgets(stud.name, 30, stdin);
printf("\n input the avarage: ");
scanf("%f", &stud.avarage);
getchar();
CLEAR;
printf ("\n ID: %d | Name: %s | Avarage: %.2f", stud.id, stud.name, stud.avarage);
printf("\n\n Input ID: ");
scanf("%d" , &stud.id);
getchar();
}
CLEAR;
return 0;
}

Get text from user input using C

I am just learning C and making a basic "hello, NAME" program. I have got it working to read the user's input but it is output as numbers and not what they enter?
What am I doing wrong?
#include <stdio.h>
int main()
{
char name[20];
printf("Hello. What's your name?\n");
scanf("%d", &name);
printf("Hi there, %d", name);
getchar();
return 0;
}
You use the wrong format specifier %d- you should use %s. Better still use fgets - scanf is not buffer safe.
Go through the documentations it should not be that difficult:
scanf and fgets
Sample code:
#include <stdio.h>
int main(void)
{
char name[20];
printf("Hello. What's your name?\n");
//scanf("%s", &name); - deprecated
fgets(name,20,stdin);
printf("Hi there, %s", name);
return 0;
}
Input:
The Name is Stackoverflow
Output:
Hello. What's your name?
Hi there, The Name is Stackov
#include <stdio.h>
int main()
{
char name[20];
printf("Hello. What's your name?\n");
scanf("%s", name);
printf("Hi there, %s", name);
getchar();
return 0;
}
When we take the input as a string from the user, %s is used. And the address is given where the string to be stored.
scanf("%s",name);
printf("%s",name);
hear name give you the base address of array name. The value of name and &name would be equal but there is very much difference between them. name gives the base address of array and if you will calculate name+1 it will give you next address i.e. address of name[1] but if you perform &name+1, it will be next address to the whole array.
change your code to:
int main()
{
char name[20];
printf("Hello. What's your name?\n");
scanf("%s", &name);
printf("Hi there, %s", name);
getchar();
getch(); //To wait until you press a key and then exit the application
return 0;
}
This is because, %d is used for integer datatypes and %s and %c are used for string and character types

C prompt ordering for reading string with getchar() [duplicate]

This question already has answers here:
Why is getchar() reading '\n' after a printf statement?
(3 answers)
Closed 9 years ago.
This is a newbie question. I am new to C programming. I have the following code which does not prompt for 'Name' Onece the 'Age' is entered, it bypass the 'Name section.
#include <stdio.h>
int main()
{
char name[30],ch;
int age;
printf("Enter age : ");
scanf("%d", &age);
int i=0;
printf("Enter name: ");
while((ch = getchar())!='\n')
{
name[i]=ch;
i++;
}
name[i]='\0';
printf("Name: %s\n",name);
printf("Age : %d\n", age);
return 0;
}
After reading first prompt it bypass the second prompt which is using getchar() function. But if I change the order of prompt to ask for 'Name' first and then 'Age' it works fine.
The working code.
#include <stdio.h>
int main()
{
char name[30],ch;
int age;
int i=0;
printf("Enter name: ");
while((ch = getchar())!='\n')
{
name[i]=ch;
i++;
}
name[i]='\0';
printf("Enter age : ");
scanf("%d", &age);
printf("Name: %s\n",name);
printf("Age : %d\n", age);
return 0;
}
My coding IDE is CodeBlock and my compiler is GNU C Compiler (mingw32-gcc.exe)
Please help me to breakthrough.
A few improvements/advices to the code in the question:
the type of the return value of getchar() is int, so the type of ch also should be int
you could (and should, I believe) use format %s to read the name, this is easier and the leading white spaces in the input stream would not be a problem
the user of the code could give a name which contains more than 30 characters, and this input could crash your program, so you should protect your code for this possibility. You have two options:
a. use format '%29s" to read the name
b. change the definition of name to char *name, read it by scanf("%ms", &name);, and call free(name); after you do not need it anymore
Here is an example, in which the name can be very long and can include spaces:
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
char *name;
int age;
printf("Enter name: ");
scanf("%m[^\n]", &name);
printf("Enter age: ");
scanf("%d", &age);
printf("Name: %s\n", name);
printf("Age : %d\n", age);
free(name);
exit(EXIT_SUCCESS);
}
And here is a run of it:
$ ./a.out
Enter name: a very looooooooooooooooooooooooooooooooooooooooooooooong name
Enter age: 12
Name: a very looooooooooooooooooooooooooooooooooooooooooooooong name
Age : 12
In first code the \n character left behind by the scanf is read by getchar. This makes the condition (ch = getchar())!='\n' in while loop false and the loop body never get executed.
You need to consume that \n character which comes up to the buffer along with the age you entered on pressing Enter key.
Putting the statement
while(getchar()!='\n');
after the scanf will consume all of the newline characters.
Your second code is working fine because %d skips white-space characters unlike %c specifiers.

scanf is not waiting for input

I'm trying to find the bug here, but still don't get it.
I've been debugging and googling it and found some close topics, but there are only solutions which I don't need ATM, and I'm curious why this code is not working:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define BUFFER 256
int main()
{
int missionCode;
char *desc = (char*)malloc(sizeof(char)*BUFFER);
do {
printf("Please enter the mission code (or -1 for exit): ");
scanf("%d", &missionCode);
fflush(NULL);
if (missionCode==-1)
return 1;
} while (missionCode>10);
do {
printf("Please enter a string:\n");
scanf("%[^\n]s", desc); //it doesn't stop here!
fflush(NULL);
if (!strcmp("exit",desc))
return 1;
} while (strlen(desc)<20);
printf("your string:\n%s", desc);
return 0;
}
There's something wrong with the scanf\flushall in the second loop, but I don't find out what.
BTW, this is C ofcourse.
scanf("%d", &missionCode);
leaves the newline in the buffer, so
scanf("%[^\n]s", desc);
immediately finds one and stops. You can add a space
scanf(" %[^\n]s", desc);
to the format to skip initial whitespace.

different behavior xcode and Dev-C++

Just beginning to learn C.
if I compile the following code in Dev-C++ the program runs fine.
If I compile in Xcode 3.2.6 it looks like in the screenshot.
I tried different compiler settings in Xcode but the behavior is still the same.
Any ideas on this?
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char artist[30];
char album[30];
int tracks;
char albumsingle;
float price;
printf("Please enter CD informations below. \n \n");
printf("enter cd artist: ");
scanf("%[^\n]", artist);
printf("enter cd title: ");
fflush(stdin);
scanf("%[^\n]", album);
printf("enter no. of tracks: ");
fflush(stdin);
scanf("%d", &tracks);
printf("enter a for album s for single: ");
fflush(stdin);
scanf("%c", &albumsingle);
printf("enter price: ");
fflush(stdin);
scanf("%f", &price);
printf("\n\n\nartist: %s\n", artist);
printf("album: %s\n", album);
printf("track no.: %d\n", tracks);
if (albumsingle == 'a'){
printf("cd type: album\n");
} else {
printf("cd type: single\n");
}
printf("price: %.2f EUR\n\n", price);
system("PAUSE");
return 0;
}
My guess is it has to do with the system("PAUSE"); statement. Xcode is used on OSX, which is a UNIX variant, and doesn't have the command pause.
Instead why not just ask the user to press the enter key manually instead? Like this:
printf("Press the ENTER key to continue.\n");
int c;
do
{
c = fgetc(stdin);
} while (c != '\n' && c != EOF);
It has the advantage of working on most systems.
fflush(stdin);
Causes an Undefined Behavior, and hence your program shows different behavior on different compilers.
Reference C standard:
int fflush(FILE *ostream);
ostream points to an output stream or an update stream in which the most recent operation was not input, the fflush function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; otherwise, the behavior is undefined.
PAUSE is a Windows, not a Unix command ... so that won't work on the Mac. Use something like getchar() instead if you just want to pause the program at the end.
Include a header file Conio.h and use getch() function whenever you want to hold screen.

Resources