This is simple code. In which I am taking a input, printing it, and taking again and printing it once more.
For the second time it doesn't let me give the input.
Can someone explain why ?
#include "stdio.h"
int main()
{
char buff[50];
printf("Enter a String\n");
scanf("%[^\n]s",buff);
puts(buff);
printf("Enter another String\n");
scanf("%[^\n]s",buff);
puts(buff);
return 0;
}
Output :
Enter a String
Hello // This I have entered
Hello // This is the output
Enter another String
Hello // This I haven't entered, It automatically takes this.
In the second scanf(), place a space at the beginning of your input specifier:
scanf(" %[^\n]s",buff);
^^^
This will eat the character that is currently satisfying scanf the second time, and allow you to enter a second string.
Using a different format helps
// scanf("%[^\n]s",buff);
scanf(" %49[^\n]",buff);
// ^ no s
// ^ width limit
// ^ consume previous line's leftover \n (and all white-space)
Note that scanf(" %[^\n]",buff); does not change buff when user enters only " \n".
But better to use fgets()
fgets(buff, sizeof buff, stdin);
buf[strcspn(buffer, "\n")] = 0; // to remove \n
Related
I know that adding a space in front of %c in scanf() will scan my second character; however, if two letters were inputted in the first character, it will input the second letter into the second character. How do I scan a single character only?
#include <stdio.h>
int main(void)
{
char firstch, secondch;
printf("Enter your first character: ");
scanf("%c", &firstch);
printf("Enter your second character: ");
scanf(" %c", &secondch);
printf("\n Fisrt character : %c \n Second character : %c \n", firstch, secondch);
return 0;
}
This is my result after running:
Enter your first character: ab
Enter your second character:
First character : a
Second character : b
I only want to read the first character 'a', but the second letter 'b' was inputted right away before I enter my second character.
When you are reading a line of user-input, use a line-oriented input function like fgets() or POSIX getline(). That way the entire line of input is read at once and you can simply take the first character from the line. Say you read a line into the array used as buffer called buf, e.g.
#define MAXC 1024 /* if you need a constant, #define one (or more) */
int main (void) {
char buf[MAXC]; /* buffer to read each line into */
You can simply access the first character as buf[0], or since buf[0] is equivalent to *(but + 0) in pointer notation, you can simply use *buf to get the first character.
As a benefit, since all line-oriented functions read and include the '\n' generated by the user pressing Enter after the input, you can simply check if the first character is '\n' as a way of indicating end-of-input. The user simply presses Enter alone as input to indicate they are done.
Using a line-oriented approach is the recommended way to take user input because it consumes and entire line of input each time and what remains in stdin unread doesn't depend on the scanf conversion specifier or whether a matching failure occurs.
Using " %c%*[^\n]" is not a fix-all. It leaves the '\n' in stdin unread. That's why you need the space before " %c". Where it is insidious is if your next input uses a line-oriented function after your code reading characters is done. Unless you manually empty the '\n' from stdin, before your next attempted line-oriented input, that input will fail because it will see the '\n' as the first character remaining in stdin.
A short example using fgets() for a line-oriented approach would be:
#include <stdio.h>
#define MAXC 1024 /* if you need a constant, #define one (or more) */
int main (void) {
char buf[MAXC]; /* buffer to read each line into */
for (;;) { /* loop continually */
fputs ("enter char: ", stdout); /* prompt for input */
/* read/validate line, break on EOF or [Enter] alone */
if (!fgets (buf, sizeof buf, stdin) || *buf == '\n')
break;
printf (" got: %c\n\n", *buf); /* output character read */
}
}
Where you simply take input continually isolating the first character as the value you want until the user presses Enter alone to break the read-loop.
Example Use/Output
$ ./bin/fgetschar
enter char: a
got: a
enter char: ab
got: a
enter char: a whole lot of stuff you don't have to deal with using fgets()
got: a
enter char: banannas
got: b
enter char: cantelopes
got: c
enter char:
Look things over and let me know if you have further questions.
Using a space before the %c will skip whitespace before scanning the next non-whitespace character. %c itself just scans a single character -- the next character in the input after whatever else was scanned or skipped previously.
So the question is, what do you want to do? Do you want to skip over all extraneous input on the line after the first character (up to newline?) fgets or scanf("%*[^\n]"); scanf("%c"); will do that (but be careful -- if firstch was itself a newline, this will skip the next line.) Do you want to check the input and make sure it is exactly one character on a line? If so, use fgets (not scanf) and check that the line read is exactly two characters (a character and a newline). Or perhaps you really want to read keystrokes without having the user hit Enter after esch one? That requires changing the input source setup, which is OS dependent.
I'm still new to C coding, and I've found a suitable answer to my problem by using scanf("%*[^\n]");
#include <stdio.h>
int main(void)
{
char firstch, secondch;
printf("Enter your first character: ");
scanf(" %c%*[^\n]", &firstch);
printf("Enter your second character: ");
scanf(" %c%*[^\n]", &secondch);
printf("\n First character : %c \n Second character : %c \n", firstch,
secondch);
return 0;
}
Results after running:
Enter your first character: ab
Enter your second character: c
First character : a
Second character : c
Thanks to #Eraklon #Chris Dodd #David C. Rankin
I was fiddling with C and happen to wrote code below. When I input a string with spaces, program receives all of the input but outputs them as if they were inputted as single words at different times. I thought scanf stopped when first whitespace character is encounterd and ignored the rest. But that seems, is not the case.
I included the output when I enter "inputWithNoSpaces" and "input with spaces", below.
I tried to look into stdin. It receives all the input. But I could not figure out what scanf was doing. I would like to learn what is happening.
Code:
#include <stdio.h>
int main()
{
int i=0;
char word[64]="";
while(1)
{
printf("enter string:");
scanf("%s",word);
i++;
printf("%d:%s\n\n",i,word);
}
return 0;
}
Output:
enter string:inputWithNoSpaces
1:inputWithNoSpaces
enter string:input with spaces
2:input
enter string:3:with
enter string:4:spaces
enter string:
In scanf(), "%s" means "skip whitespace characters then read a sequence of non-whitespace characters". So when you give it the input input with spaces it will return "input", "with" and "spaces" in three sequential calls. That is the expected behavior. For more information read the manual page.
input with spaces
^^^^^ First scanf("%s", s) reads this
^ Second scanf("%s", s) skips over this whitespace
^^^^ Second scanf("%s", s) reads this
^ Third scanf("%s", s) skips over this whitespace
^^^^^^ Third scanf("%s", s) reads this
The program is to compare the string but however there's a problem with the spacing when I execute it. As I input the first string with spacing, the program just jump to comparing the strings, not allowing me to input the second string as follows:
>>"Enter first string":
"Hello Hey"
">>Enter second string:"
">>First string is more than the second string."
Here is my code:
#include<stdio.h>
#include<string.h>
int main (void) {
int result; //store results
char input1[50];
char input2[50];
printf("Enter first string:\n");
scanf("%[^\n]s",input1);
printf("Enter second string:\n");
scanf("%[^\n]s",input2);
result = strcmp(input1, input2);
if (result==0)
printf("First string is equal to second string\n");
if (result>0)
printf("First string is greater than second string\n");
if (result<0)
printf("First string is less than the second string\n");
return 0;
}
Add spaces:
scanf(" %[^\n]s",input1);
scanf(" %[^\n]s",input2);
It will consume all the white spaces encountered in previous inputs.
When you enter any input, you also enter a new line character (white space) with your input. And that newline character is being read by second scanf in your code.
The Question:
How do I allow spaces to be read during execution? (the question)
You are already doing it using [^\n] in scanf("%[^\n]s",input1); which means to read the input until a new line (\n) is encountered. Also, not that \n itself doesn't get read in this way.
Output:
Enter first string:
Strings in C
Enter second string:
Strings in C
First string is equal to second string
I think you can do it with the stdlib.h with this function:
gets(input1);
gets(input2);
For sure, the POSIX way will work, you can use read to get the line from stdin:
read(STDIN_FILENO, input1, 50)
I am using GCC to compile my C code.
My second scanf is not stopping to get the input.
It only reads in the first scanf and prints the two statements, one with what I entered in string and the other is just blank.
int main (void) {
setvbuf(stdout, NULL, _IONBF, 0);
char string[25] = {'\0'};
char c;
scanf(" %s", string);
scanf(" o%c", &out);
printf("Input is : %s \n\n", string);
printf("Out is: %c", out);
return 0;
}
Instead of getting
Input is whatever I typed and a prompt to enter a char for out
I got output as shown below
Input is : whatever i typed
Out is:
The program terminates. Can someone help. I've done some research and tried to put a space before %c for out and for string and still nothing happened.
You haven't defined out. And c is unused here. Having said that
Change
scanf(" o%c", &out); //What is that o in here? Is it a typo?
to
scanf(" %c", &out);
If your terminal uses line-buffered input
scanf(" %s", string);
can read the input till the first white-space. So the input buffer from the white-space is unused which is available for the next scanf which automatically starts reading from the buffer. So if you enter a string with spaces, the white-space will be assigned to the character out in your case
Change first scanf like below to clear the buffer:
if( scanf(" %s", string) == 1)
{
while(getchar()!='\n')
continue;
}
Also you might wish to replace
scanf(" %s", string);
with
fgets(string,25,stdin);
/* Use 26 if you actually wish to have max 25 characters
* ie char string[26]={'\0'}
*/
fgets has the advantage that it can read the white spaces and the newline charcter '\n' and it will automatically trim the output in case of an overflow.
I checked here and there and wasted around 3 hours checking for a solution. My program just infinite loop itself. Here is my C program:
#include <stdio.h>
#include <string.h>
int main (void)
{
int attempts = 0;
char password[10];
do
{
printf("Enter your password:\n");
scanf("%[^\n]s", password);
printf("\n");
attempts++;
} while (strcmp(password, "awesome 123 ok"));
printf("You entered a correct password in %d attempts!", attempts);
return 0;
}
I tried scanf("%[A-Za-z0-9 ]s", password)"so it can take all characters and numbers including space as an input but it just loop. And I also tried using getchar() but it asks for password again and again even if I enter the correct one. Any help will be appreciated.
Size of awesome 123 ok is 15 including \0. But you are allocating memory for 10 bytes. It causes undefined behavior.
When you are using %[^\n] format specifier no need to use s with that, It will automatically scan the spaces also.
Try the following changes-
int main (void)
{
int attempts = 0;
char password[20]; // Fix 1
do
{
printf("Enter your password:\n");
scanf("%[^\n]", password); // Fix 2
printf("\n");
attempts++;
} while (strcmp(password, "awesome 123 ok"));
printf("You entered a correct password in %d attempts!", attempts);
return 0;
}
You declare char password[10]; but you compare it with awesome 123 ok which has more characters.
From this scanf (and family) reference:
All conversion specifiers other than [, c, and n consume and discard all leading whitespace characters before attempting to parse the input.
That means that the trailing newline (a whitespace character) will be included in the next call to scanf in the loop.
The solution is simple: Tell scanf to read and discard leading whitespace:
scanf(" %[^\n]", password);
/* ^ */
/* | */
/* Note leading space */
Also note that I removed the trailing s in the format, because that tells scanf to expect a literal s in the input. The "%[" format ends with the closing ']'.
You also might want to limit the number of characters read so you don't overflow the buffer you read into:
scanf(" %9[^\n]", password);
Note that the above format set the maximum field width as nine characters, because the buffer needs to include the terminating '\0' character as well. Modify this number if you increase the buffer size, but remember that it should be (at most) one less than the buffer size.
Change the dec password[10] to password[20]
I would use fgets because it is a safer way than gets or scanf:
#include <stdio.h>
#include <string.h>
int main (void) {
int attempts = 0;
char password[20];
do {
printf("Enter your password:\n");
fgets(password, sizeof(password), stdin);
password[strlen(password) - 1] = '\0';
printf("\n");
attempts++;
} while (strcmp(password, "awesome 123 ok"));
printf("You entered a correct password in %d attempts!", attempts);
return 0;
}
Now, this will only work if you increase the size of password[] as I did in my example. When not using fgets it might still work in a bad way because you are comparing a buffer overflow.
The issue is that password is too narrow. Because of this, the program routinely writes past the end of the array, resulting in undefined behaviour.
You can fix this by making password wider. However, your program will still be open to stack smashing: an attacker can potentially execute arbitrary code by entering a long carefully crafted password string.
To fix that, you need to change the scanf() format specifier to limit how many characters it can store in password.
The following changes will fix both:
char password[32]; /* more space: 31 characters + NUL */
do {
...
scanf("%31[^\n]%*c", password); /* format specifier */
The latter will make sure you're never reading more than 31 characters into password; it also consumes the newline without storing it.
Add getchar() to consume the \n character. Find the modified code in below.
int main (void)
{
int attempts = 0;
char password[10];
do
{
printf("Enter your password:\n");
scanf("%[^\n]s", password);
getchar (); // Fix1
printf("\n");
attempts++;
} while (strcmp(password, "awesome 123 ok"));
printf("You entered a correct password in %d attempts!", attempts);
return 0;
}
The array password is not used properly in your code. So change the logic for it. User can enter N numbers of character. So restrict the user input to limited character or use dynamic memory allocation