when i m running this code.Code was supposed to ask for second scanf string.But it is printing some garbage value..Please explain this why this is happening??
int main()
{
char arr[50];
int ll;
char sb[20];
printf("enter the string\n");
scanf("%[^\n]s",arr);
printf("string=%s\n",arr);
printf("\n enter sub");
scanf("%[^\n]s",sb);
printf("\n sub-string=%s",sb);
return 0;
}
I haven't tested myself...
scanf("%[^\n]s",arr); stops when it encounters \n
The stdin still holds \n
scanf("%[^\n]s",sb); stops when it encounters the very same \n at the end of the 1st human input
Btw it is a good practice to use the combination of fgets and sscanf instead of scanf.
"%[...]" does not need a trailing 's'.
"%[...]" does not consume leading white-space.
Whenever scanning strings, incorporate width limits.
Check scanf() return value.
char arr[50];
// v--- Space added to consume any white-space including any \n
if (scanf(" %49[^\n]", arr) != 1) Handle_Error();
char sb[20];
if (scanf(" %19[^\n]", sb) != 1) Handle_Error();
In OP's original code, OP is getting garbage because the scanf() did not work. The first "%[^\n]s" likely worked OK, but left a '\n' in stdin for the next IO operation. The 2nd "%[^\n]s" tries to scan that left-over '\n' and since it does not match "%[^\n]", scanf() stopped and put nothing in sb. So uninitialized sb had whatever garbage it started with.
Better yet, use fgets().
Replace:
scanf("%[^\n]s",arr);
...
scanf("%[^\n]s",sb);
With:
scanf("%49s %19s",arr,sb);
Use this code if you do not want to use fgets or sscanf
int main()
{
char arr[50];
int ll;
char sb[20];
printf("enter the string\n");
scanf("%[^\n]s",arr);
fflush(stdin);//to clear \n from the buffer
printf("string=%s\n",arr);
printf("\n enter sub");
scanf("%[^\n]s",sb);
printf("\n sub-string=%s",sb);
return 0;
}
Related
int main(){
char str[10][50],temp[50];
int lim,i,j;
printf("Enter lim: ");
scanf("%d",&lim);
for(i=0;i<lim;++i){
printf("Enter string[%d]: ",i+1);
gets(str[i]);
}
Here the str[0](Enter string[1]: ) can't be read. The reading starts from 'Enter string[2]: '(str[1]).
But if instead of lim, an integer is passed to loop as below, program executes correctly. What may be reason for this scenario ?
int main(){
char str[10][50],temp[50];
int lim,i,j;
for(i=0;i<5;++i){
printf("Enter string: ");
gets(str[i]);
}
Your scanf() for the number has left a newline in the input stream, which will feed the first gets().
Have a look here for help:
http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html
How to read / parse input in C? The FAQ
Also, you do not want to use gets() anymore.
Why is the gets function so dangerous that it should not be used?
Firstly don't use gets() use fgets() instead. From the manual page of gets()
Never use gets(). Because it is impossible to tell without knowing the
data in advance how many characters gets() will read, and because
gets() will continue to store characters past the end of the buffer,
it is extremely dangerous to use. It has been used to break computer
security. Use fgets() instead.
Secondaly stdin is line buffered, when you use scanf() like scanf("%d",&lim); and press ENTER, the newline \n char is left into stdin stream that causes gets() to not to read str[0].
For e.g
for(i=0;i<lim;++i){
printf("Enter string[%d]:\n ",i);
fgets(str[i],sizeof(str[i]),stdin);
}
Also note that when you use fgets() it will store \n into buffer at the end. If you don't want \n at the end of str[index] you have to remove it.
Also don't Forget to check the return value of fgets().
For e.g
char *ptr = NULL;
ptr=fgets(str[i],sizeof(str[i]),stdin);
if( ptr != NULL && str[strlen(str[i])-1] == '\n'){
str[strlen(str[i])-1] = '\0'; /* replace \n with \0 */
}
When i use gets separately this works. But, when i use scanf in my program it does not work. Can anyone explain what I've missed?
#include <stdio.h>
#include <stdlib.h>
int main(){
char a[]="computer";
char b[]={'p','c','\0'};
char c[30];
char d[30];
printf("a=%s,b=%s\n",a,b);
printf("enter a word\n");
scanf("%s",c);
printf("%s",c);
printf("enter a sentence\n");
gets (d);
printf("%s",d);
return 0;
}
gets doesn't skip the white-space characters before starting to read the string while scanf does.
After your first input, there is \n character in the buffer left behind by first scanf call. This \n is read by gets but scanf skips this white-space character.
this can be solved by using a getchar statement after the scanf call.
printf("enter a word\n");
scanf("%s",c);
getchar();
Do not use gets neither scanf (they do not check array bound), instead use fgets.
printf("enter a word\n");
fgets(c, 30, stdin);
printf("%s",c);
printf("enter a sentence\n");
fgets(d, 30, stdin);
printf("%s",d);
Scanf leaves behind "\n"(without quotes) and then gets() function reads only it.
scanf("%s",c) left the Enter or \n in stdin. When gets() executed it consumed that and returned an empty string. gets() reads in all data up to the \n and trims it off before returning.
The format specifiers like %d %s, etc. (all except %n %c %[) and the whitespace format directives like " " direct scanf() to skip leading whitespace. scanf() itself does not skip leading whitespace.
Suggest using fgets() and avoid using gets().
char buf[100];
printf("enter a word\n");
fgets(buf, sizeof buf, stdin);
sscanf(buf, "%29s", c); // 29 because c is size 30
printf("%s\n",c);
printf("enter a sentence\n");
fgets(d, sizeof d, stdin);
printf("%s",d);
scanf removes whitespace automatically from before the datum it's trying to get. An exception to this is the character formats (primarily %c), which don't remove whitespace. However, scanf leaves whitespace after the datum. Therefore, you'll need a way to get rid of that. Use
getc(stdin);
you can then continue on your merry way. This page has more documentation on getc.
scanf("%d %c",&size,&chara); works but separate scanf for character input does not work. I show these inside the code. Why is that?
void squareCustomFill(int size, char chara);
int main(void) {
int size,i,k;
char chara;
printf("Enter size of square: "); //This works
scanf("%d %c",&size,&chara);
//printf("Enter fill character: "); BUT WHY DOES NOT THIS WORK??
//scanf("%c",&chara);
squareCustomFill(size,chara);
return 0;
}
void squareCustomFill(int size, char chara){
int i,k;
for (k=1;k<=size;k++){
for(i=1;i<=size;i++)
printf("%c",chara);
printf("\n");
}
}
Scanf did not consume the \n character that stayed in the buffer from the first scanf call.
So the second scanf call did.
You have to clear the stdin before reading again or just get rid of the newline.
The second call should be
scanf(" %c",&chara);
^ this space this will read whitespace charaters( what newline also is) until it finds a single char
Yes I believe Armin is correct. scanf will read in whitespace (spacebar, newline, etc.). When you're inputting values if you click the space bar or enter right after the first scanf, the second scanf will read in that value (space, newline, etc.). So you fixed that with scanf("%d %c",&size,&chara) because there is a space between %d and %c. If you want them separate just do what Armin suggested: scanf(" %c",&chara).
Throw a getchar() in between them and slurp up that extraneous newline.
I am having trouble with inserting string in to char variable. Problem appeares when I put it into function. When I debug my program, it displays printf but it skipes gets
here is my code:
int uloz(SPRAVA *p){
char string[200];
printf("Your message here: ");
gets(string);
printf("You have entered: %s", string);
getchar();
return 0;
}
Use scanf(" %30[^\n]%*c",string);
[^\n] will accept anything till \n.
30 will limit the length of number of characters to max 30.
initial space(' ') will consume any \n already in stdin stream. (optional & i have not verified it)
& Finally, %*c will consume \n pressed after entering string.
I think, scanf(" %30[^\n]%*[^\n]%*c",string); would be a good option, to discard remaining characters (after 30) that were entered. However this is completely unverified. Just added as a possible idea. Test before use. :-)
There's a newline in the stdio buffer (left over by some previous scanf) so gets is immediately satisfied.
There's no easy way to fix it but you could try discarding input, before the fgets:
while((c = getchar()) != '\n' && c != EOF)
/* discard the character */;
The true solution is to avoid mixing scanf and fgets.
Use fgets instead of gets.
I am trying to take five character and 5 float input.
main()
{
char c[5];
float q[5];
int i;
for(i=0;i<5;i++)
{
printf("\n%d ",i);
scanf("%c",c+i);
scanf("%f",q+i);
}
}
But the output is absurd. After two sequential scans, it skips third scan and then again skips fifth scan.
I am not able to understand why is it showing such a behaviour.
I am working on gcc compiler.
Use of scanf is not recommended because of problems like this.
Instead use fgets to read the entire line and then use sscanf to extract what you want(a char or a float) from the line just read:
char line[MAX];
for(i=0;i<5;i++)
{
if( fgets(line,MAX,stdin) && sscanf(line,"%c", c+i)!=1 )
*(c+i) = 0;
if( fgets(line,MAX,stdin) && sscanf(line,"%f", q+i)!=1 )
*(q+i) = 0.0;
printf("%c %f\n",*(c+i),*(q+i));
}
To directly answer why the 3rd and every other scan "skips", it is the way scanf() and the %c format works. When there is a call to scanf(), you typically have to press enter to "submit" the input. Consequently that inserts a newline character into the stdin stream.
When the previous float scan got inputted, the newline is still left in the stream. When the character scan gets reached, that remaining newline character is read in since it fits effectively "skipping" the call.
You should use fgets() with sscanf() as codaddict suggests.
But as a quick fix, you could try adding a call to getchar() after the float scan to consume that newline character from the stream.
edit:
You're saying this doesn't work? (assuming you input the correct kinds of values, one per scanf call)
main()
{
char c[5];
float q[5];
int i;
for(i=0;i<5;i++)
{
printf("\n%d ",i);
scanf("%c",c+i);
scanf("%f",q+i);
getchar();
}
}
You should try this:
int main(){
char c[6];//char array size must be 6 to store five charecter
//as null-terminator('\0')will use the last one
float q[5];
int i;
for(i=0;i<5;i++){
printf("\n%d\n",i);fflush(stdout);
scanf("%c",&c[i]);fflush(stdin);//fflush(stdin) to clear input stream that
//next scanf() won't skip
scanf("%f",&q[i]);fflush(stdin);//fflush(stdin) to clear input stream that
//scanf() won't skip at new loop
}
return 0;
}
fflush() is not defined on an input stream, like stdin. Don't do it.
If you want to "read and discard until newline", then do:
int ch;
do {
ch = getchar();
} while (ch != EOF && ch != '\n');
Note that %c means "read the next character in the input stream, even if it's whitespace, then stop". %f means "read and discard whitespace, then try to read a float from the input stream, then stop."
Your code should be like this :
main()
{
char c[5];
float q[5];
int i;
for(i=0;i<5;i++)
{
printf("\n%d ",i);
scanf("%c",c+i);
while (getchar()!='\n');
scanf("%f",q+i);
while (getchar()!='\n');
}
}
the sentence while (getchar()!='\n'); search till the end of input, so it would not take '\n' as an input value for q+i.Also another while (getchar()!='\n'); after scanf q+i,since you use loop.
Problem in scanning a char value after a float value.
Solution is very simple!!!
instead of writting your code like this
scanf("%c",&...)
try this,
scanf(" %c",&...)
A Space before the"%c" will resolve the problem by neglecting the value of the Return(Enter) key when pressed after typing the value of the float as an input.
When a float value is scanned before a character value.
The value obtained by pressing the Return(Enter) key is collected in the following char variable. Using a space before(" %c",&...) discards the value collected of the Return(Enter) Key, Causing the Char value to be scanned in the next line. Thus solving The Scanning Float-Char problem.