How can I enter space bar as input using scanf? [duplicate] - c

This question already has answers here:
How do you allow spaces to be entered using scanf?
(11 answers)
Closed 5 years ago.
I'm writing an fuction and I got a problem, the scanf function cant read spacebar " ", how can I solve it?
void add()
{
char choose2;
FILE *fp;
struct booking book;
system("cls");
fp=fopen("hotelbooking.txt","a");
if(fp == NULL)
{
printf("There are no data file!");
}
else
{
printf("Add New Hotel Booking Record(s)\n");
printf(" Name of Traveller: \n");
scanf("%s",book.travellername);
fprintf(fp,"\n%s",book.travellername);
printf(" Destination: ");
scanf("%s",book.destination);
fprintf(fp,"\n%s",book.destination);
fclose(fp);
}
}
In the tervellername part, If I want to enter e.g. "Jason George", How can I scan the space bar between the name?
I'm using the structure below:
struct booking
{
char travellername[20];
char destination[20];
}book;

scanf() with %s format specifier stops scanning as soon as it hits a whitespace. You cannot scan space using it.
Quoting C11, chapter ยง7.21.6.2,
s Matches a sequence of non-white-space characters.
For a better and robust alternative, you can use fgets() to scan an entire line, terminated by a newline. Remember, in this case, fgets() scans and stores the terminating newline also in the supplied buffer, so you need to manually get rid of it, if that matters.

Try this
scanf("%[^\n]", book.travellername);
Input string will read space separated words and terminate upon encountering a newline character (i.e. \n). Also be Careful that this does not get buffer overflows. so define size of book.travellername accordingly.
update: I have updated the format specifier.

Related

C program won't use printf after scanf [duplicate]

This question already has answers here:
What is the effect of trailing white space in a scanf() format string?
(4 answers)
Why does printf not flush after the call unless a newline is in the format string?
(10 answers)
Closed 2 days ago.
I am new to C and am writing a very simple C program which just provides a input and repeats it back to you. The code shows the first print f which is a $ and lets you input something but will not print the text back to you. Here is the code:
char input[50];
printf("$");
scanf("%s\n", input);
printf("\n %s", input);
I thought it might have been a compile issue but nothing changes. I use make token which is the name of the file.
Remove the "\n" in the scanf() format string. The trailing "\n" instructs scanf() to match any number of white space characters and it will only know when it's done when encountering a non-white space character. Meanwhile you expect it to return after reading the first "\n". Consider using fgets() instead.
#include <stdio.h>
int main() {
char input[50];
printf("$");
scanf("%s", input);
printf("\n %s", input);
}
and example session:
$abc
abc

why %s does not print the string after it encounters a space character? [duplicate]

This question already has answers here:
How do you allow spaces to be entered using scanf?
(11 answers)
Closed 6 years ago.
#include <stdio.h>
int main()
{
char name[20];
printf("Enter name: ");
scanf("%s", name);
printf("Your name is %s.", name);
return 0;
}
Output:
Enter name: Dennis Ritchie
Your name is Dennis.
So far I haven't found any specific valid reason for this question. Can anyone help me out?
scanf only read till it gets to space that is why it is not storing after the first space , so your printf function is not faulty , it is the scanf that is not storing the complete string , stopping on encountering first space.
One should never use gets() , unless they completely know what they are doing , because it does not have buffer overflow protection , it continue to read after the buffer ends until it finds a new line or encounter a EOF. You can read more about that here.Please Check This Why is the gets function so dangerous that it should not be used?
You should instead use fgets().
#include <stdio.h>
int main(){
char name[20];
printf("Enter name: ");
fgets(name,20,stdin);
printf("Your name is %s.", name);
return 0;
}
Remember fgets() also reads newline character(the one you get when you press enter) so you should manually remove that.
Also I highly Recommend this answer for using fgets() to its full potential and avoiding common pitfalls.
This answer tells about using scanf to read string.What it says is the following:
int main(){
char string[100], c;
int i;
printf("Enter the string: ");
scanf("%s", string);
i = strlen(string); // length of user input till first space
do{
scanf("%c", &c);
string[i++] = c; // reading characters after first space (including it)
}while (c != '\n'); // until user hits Enter
string[i - 1] = 0; // string terminating
return 0;
}
How this works? When user inputs characters from standard input, they will be stored in string variable until first blank space. After that, rest of entry will remain in input stream, and wait for next scanf. Next, we have a for loop that takes char by char from input stream (till \n) and appends them to end of string variable, thus forming a complete string same as user input from keyboard.

C program skipping part of function in switch statement. [duplicate]

This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 6 years ago.
I have written a program that is far too long to copy to this site. But what is needed will be pasted into the website.
Here is the switch statement:
void enterName();
int adminChoice;
printf("\nEnter Numeric Choice: ");
scanf("%d", &adminChoice);
switch(adminChoice)
{
case(1):
{
enterName();
}
}
Here is the actual function:
void enterName()
{
FILE *fp = fopen("/home/matthew/Desktop/BBE.txt", "w");
if (fp == NULL)
{
printf("Error opening file!\n");
exit(1);
}
char comment[100];
printf("Enter, String\n");
fgets(comment, sizeof comment, stdin);
fputs(comment,fp);
}
What happens is the program asks for user input of a string. But does not allow for time to put in a desired string. It just ends the program.
The problem is that scanf() leaves a \n character which terminates the fgets() immediately without reading anything. fgets() would stop reading when it sees a newline character or EOF.
You could use a hacky approach and use a getchar(); right before fetgs() call. Better option is to use fgets() to read the adminChoice (and convert it to integer using sscanf() or strto* functions) as well so that you avoid scanf(). In any case, you always have to watch out for newline character when using fgets().

Character is not accepted [duplicate]

This question already has answers here:
C skipping one command of a function? [duplicate]
(2 answers)
Closed 7 years ago.
I've written a C program to count the number of occurrences of an entered character. When I execute,I could only enter the file name.Before I enter the character to be counted , the next statement executes.The output I get is shown below.
Enter the file name
test.txt
Enter the character to be counted
File test.txt has 0 instances of
Here is my code
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE *fp1;
int cnt=0;
char a,ch,name[20];
printf("Enter the file name\n");
scanf("%s",name);
//fp1=fopen(name,"r");
printf("Enter the character to be counted\n");
scanf("%c",&ch);
fp1=fopen(name,"r");
while(1)
{
a=fgetc(fp1);
if (a==ch)
cnt=cnt+1;
if(a==EOF)
break;
}
fclose(fp1);
printf("File %s has %d instances of %c",name,cnt,ch);
return 0;
}
How to resolve this?
It's a common beginners problem, especially when using the scanf family of functions.
The problem is that when you enter the file-name, and press Enter, the scanf function reads the text but leaves the Enter key, the newline, in the input buffer, so when you next read a character it will read that newline.
The solution is very simple: Tell scanf to read and discard any leading white-space by putting a single space in the scanf format:
scanf(" %c",&ch);
// ^
// |
// Note leading space
If you follow the link to the scanf reference it will tell you that almost all formats automatically reads and discards leading white-space, one of the three exceptions is just the format to read single characters, "%c".

storing and printing out elements of structs in C

I have created a simple struct:
struct album {
char title[20];
char artist[20];
};
and later in the program I created an instance a (struct album a;). I only need to ask the user to enter the title and the artist so that I save them in the appropriate place and then print the values:
printf("Please enter your album: \n");
printf("album name: ");
scanf("%.20s", a.title);
fflush(stdin);
printf("artist: ");
scanf("%.20s", a.artist);
printf("======\n");
printf("The album's name is %s and the artist is %s\n", a.title, a.artist);
however when I run this, I get this result:
Part of the input text is lost. What exactly goes wrong here?
scanf reads characters up to white space. So if you are entering Michel Jackson the space in between Michel and Jackson terminates your string so you only get the string Michel.
Try using something like fgets:
fgets(a.artist, 20, stdin);
fgets gets terminates the string on new line rather than white space.
**if you do use fgets make sure to remove the new line character from the end of the string of you do not want a new line character at the end.
With the %s specifier in scanf, the length specifier is the number of characters to write. This differs from most functions which expect the size of the entire buffer.
Since your buffer needs to contain the null terminator, you need to be using "%.19s" here. Another option is to not hardcode the value:
scanf("%.*s", (int)sizeof a.title - 1, a.title);
Note that this only works if a.title is an array (not a pointer), and the cast is necessary because int may be a smaller type than size_t but the * expects int.
As noted by others, %s is for reading up until the next whitespace. You can read up until the next line with %[ , for example:
scanf("%.19[^\n]", a.title);
The ^ means to keep reading until any of the following characters are hit, and \n actually means the newline specifically, not general whitespace.
You will want to flush the buffer after doing this, because the newline will still be in the buffer. However fflush(stdin); is not portable. The portable way to discard the rest of the current line is:
int ch; while( (ch = getchar()) != EOF && ch != '\n' ) { }

Resources