I'm new to C, I have lines of code look like this:
char user[16];
fgets(user,16,stdin);
I typed "zeyang" on the keyboard, and I have another code:
char pwname[1000];
pwname="zeyang";
Then I use strcmp to compare user and pwname:
strcmp(user, pwname);
The return value is a negative number, I expect it to be 0, because they are all "zeyang". Why it isn't 0?
fgets includes the typed newline if there's room. You're comparing "zeyang\n" with "zeyang". From the fgets(3) man page:
The newline, if any, is retained.
The first string coming from stdin contains an additional newline character.
The problem is that the sentence you enter will be terminated by a new line character. (I guess you pressed ENTER when you have finished to insert characters. :D
In this case I would use strncmp :
strncmp(user,pwname,strlen(pwname));
This code won't compare the new line character.
Related
Well I've been programming in C for quite a while now, and there is this question about the function scanf()
here is my problem:
I know that every element in ASCII table is a character and I even know that %s is a data specified for a string which is a collection of characters
My questions:
1.why does scanf() stops scanning after we press enter. If enter is also character why cant it be added as a component of the string that is being scanned.
2.My second question and what I require the most is why does it stops scanning after a space, when space is again a character?
Note: My question is not about how to avoid these but how does this happen
I'd be happy if this is already addressed, I'd gladly delete my question and even if I've presumed something wrong please let me know
"why does scanf() stops scanning after we press enter." is not always true.
The "%s" directs scanf() as follows
char buffer[100];
scanf("%s", buffer);
Scan and consume all white-space including '\n' generated from multiple Enters. This data is not saved.
Input white-space characters (as specified by the isspace function) are skipped, unless the specification includes a [, c, or n specifier C11dr §7.21.6.2 8
Scan and save all non-white-space characters. Continue doing so until a white-space is encountered.
Matches a sequence of non-white-space characters §7.21.6.2 12
This white-space is put back into stdin for the next input function. (OP's 2nd question)
A null character is appended to buffer.
Operations may stop short if EOF occurs.
If too much data is save in buffer, it is UB.
If some non-white-space data is saved, return 1. If EOF encountered, return EOF.
Note: stdin is usually line buffered, so no keyboard data is given to stdin until a '\n' occurs.
From my reading of your question, both of your numbered questions are the same:
Why does scanf with a format specifier of %s stop reading after encountering a space or newline.
And the answer to both of your questions is: Because that is what scanf with the %s format specifier is documented to do.
From the documentation:
%s Matches a sequence of bytes that are not white-space characters.
A space and a newline character (generated by the enter key) are white-space characters.
I made miniprogram with scanf for get multiple name without stop on space or ever enter.
i use while
Scanf("%s",text);
While (1)
{
Scanf("%s",text1)
If (text1=='.'){break;}
//here i simple add text1 to text
}
This way i get one line if use the .
Now i use
scanf("%[^\n]",text);
It work great.
I'm using strstr() function to search a string given by the user in some other string.
Problem is that when I use fgets() to take input, the strstr() function is giving zero(false) even if the string entered by user is there.
For Example:
char search[20]; //MAX size of search term is 20 bytes
puts("Enter search term: ");
fgets(search,20,stdin); //suppose user enters: photographer (12 characters long)
if(strstr("I'm no photographer but I can picture us together",search))
puts("Found!");
else
puts("No luck!");
Output: No luck!
Even tough "photographer" is there in the string
However, if I use scanf() to take search input.
scanf("%19s",search); //like this
Output: Found!
Why is this happening ?
This is happening because fgets() stores a trailin newline \n at the end of the string read. So the string you read in search is basically "photographer\n"
Either use scanf() or overwrite a null character \0 on the newline.
To overwrite on the newline, you can do something like this
l=strlen(search)-1;
if(search[l]=='\n')
search[l]='\0';
from the manual:
fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A terminating null byte ('\0') is stored after the last character in the buffer.
beware that none of those functions are safe to use because they don't check the size of the buffer.
I found a nice example of how to use strcmp, but it's only working with fgets(), and i need to make it work with scanf. So, here's the code:
int main(void) {
char fruit[] = "apple\n";
char ans[80];
do {
printf ("Guess my favorite fruit? ");
scanf ("%s",ans);
} while (strcmp (fruit, ans) != 0);
puts ("Correct answer!");
return 0;
}
Even when I write the correct answear ("apple") it stays in the loop and keeps asking me what is the favorite fruit... I'm guessing it has something to do with the chars that are not written at ans[80](I need it to be a char array with 80chars at max). I'm not getting this...
Thanks in advance.
Scanf will ignore "\n", so you should init char fruit[] = "apple", since ans will never end with '\n'.
P.S: An explain for scanf: Any number of non-whitespace characters, stopping at the first whitespace character found. A terminating null character is automatically added at the end of the stored sequence.
scanf() does not write the trailing newline character(s) into ans. strcmp() does consider newline characters in its comparison, so it's not matching your literal, which includes the newline.
"scanf" does take newline "\n" character as input. So you are not able to equal the both strings. if you want to equal both strings you need to remove newline"\n" form the first string ("apple" is fine).
i have a piece of code in C .But i am not able to understand its output
#include<stdio.h>
main()
{
char a1[20];
char a2[30];
char a3[40];
scanf("%s",&a1);
gets(a2);
fgets(a3,sizeof(a3),stdin);
printf("%d,%d,%d\n",strlen(a1),strlen(a2),strlen(a3));
}
When i enter my input like
amit
singh
output comes out to be 4,0,6 and fgets doest not allow me to enter any string ,i am able to enter only 2 inputs?
input is "amit\nsingh\n"
the scanf consumes "amit" (and writes that into a1)
the gets consumes "\n" (and writes empty string to a2)
the fgets consumes "singh\n" (which it writes to a3)
The output is correct.
Do not EVER use gets!
http://pubs.opengroup.org/onlinepubs/9699919799/functions/fscanf.html
http://pubs.opengroup.org/onlinepubs/9699919799/functions/gets.html
http://pubs.opengroup.org/onlinepubs/9699919799/functions/fgets.html
scanf() takes amit and stores it in array a1.
Since functions of the scanf() family leave the newline character in the input buffer and gets() reads up to a newline character (which it finds immediately), it stores an empty string into a2.
So the call to fgets() reads singh into a3. fgets() puts also the newline character into the target variable - this is why you see 6 characters as string length for a3.
Since there are no more input commands, no 3rd line is read.
scanf leaves a '\n' in the stream which is read by gets.
gets doesn't count \n in the length. Hence you get a 0 there.
Then your fgets reads "singh" and as it does take into account the newline character, it outputs 6.
Have a look at the following references for better understanding:
http://www.cplusplus.com/reference/clibrary/cstdio/fgets/
http://www.cplusplus.com/reference/clibrary/cstdio/gets/
Take for instance:
printf("Continue?\n>>");
scanf("%d", &cont);
getchar();
Normally I add the getchar() to prevent the program from infinite looping (reading off the '\n' character from the buffer). However, when used with a menu following this statement the extra characters are read in and any scanfs following the character input (up to the number of characters input) are skipped.
What I want to figure out is how to prevent it from skipping forward through several sections of my program when it reads in a type of input other than an int. Would this be best solved by putting it inside of a loop that won't continue until the variable is in the expected domain?
Consider using fgets and sscanf instead. Load a line's worth of input, then parse only that line instead of the entire stdin.
Check the value returned by scanf. The return value indicates the number variables that were assigned to. If you're expecting an int and the user types in a character, scanf should return zero.
Try including a "%*s" input specifier. See http://www.cplusplus.com/reference/clibrary/cstdio/scanf/
Instead of reading an integer, just read a string and convert it to a number (atoi). Two problems that may occur:
Char buffer not big enough. To prevent this you can read char by char from the input and realloc the buffer if necessary.
String is not a number. Atoi will return some default value (0 or -1, don't remember). You just have to check the string somehow.