Thread: gets function is missed, not even given a chance to enter enything.

  1. #1
    Registered User
    Join Date
    Apr 2004
    Posts
    27

    gets function is missed, not even given a chance to enter enything.

    I have written function that allows a user to enter a long string of text into a file:

    Code:
    void menuoption3(void)
    {
    	FILE *textfile;
    	char insertedtext[30];
    	textfile=fopen(".\\textfiles\\temp.txt","w");
    
    	printf("\n\nPlease enter in your text."
                    "\nTo finish, please press enter.\n\n");
    	gets(insertedtext);
    	fputs(insertedtext,textfile);
    	fclose(textfile);
    }

    If I put this function as a main one i.e. void main (void), is works fine, temp.txt is changed to whatever the user types.

    However, when I use this function being called by another function (shown below), the "gets" function is missed, as in I'm not given a chance to write anything.

    The menuoption3() function is called from the main function in a switch function like this:

    Code:
    void main (void)
    ....
    switch(n)
    ...
    	case 2: menuoption2();break;
    	case 3: menuoption3();break;
    	case 4: menuoption4();break;
    ....
    So why doesn't the "gets" function allow me to type data at runtime?

    Thanks in advance,
    CookieMonster

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    1) main does not return void. It returns an int. Always.
    2) Let me guess, you're using scanf to read n, right? Well that's your problem. Don't mix scanf with any other type of input reading. For that matter, just don't use scanf.
    3) Read the FAQ, you should never use gets. What happens if I feel like typing 50 characters instead of the 29 you expect?

    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Apr 2004
    Posts
    27
    Quote Originally Posted by quzah
    1) main does not return void. It returns an int. Always.
    Okay I'll change it to an int.

    Quote Originally Posted by quzah
    2) Let me guess, you're using scanf to read n, right? Well that's your problem. Don't mix scanf with any other type of input reading. For that matter, just don't use scanf.
    What should I use instead? I have tried doing:

    Code:
    menuoption=getchar();
    It doesn't work, the "cases" in the switch function do not recognise what number I entered.

    Quote Originally Posted by quzah
    3) Read the FAQ, you should never use gets. What happens if I feel like typing 50 characters instead of the 29 you expect?
    I'll use malloc to assign some memory at run time later.

    What should I use instead of gets? An array of chars? What does work?

    When I search "gets" in the FAQ, I get no results.

    http://cboard.cprogramming.com/faq.p...y&titlesonly=0

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    He means this FAQ

    Code:
    scanf( "%d", &choice );
    getchar();
    Can be replaced with
    Code:
    char buff[BUFSIZ];
    
    fgets( buff, sizeof buff, stdin );
    sscanf( buff, "%d", &choice );
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Apr 2004
    Posts
    27
    Thanks for that.

  6. #6
    Registered User
    Join Date
    Apr 2004
    Posts
    27
    CookieMonster has been thinking (<<<a dangerous thing ) a lot about streams.

    Here's is what I did to solve my problem. Now this is only a small program, but I'd just like to know if this would work for bigger programs in the future:


    Code:
    int main ()
    {
    ...
    	scanf(" %i", &menuoption);
    	
    	switch(menuoption)
    	{
    	case 1: menuoption1();break;
    	case 2: menuoption2();break;
    	case 3: menuoption3();break;
    ...
    }

    Code:
    void menuoption3(void)
    {
    	FILE *textfile;
    	char insertedtext[30];
    	textfile=fopen(".\\textfiles\\usertext.txt","w");
    
    	printf("\n\nPlease enter in your text you wish to assess."
    		   "\nYou have a limit of 3000 characters."
    		   "\nTo finish, please press enter.\n\n");
    	scanf(" %s",&insertedtext);
    	fputs(insertedtext,textfile);
    	fclose(textfile);
    	statisticsoftextfile ("User Text",".\\textfiles\\usertext.txt");
    }
    The difference is the space that I put before the % in the scanf's in each of the two functions.

    And another noob question: What is so bad about using void main (void), because I've been using it for the past 5 months or so.

    I only ask after seeing Salem's avatar!

    Why didn't someone inform me of the atrocity void main (void) committed?

  7. #7
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Code:
    scanf(" %s",&insertedtext);
    This is just as safe as gets.

    >Why didn't someone inform me of the atrocity void main (void) committed?

    Try this.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  8. #8
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >I'd just like to know if this would work for bigger programs in the future
    No. Very no. And here's why:

    >scanf(" %i", &menuoption);
    The leading space trick is just a kludge. It works around the problem instead of addressing it directly. The core of the problem is that scanf doesn't play well with others.

    >char insertedtext[30];
    Okay just as long as you check for buffer overflow.

    >"\nYou have a limit of 3000 characters."
    Get ready for some serious buffer overflow. When you tell the user they have a certain leeway, they use it. So unless your string reading function stops reading at 29 characters (leaving space for the '\0'), you'll have problems.

    >scanf(" %s",&insertedtext);
    Strike three. When scanf is used in this manner, it isn't any better than gets. It keeps reading characters until whitespace, or writing over memory that you don't own causes your hardware to short circuit. You also don't use the address-of operator for variables that are already pointers. A better way would be to specify a size:
    Code:
    scanf(" %29s", insertedtext);
    But scanf is notoriously bad at reading string data, so you should just stick to fgets:
    Code:
    if ( fgets ( insertedtext, sizeof insertedtext, stdin ) != NULL ) {
      /* Use the string */
    }
    >What is so bad about using void main (void)
    Undefined behavior. This means that your program has the right to do anything at all, including sending emails to everyone in your address book with the message that you're incompetent.

    >because I've been using it for the past 5 months or so
    Just because something works for you doesn't mean that it works for everyone else.

    >Why didn't someone inform me of the atrocity void main (void) committed?
    I would be very surprised if we didn't. You probably just weren't paying attention.
    My best code is written with the delete key.

  9. #9
    Registered User
    Join Date
    Apr 2004
    Posts
    27
    Ooohhh!

    Doh! Three strikes! I hadn't yet finished writing up that function, but thanks for the %29s thing, you woulda still got me there.
    Last edited by CookieMonster; 04-07-2004 at 01:29 PM. Reason: :)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. program doesnt enter function
    By avisik in forum C Programming
    Replies: 5
    Last Post: 12-17-2008, 11:06 PM
  2. Assignment output help
    By Taka in forum C Programming
    Replies: 13
    Last Post: 09-23-2006, 11:40 PM
  3. Time to seconds program
    By Sure in forum C Programming
    Replies: 1
    Last Post: 06-13-2005, 08:08 PM
  4. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  5. Replies: 6
    Last Post: 03-02-2005, 02:45 AM