I've written a function that stores information on books to a struct Book and everything is working fine except for when the book title has any white spaces. So something like Dracula will be stored and displayed just fine, but something like Lord of the Rings will just skip scanning for the rest of the book's information and proceed to close the program. Is there any way to use scanf to register the string with the white spaces? Here's my code:
void addBook(struct Book book[], int *size)
{
if(*size== MAX_BOOKS) {
printf("the inventory is full.\n");
}
else {
printf("ISBN\n");
scanf("%d", &book[*size]._isbn);
printf("Title\n");
scanf("%s", book[*size]._title);
printf("Price\n");
scanf("%f", &book[*size]._price);
printf("Year\n");
scanf("%d", &book[*size]._year);
printf("Qty\n");
scanf("%d", &book[*size]._qty);
printf("Book successfully added to inventory\n");
(*size)++;
}
}
I can update with the full code if necessary.
No problem. That's because %s stops at the first space. Use %[^\n] so it reads until he find the enter.
Related
still making my way through C Programming Absolute Beginner's Guide.
I am at the example about Structures and I cannot figure out what is going wrong. When I compile and run the code, the first two questions run fine, but after it prompts for "How much did the book cost?", when I enter the input for this one, the next two questions get posted together. I have no idea why. I think I have the code written as shown in the book. I have read online that gets is not code but I am not sure why at this point. Any guidance would once again be greatly appreciated!
//This header file defines a structure for information about a book
struct bookInfo {
char title[40];
char author[25];
float price;
int pages;
};
/*This program gets the bookInfo structure by including structurePractice.h
and asks the user to fill in three structures and then prints them*/
//First, include the header file
#include "structurePractice.h"
#include <stdio.h>
int main()
{
int ctr;
struct bookInfo books[3]; //Array of 3 structure variables
//Get information about each book from the user
for (ctr = 0; ctr < 3; ctr++)
{
printf("What is the name of the book #%d?\n", (ctr+1));
gets(books[ctr].title);
puts("Who's is the author? ");
gets(books[ctr].author);
puts("How much did the book cost? ");
scanf(" $%f", &books[ctr].price);
puts("How many pages are in the book? ");
scanf(" %d", &books[ctr].pages);
getchar(); //Clears last newline for next loop
}
//Print a header line and then loop through and print the info
printf("\n\nHere is the collection of books: \n");
for (ctr = 0; ctr < 3; ctr++)
{
printf("#%d: %s by %s", (ctr+1), books[ctr].title, books[ctr].author);
printf("\nIt is %d pages and costs $%.2f", books[ctr].pages, books[ctr].price);
printf("\n\n");
}
return (0);
}
You have a typo in your scanf.
scanf(" $%f", &books[ctr].price);
^
|
here
That says you want a $ followed by a decimal number. If the user does not input a dollar sign, scanf will read nothing. The input will remain on the input buffer. It will be read by the next scanf.
This is one of the many problems with scanf. Because scanf mixes up reading input with parsing input, if the input does not match the expected format it will remain in the input buffer. Instead, read and parse separately with fgets (not gets) and sscanf. It's also important to check that the input was read else books[ctr].price will contain garbage.
// Declare a buffer once outside the loop. Reuse it for each fgets call.
// BUFSIZ is a constant for the natural I/O buffer size of your platform.
char buf[BUFSIZ];
puts("How much did the book cost? ");
// Read only as much as the buffer can handle. This is what makes fgets safe,
// and gets unsafe.
fgets(buf, sizeof(buf), stdin);
// sscanf returns the number of items matched. Check if they all matched.
if( sscanf(buf, " %f", &books[ctr].price) != 1) {
printf("Sorry, '%s' doesn't look like a price.", buf);
// Set it to something or else it will be garbage.
books[ctr].price = 0;
}
A real program would loop until it gets valid input. The important thing is to read the buffer, then parse it, and check if the parsing worked. Later on you might write a little function to package up this prompting code.
When i Compile this program then i can't input book2.title name,
is it fault about using gets funtion then why?
please explain it more ...........................
#include<stdio.h>
#include<string.h>
struct name{
char author[20];
char title[20];
float price;
};
int main()
{
struct name book1,book2;
printf("Enter 1st title name:");
gets(book1.title);
printf("Enter 1st Author name:");
gets(book1.author);
printf("Enter 1st Book price:");
scanf("%f",&book1.price);
printf("\nThe 1st Book Name is %s",book1.title);
printf("\nThe 1st Book Author is %s",book1.author);
printf("\nThe 1st Book Price is %f",book1.price);
printf("\nEnter 2nd title name:");
gets(book2.title);
printf("Enter 2nd Author name:");
gets(book2.author);
printf("Enter 2nd Book price:");
scanf("%f",&book2.price);
printf("\nThe 2nd Book Name is %s",book2.title);
printf("\nThe 2nd Book Author is %s",book2.author);
printf("\nThe 2nd Book Price is %f",book2.title);
return 0;
}
Your code has two problems unrelated to your question:
The use of gets
The use of %f in printf for a string.
However, the behavior leading to your question lies in these two lines:
scanf("%f",&book1.price);
...
gets(book2.title);
Note, when you enter the book1 price (say 12.3) in the terminal, you press enter afterwards. Therefore, the stdin buffer holds the characters 12.3\n. The scanf reads the first few bytes which it can interpret as a float 12.3, leaving the buffer holding \n. Now, when you run gets, it reads the newline, and your 2nd book's title is the blank string "\0".
See this website: https://www.geeksforgeeks.org/problem-with-scanf-when-there-is-fgetsgetsscanf-after-it/
Note: Please, please use fgets/scanf/getline instead of gets. For more information, see the link posted by #RobertS in the comments above.
I'm a beginner and just learning structures in C, but I encountered a small problem. This is the code:
struct Phone{
char name[50];
double screensize;
int memory;
int camera;
};
int main(){
struct Phone phone1;
printf("What model do you have? ");
fgets(phone1.name,50, stdin);
printf("How many MP does the camera have? ");
scanf(" %d", &phone1.camera);
printf("How much memory does you phone have? ");
scanf(" %d", &phone1.memory);
printf("You entered you have: \n");
printf("Model: %s \nCamera: %d \nMemory: %d", phone1.name, phone1.camera, phone1.memory);
}
It doesn't have any errors but, when I run it and input my stuff, the last printf from the code will display the model name, a line of white space, and then the camera and memory on consecutive rows. I want to get rid of that line of white space. I tried to leave a white space in scanf before all %d in order to discard that line, but it doesn't work (I've read that scanf reads the newline when you input something first and, to prevent that, we just need to add a space to flush the buffer first).
Here you input a line from console:
printf("What model do you have? ");
fgets(phone1.name,50, stdin);
it captures also a '\n' character, and then you print:
printf("Model: %s \nCamera: %d \nMemory: %d", phone1.name, phone1.camera, phone1.memory);
// ^ ^ there you print that '\n' in phone1.name and second hardcoded
I am working on my assignment and this is the issue that I bumped into. In the assignment, it says that the input value for the middle initals should be this - "L. A.". However, once I run my program it prints some printf functions on the same line, skipping the scanf function. I have went through a lot of topics about that " %c" issue, but I still can not make my program run properly. Some of the variables are from .h file. The actual assignment is bigger, however it is pretty much repetative so I thought if I figure out how to fix this certain issue I will be able to finally finish my assignment.
int main(void){
// Declare variables here:
char ch;
struct Name FullName = { {'\0'} };
struct Address AddressInfo = { 0, '\0', 0, '\0', '\0' };
struct Numbers PhoneInfo = { {'\0'} };
// Display the title
printf("Contact Management System\n");
printf("-------------------------\n");
// Contact Name Input:
printf("Please enter the contact’s first name: ");
scanf("%s", &FullName.firstName);
printf("Do you want to enter a middle initial(s)? (y or n): ");
scanf(" %c", &ch);
if (ch == 'y') {
printf("Please enter the contact’s middle initial(s): ");
scanf(" %s", FullName.middleInitial);
}
printf("Please enter the contact’s last name: ");
scanf(" %s", &FullName.lastName);
// Contact Address Input:
printf("Please enter the contact’s street number: ");
scanf("%d", &AddressInfo.streetNumber);
OUTPUT (I have highlighted input values):
Contact Management System
-------------------------
Please enter the contactÆs first name: *Artem*
Do you want to enter a middle initial(s)? (y or n): *y*
Please enter the contactÆs middle initial(s): *L. A.*
Please enter the contactÆs last name: Please enter the contactÆs street number:
The %s format specifier reads a sequence of characters terminated by whitespace. When you enter L. A., only L. gets read into middleInitial because it stops reading at the space and A. is left in the input buffer. On the next scanf, it immediately reads those buffered characters so it doesn't stop to prompt for anything.
The simplest way to handle this is to leave out the space when inputting, i.e. L.A.. If you want to support whitespace, you'll want to get rid of scanf entirely and read everything a full line at a time using fgets. Note that fgets also reads in the trailing newline, so you'll need to strip that out.
I want to make a program which take Roll No and Full name as input and simply display it
My code is . this code skip scaning value of n through gets function. Why this error occur and how to over come this?
#include<stdio.h>
#include<conio.h>
void main()
{
int r;
char n[30];
printf("enter your roll no");
scanf("%d",&r);
printf("enter your full name");
gets(n);
printf("roll no is %d ",r);
printf("name is %s ",n);
getch();
}
while the below code scan the first gets value and skips the second one.
#include<stdio.h>
#include<conio.h>
void main()
{
int r;
char n[30], f[30];
printf("enter your roll no");
scanf("%d",&r);
printf("enter your full name");
gets(n);
printf("enter your full name of your father ");
gets(f);
printf("roll no is %d ",r);
printf("name is %s ",n);
printf("father name is %s ",f);
getch();
}
The code DOES NOT skip scanning the value of 'n'.
I believe that when you run the program, you enter the Roll No and then press the ENTER key on your keyboard.
This is the cause.
As soon as you press the ENTER key, the escape sequence '\n' is saved in the array n. Your gets() command is executing perfectly.
In the second case, the variable 'n' stores the escape sequence and the next variable 'f' takes the string you enter next.
To make your code work just enter your scanf statement like this:-
scanf("%d ",&r);
Notice the space after %d.
Try this code-
#include<stdio.h>
int main(void)
{
int r;
char n[30], f[30];
printf("Enter your roll no");
scanf("%d ",&r); // I have inserted a space after %d
printf("Enter your full name");
gets(n);
printf("Enter your full name of your father ");
gets(f);
printf("\nRoll no is %d ",r);
printf("\nName is %s ",n);
printf("\nFather name is %s ",f);
return 0;
}
TIP:- You must try not to use gets() and puts()
You can read more about it here.
The simple solution for the problem is to add fflush(stdin); between scanf(); and gets();
#include<stdio.h>
#include<conio.h>
void main()
{
int r;
char n[30],fn[30];
clrscr();
printf("\nEnter roll ");
scanf("%d",&r);
fflush(stdin);
printf("\nEnter name ");
gets(n);
printf("\nEnter father name ");
gets(fn);
printf("\n\nRoll %d",r);
printf("\nname %s",n);
printf("\nfather name %s",fn);
getch();
}
Using scanf instead of gets will solve your problem:
scanf("%s", n); // Read in your name
Please note that when reading in any string like this you should use safe functions that are passed the length of the string (for example scanf_s from MSDN).
I don't know why it gets skipped but what you could do to avoid any other confusion like fflush(stdin) or fgets etc etc.
Just use gets(string) on the next line. So when it skips the first gets command it goes onto the other one.
Try that
Cheers,
;)
I just had the same problem two hours ago, but to solve this situation easily, all you have to fo is to add a "getchar()" after the "scanf()" and before the "gets()", so that the extra "\n" goes to the "getchar()" and you can type as you want in the next "gets()".
I was also facing the same problem as mentioned above.. so with the help of the answers mentioned here and using hit and trial method, I found that when we press enter after giving input to any variable using scanf(), \n is stored in the next gets() function.. and next time it doesn't take any input from the keyboard.. so to avoid this just use getchar() in between the scanf() nd gets() nd also remember that getchar() takes only 1 character.. so don't give any extra input to scanf() as again this will be stored and will be used in gets() nd the problem will remain the same....
hope this will help..
thank u..