• RSS
  • Twitter
  • FaceBook

Security Forums

Log in

FAQ | Usergroups | Profile | Register | RSS | Posting Guidelines | Recent Posts

fgets function discrepancy

Users browsing this topic:0 Security Fans, 0 Stealth Security Fans
Registered Security Fans: None
Post new topic   Reply to topic   Printer-friendly version    Networking/Security Forums Index -> Programming and More

View previous topic :: View next topic  
Author Message
LrB113
Just Arrived
Just Arrived


Joined: 07 Jan 2010
Posts: 0


Offline

PostPosted: Thu Jan 07, 2010 3:31 am    Post subject: fgets function discrepancy Reply with quote

I was creating an app in C and it was supposed to ask a user select one of two choices. Either enter a name string or recite the alphabet. When you select the first option, to enter a string and then repeat it out back, it will not work. What happens is that it will ignore the fgets statement that is supposed to pickup the string that you are to enter into the program. Below is the code that I am using for this app.

****************************************************************

Code:
#include <stdio.h>
#include <stdlib.h>

int i, j, k, m;
float jake;
char cake[] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
char fname[101];



int main(int argc, char *argv[])
{
   
   
     
printf("Select an option: \n");
printf("-----------------\n");
printf("1.) Recite the name you entered:\n");
printf("2.) Recite the alphabet\n\n");

scanf("%i", &k);

if ( k == 1 ){
     
     printf("Please enter a name: \n");
   
     fgets(fname, sizeof(fname), stdin);
   
     printf("The name you entered is: \n");
     
     m = strlen(fname);
 
     for ( i = 0; i < m; i++){
         printf("%c", fname[i]);
         }
         
     }
     else if ( k == 2 ){
          printf("You want to see the Alphabet?, here you go....\n\n");
          for ( i = 0 ; i < 26; i++){
              for ( j = 0; j < 250000000; j++);
              printf("%c \n", cake[i]);
              }
          printf("\n");
          printf("That is it.\n");
          }
          else if ( k != 1 && k != 2){
               printf("Since you gave a response that I do not understand, I cannot give you anything!\n\n");
               }

 
  system("PAUSE");   
  return 0;
}



*************************************************************
Does anyone know why this is not working? Thank you.

Moderator note: edited to add code tags - capi
Back to top
View user's profile Send private message
capi
SF Senior Mod
SF Senior Mod


Joined: 21 Sep 2003
Posts: 16777097
Location: Portugal

Offline

PostPosted: Thu Jan 07, 2010 5:22 am    Post subject: Reply with quote

I've added some [code] tags to your post, to make it easier to read.

Let me guess... you enter 1 and then instead of pausing and waiting for you to enter your name, it just continues and prints an empty name.

Your problem is in the way you're calling scanf.

I've covered this in an older post, so I'll quote myself from there. In that thread, the original poster was trying to read a single character for a menu choice, by using scanf("%c", &choice). You are trying to read an integer, but the problem is exactly the same. Just replace %c with %i in what I've said below. I recommend you click on the link and read the whole post, though, since it contains a much lengthier explanation.

I wrote:
scanf takes input by matching it against the format string. Think of it as an input parser, since that's what it is. It matches the input against the format string, and quits when it's matched everything it was asked for (in your case, 1 character), or when the input differs from what it's expecting. If you tell it to match "%c54%c" it's going to expect to read one character, followed by 54, followed by another character. If it finds anything else, it bails out.

Note that it won't work if you do scanf("%c\n", &choice); (which would seem like the obvious choice). This would be telling scanf to read 1 character, followed by any amount of whitespace. Since scanf keeps reading from the input until it's matched everything it was asked to match, it will not stop when the user presses Enter (since Enter falls under "any amount of whitespace"). It will only stop when it finds something other than whitespace, after that first Enter.

scanf can be a complicated beast for the novice, as it's not entirely intuitive. You may find it simpler to use a function such as fgets (which reads a whole line of input) and do the processing yourself. You could process the string with sscanf, or just compare it to your allowed choices with strcmp(line, "y\n").

Do NOT, however, under any circumstance, use gets: that function is a broken design which you should never use in a real program. You cannot use gets in a secure way (search the web for "buffer overflows" and gets if you're curious), so don't get used to it in the first place.
Back to top
View user's profile Send private message
LrB113
Just Arrived
Just Arrived


Joined: 07 Jan 2010
Posts: 0


Offline

PostPosted: Sat Jan 09, 2010 8:04 am    Post subject: first attempt Reply with quote

Hmm, I read the older post and if I understand it, you put a whitespace or a \n to clear out the buffer to scanf. I did that and that did not fix the problem. For some reason the fgets function is being ignored when the first choice is selected. Is there another reason why fgets is ignored by the program?
Back to top
View user's profile Send private message
capi
SF Senior Mod
SF Senior Mod


Joined: 21 Sep 2003
Posts: 16777097
Location: Portugal

Offline

PostPosted: Sat Jan 09, 2010 7:05 pm    Post subject: Reply with quote

Ah yes, sorry, I forgot you were using an fgets after the scanf. My solution would have more sense if it was a scanf after another scanf. That's what comes from posting at 4 am lol.

Your problem is still related: the scanf is leaving the Enter on the stdin buffer (because it's being told to read an integer, and an Enter is not an integer). When fgets goes in to read, it finds an Enter there, and it returns an empty line.

You need to clear out that Enter from the input buffer. You could use something like getchar, or you could save yourself the trouble and just use fgets for the first choice too, and process it with sscanf (or atoi, strtol, etc).
Back to top
View user's profile Send private message
LrB113
Just Arrived
Just Arrived


Joined: 07 Jan 2010
Posts: 0


Offline

PostPosted: Tue Jan 12, 2010 6:16 am    Post subject: Reply with quote

Let me try that. I will get back to you with my results. Thank you. Btw, do you mind if I ask what is your occupation? You seem to know a lot about C?
Back to top
View user's profile Send private message
capi
SF Senior Mod
SF Senior Mod


Joined: 21 Sep 2003
Posts: 16777097
Location: Portugal

Offline

PostPosted: Tue Jan 12, 2010 6:39 am    Post subject: Reply with quote

No worries. I'm a software developer, specializing in lower level areas such as systems programming Smile

As you can probably tell from my C signature, I prefer to work in POSIX environments (GNU/Linux, Unix, etc.), but I'm comfortable enough with Windows as well.

I also do some sysadminning on the side, but coding is definitely my passion.
Back to top
View user's profile Send private message
Display posts from previous:   

Post new topic   Reply to topic   Printer-friendly version    Networking/Security Forums Index -> Programming and More All times are GMT + 2 Hours
Page 1 of 1


 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

Looking for more Windows Networking info?

Sign up to the WindowsNetworking.com Monthly Newsletter, written by Enterprise Security MVP Deb Shinder, containing news, the hottest tips, Networking links of the month and much more. Subscribe today and don't miss a thing!
View a sample newsletter.

Become a WindowsNetworking.com member!

Discuss your Windows Networking issues with thousands of other Windows Newtorking experts. Click here to join!

Community Area

Log in | Register

Readers' Choice

Which is your preferred data recovery solution?

Follow TechGenix on Twitter