I have the below code. I was thinking I should input only one character at a time. But even if I give a string like hello as input in one line, it accepts correctly. Why is this? Is it related to standard input buffer flushing issue?
#include <stdio.h>
#include <malloc.h>
#include <conio.h>
int main()
{
char sourceString [100];
int index=0;
printf("Enter the characters one by one enter * to stop\n");
do
{
scanf("%c",&sourceString[index]);
index++;
} while (sourceString[index-1]!='*');
index=0;
while (sourceString[index]!='*')
{
printf("%c",sourceString[index]);
index++;
}
printf("\n");
return(0);
}
When you enter a string and press ENTER, the whole string goes into the input buffer stdin.
Next, as per the property of %c format specifier, as mentioned in the C11 standard, chapter ยง7.21.6.2, fscanf()
Matches a sequence of characters of exactly the number specified by the field
width (1 if no field width is present in the directive).
It will match (and scan and store) the first entry (char) in the buffer leaving the rest of the buffer content unchanged.
As you're running the scanf() in a loop, the next call will again go and read from the input buffer ( and continue as long as their is content pending in the stdin buffer).
What's wrong here? It's accepting one character at a time, no matter how many characters there are and putting one character at a time into an array until a condition is met. This is just a (more complicated) way to input a string with an asterisk (*) acting like a null-terminator ('\0').
By the way, you should check the bounds in your first loop. Add something like this or your program will crash with a segfault when the input string gets bigger than 100 characters.
do {
// your code here
} while ((sourceString[index-1]!='*') && (index < 100));
When using scanf you need to terminate the input with a whitespace character(e.g. \n). The scanf will finish reading input when you enter a newline. However since you have a loop it will keep reading input until you enter "*".
Related
How would I scanf an input of "2 & 3"?
Currently, I have it set up as
char expr[10]={};
printf("Enter the expression:");
scanf("%s", expr);
And at the moment it is just grabbing the 2.
With scanf, the entry must be limited to the size of the buffer -1. In your case 9. To include white-space characters we use %[^\n], that means all the characters except '\n', which therefore makes %9[^\n]
#include <stdio.h>
int main(void)
{
char expr[10];
printf("Enter the expression: ");
scanf("%9[^\n]", expr);
puts(expr);
return 0;
}
If you have other entries in a row, you should also purge the keyboard buffer to get out the characters entered in excess and the '\n' which has not been removed.
As manual page described: The input string stops at white space or at the maximum field width, whichever occurs first.
If you want to read a line from console, you can search "c get line" in google, you will get more results.
for example: founction getline()
Why did my scanf function inside while runs only one time?
#include<stdio.h>
#include<stdlib.h>
int main()
{
char s[9999];
while(scanf("%[^\n]s",s)>0)
{
int count=0, prev=0;
for (int i=0;i<strlen(s);i++)
{
if(s[i]==' ')
{
count=i-prev;
prev=i+1;
printf("%c", (char) (96+count));
}
else if(strlen(s)-1==i)
{
count=i-prev+1; printf("%c", (char) (96+count)); }
}
printf(" ");
}}
my test case and output:
Input is considered as a string with a maximum length 1000
Unless you understand scanf, you shouldn't use it. When you understand scanf, you will not use it. There are several problems with
while(scanf("%[^\n]s",s)>0)
scanf will read the input stream, writing characters into the variable s until it sees a newline. It will then try to match a literal s in the input stream. Clearly, the next character is not an s (it is a newline), so the s in the format string does not match. (This is not really a problem, but is certainly bizarre that you have asked scanf to match a literal s when an s is certainly not there. If you had tried to do further matches with something like "%[^\n]s%d", you might be confused as to why scanf never matches an integer. It is because scanf stops scanning as soon as the input stream does not match the format string, and the s in the format string will not match.) On the second iteration of the loop, the first character scanf sees is that newline, so it makes no conversions and returns 0. If you want to discard that newline and are okay with removing leading whitespace, you can simply use " %[\n]" as a conversion specifier. If you do not want to discard leading whitespace, you can discard the newline with " %[\n]%*c" Note that you really ought to protect against overwriting s, so you should use either:
while(scanf(" %9998[^\n]", s) > 0)
or
while(scanf("%9998[^\n]%*c", s) > 0)
Here, during the first iteration, s stores the first line, and at the second iteration s read \n. Since I used %[^\n], scanf will stop scanning.
Now here, the number of elements scanned is zero. So the while loop condition is failed. Hence, the loop is iterated only for one line.
We can change the condition as:
while(scanf("%[^\n]\n",s)>0)
This will skip scanning \n, and desired output is printed.
I write this code, which takes an integer number (t) as input from the user. A loop will be executed just 't' times. But I find that it runs for (t-1) times. For example, if I give input 3, it runs only 2 times. Can anyone please explain why this is happening?
I tried and used scanf("%s", &str), it works, but then I can't take a string as input that contains spaces.
#include <stdio.h>
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
char str[100];
gets(str);
printf("%s\n", str);
}
return 0;
}
scanf("%d", &t) consumes only the numeral in the input stream and leaves the remaining characters. When you enter a numeral and press enter, there is a newline character after the numeral.
The first gets reads this newline and returns a string that is empty except for the newline. The first iteration of the loop prints this blank line.
Loop is iterating 3 times as it should.But it seems that it is iterating 2 times only because of the reason that the \n character left behind by gets in the buffer is read in second iteration.
For first iteration, when you enter a string and the press Enter, the \n character go to the buffer with the string. gets stop reading when it encounters \0, leaving \n in the buffer. On next iteration this \n (non printable character) is read by gets and then printed to terminal.
NOTE: Never use gets function. It is no longer is the part of standard C. Use fgets instead.
I guess you can also use the scanf function to resolve your problem that the string is not accepting anything after a SPACE . Also, the loop is running (t-1) times because the buffer is not being cleared due to the use of gets() . In order to resolve this, you can use the getch() function to clear the buffer. The following code should work I guess,
#include <stdio.h>
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
char str[100];
scanf("%[^\n]c",&str);
printf("%s\n", str);
getch();
}
return 0;
}
In this code, the getch() will clear the buffer by accepting the useless value. Also as far as scanf() is considered, the ^ inside the scanf tells the function that it needs to take the input till the character after the ^ is encountered which in this case is an escape sequence of NEW LINE . I have tried using some small words as well instead of the newline and it has worked as well. Hope this clears your issue :)
I want to execute a statement based on the input of the user:
#include <stdio.h>
#include <string.h>
void main() {
char string_input[40];
int i;
printf("Enter data ==> ");
scanf("%s", string_input);
if (string_input[0] == '\n') {
printf("ERROR - no data\n");
}
else if (strlen(string_input) > 40) {
printf("Hex equivalent is ");
}
else {
printf("Hex equivalent is ");
}
}
When I run it, and just press enter, it goes to a new line instead of saying "ERROR - no data".
What do I do?
CANNOT USE FGETS as we have not gone over this in class.
Use
char enter[1];
int chk = scanf("%39[^\n]%c", string_input, enter);
but string_input will not have a '\n' inside. Your test
if (string_input[0] == '\n') {
printf("ERROR - no data\n");
}
will have to be changed to, for example
if (chk != 2) {
printf("ERROR - bad data\n");
}
use fgets instead of scanf. scanf doesn't check if user enters a string longer than 40 chars in your example above so for your particular case fgets should be simpler(safer).
Can you use a while loop and getch, then test for the <Enter> key on each keystroke?
scanf won't return until it sees something other than whitespace. It also doesn't distinguish between newlines and other whitespace. In practice, using scanf is almost always a mistake; I suggest that you call fgets instead and then (if you need to) use sscanf on the resulting data.
If you do that, you really ought to deal with the possibility that the user enters a line longer than the buffer you pass to fgets; you can tell when this has happened because your entire buffer gets filled and the last character isn't a newline. In that situation, you should reallocate a larger buffer and fgets again onto the end of it, and repeat until either you see a newline or the buffer gets unreasonably large.
You should really be similarly careful when calling scanf or sscanf -- what if the user enters a string 100 characters long? (You can tell scanf or sscanf to accept only a limited length of string.)
On the other hand, if this is just a toy program you can just make your buffer reasonably long and hope the user doesn't do anything nasty.
fgets does what you need. Avoid using scanf or gets. If you can't use fgets try using getchar
The problem is that "%s" attempts to skip white-space, and then read a string -- and according to scanf, a new-line is "whitespace".
The obvious alternative would be to use "%c" instead of "%s". The difference between the two is that "%c" does not attempt to skip leading whitespace.
A somewhat less obvious (or less known, anyway) alternative would be to use "%[^\n]%*[\n]". This reads data until it encounters a new-line, then reads the new-line and doesn't assign it to anything.
Regardless of which conversion you use, you want (need, really) to limit the amount of input entered so it doesn't overflow the buffer you've provided, so you'd want to use "%39c" or "%39[^\n]". Note that when you're specifying the length for scanf, you need to subtract one to leave space for the NUL terminator (in contrast to fgets, for which you specify the full buffer size).
What platform are you running on?
Is the character sent when your press the ENTER key actually '\n', or might it be '\r'? Or even both one after the other (ie. "\r\n").
If I want to receive a one character input in C, how would I check to see if extra characters were sent, and if so, how would I clear that?
Is there a function which acts like getc(stdin), but which doesn't prompt the user to enter a character, so I can just put while(getc(stdin)!=EOF);? Or a function to peek at the next character in the buffer, and if it doesn't return NULL (or whatever would be there), I could call a(nother) function which flushes stdin?
Edit
So right now, scanf seems to be doing the trick but is there a way to get it to read the whole string, up until the newline? Rather than to the nearest whitespace? I know I can just put "%s %s %s" or whatever into the format string but can I handle an arbitrary number of spaces?
You cannot flush the input stream. You will be invoking undefined behavior if you do. Your best bet is to do:
int main() {
int c = getchar();
while (getchar() != EOF);
return 0;
}
To use scanf magic:
#include <stdio.h>
#include <stdlib.h>
#define str(s) #s
#define xstr(s) str(s)
#define BUFSZ 256
int main() {
char buf[ BUFSZ + 1 ];
int rc = scanf("%" xstr(BUFSZ) "[^\n]%*[^\n]", buf);
if (!feof(stdin)) {
getchar();
}
while (rc == 1) {
printf("Your string is: %s\n", array);
fflush(stdout);
rc = scanf("%" xstr(LENGTH) "[^\n]%*[^\n]", array);
if (!feof(stdin)) {
getchar();
}
}
return 0;
}
You can use getline to read a whole line of input.
Alternatively (in response to your original question), you can call select or poll on stdin to see if there are additional characters to be read.
I had a similar problem today, and I found a way that seems to work. I don't know the details of your situation, so I don't know if it will work for you or not.
I'm writing a routine that needs to get a single character from the keyboard, and it needs to be one of three specific keystrokes (a '1', a '2', or a '3'). If it's not one of those, the program needs to send and error message and loop back for another try.
The problem is that in addition to the character I enter being returned by getchar(), the 'Enter' keystroke (which sends the keystroke to the program) is saved in an input buffer. That (non-printing) newline-character is then returned by the getchar() facility in the error-correction loop, resulting further in a second error message (since the newline-character is not either a '1', a '2', nor a '3'.)
The issue is further complicated because I sometimes get ahead of myself and instead of entering a single character, I'll enter the filename that one of these options will request. Then I have a whole string of unwanted characters in the buffer, resulting in a long list of error messages scrolling down the screen.
Not cool.
What seems to have fixed it, though, is the following:
c = getchar(); // get first char in line
while(getchar() != '\n') ; // discard rest of buffer
The first line is the one that actually uses the character I enter. The second line disposes of whatever residue remains in the input buffer. It simply creates a loop that pulls a character at a time from the input buffer. There's no action specified to take place while the statement is looping. It simply reads a character and, if it's not a newline, goes back for the next. When it finds a newline, the loop ends and it goes on to the next order of business in the program.
We can make a function to clear the keyboard buffer, like this:
#include <stdio.h>
void clear_buffer(){
char b;
//this loop take character by character in the keyboard buffer using
//getchar() function, it stop when the variable "b" was
//enter key or EOF.
while (((b = getchar()) != '\n') && (b != EOF));
}
int main()
{
char input;
//get the input. supposed to be one char!
scanf("%c", &input);
//call the clearing function that clear the buffer of the keyboard
clear_buffer();
printf("%c\n",input); //print out the first character input
// to make sure that our function work fine, we have to get the
// input into the "input" char variable one more time
scanf("%c", &input);
clear_buffer();
printf("%c\n",input);
return 0;
}
Use a read that will take a lot of characters (more than 1, maybe 256), and see how many are actually returned. If you get more than one, you know; if you only get one, that's all there were available.
You don't mention platform, and this gets quite tricky quite rapidly. For example, on Unix (Linux), the normal mechanism will return a line of data - probably the one character you were after and a newline. Or maybe you persuade your user to type ^D (default) to send the preceding character. Or maybe you use control functions to put the terminal into raw mode (like programs such as vi and emacs do).
On Windows, I'm not so sure -- I think there is a getch() function that does what you need.
Why don't you use scanf instead of getc, by using scanf u can get the whole string.