>actually i do not know why, do they produce different results?
They can. scanf is unique in how it handles whitespace. A newline is taken to be whitespace, so plenty of people (even experienced C programmers) have trouble with scanf and string data. The most common problem being something like this:
scanf stops reading at whitespace and leaves the resulting newline character in the input stream. Since fgets stops reading at a newline and the first character it reads is the leftover newline from scanf, it appears as if the call to fgets is skipped completely. Some people like to add a space in the format string of scanf since a space tells scanf to read a length of whitespace. This of course is a hack that rarely works as planned. Other hacks include
fgets(s, sizeof (s), stdin);
fflush(stdin); /* Undefined */
and a better (if cryptic) use of scanf to remove extraneous characters from the stream and then eat the newline if scanf succeeded:
while (getchar() != '\n')
Note the 99 added to mark the maximum length of acceptable input. This is a good idea in any situation because the vanilla %s format flag is open to buffer overrun if there's too much input.
if (scanf("%99s%*[^\n]", s) >= 0)
All of this should tell you that it's usually better to avoid scanf completely and use fgets for all of your interactive input needs. Then you can use a host of parsing techniques (such as sscanf which doesn't suffer the problems of scanf).