CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5
  1. #1
    Join Date
    Oct 2009
    Posts
    40

    [RESOLVED] fgets don't work as I expected with this code,need help

    I have a problem with the codes below.I am trying to do an exercise from a C book.My code first asks for user input,then it seperates the given input into it's "atoms".Then it changes the words like this:Let's say one of the word is "soccer",my program tries to change it to "occersay",it puts the first letter of the word after the last letter of the word and it adds "ay" to the last part of the word.

    But the problem is,if I use fgets for asking user input,it runs as this:

    "
    Please write a sentence without using any punctuator: We play soccer

    eWay
    laypay
    occer
    say
    "


    As you see,it automatically passes to newline before putting "s" and "ay" after the "occer",though it works well with previous words.
    After minutes/hours of investigation,I have found that the problematic part is fgets.If I use "gets(sentence)" instead of "fgets(sentence,50,stdin)" then no problem,it works as I expected.

    Is there a way to do same thing with fgets?I have read on internet that "gets" has not been a type-safe function and it was recommended to use fgets instead of gets.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    void lwords(char*);

    int main()
    {
    char* sentence=(char*) malloc(150);

    printf("Please write a sentence without using any punctuator: ");

    fgets(sentence,50,stdin);


    char* word=strtok(sentence," ");



    while (word!=NULL)
    {

    lwords(word);
    word=strtok(NULL," ");

    }

    free(sentence);

    }


    void lwords(char* word)
    {
    char* plat=(char*) malloc(40);


    strcpy(plat,word);


    int stringsize=strlen(plat);
    memmove(&plat[strlen(plat)],&plat[0],1);

    plat[(stringsize+1)]='\0';

    sprintf(plat,"&#37;s%s",plat,"ay");

    memmove(plat,&plat[1],strlen(plat));

    printf("%s\n",plat);


    }
    Last edited by AwArEnEsS; February 23rd, 2012 at 08:48 PM.

  2. #2
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: fgets don't work as I expected with this code,need help

    The problem with your code arises from the fact that gets() does not return the '\n' that ends the input line as part of the input string but fgets() does (for reference: http://www.cplusplus.com/reference/c...y/cstdio/gets/, http://www.cplusplus.com/reference/c.../cstdio/fgets/). I see three possible fixes for you:
    • Check for a '\n' at the end of your input string and remove it when you find one. (You may omit the check and simply remove the last character if you trust your users never to enter a string that's longer than the maximum number of characters you specify minus two.)
    • Add '\n' to the set of delimiters you pass to strtok(). That way it will be skipped.
    • Simply use gets() instead. Yes, it's insecure (though not for reasons related to type safety), but that may be neglectible since your program doesn't seem to be intended to be used in a real production environment and being subject to potential hacker attacks, as long as only the buffer you supply is sufficiently big.

    Also, why do you allocate the input buffer dynamincally? There's no reason for that. This is pretty much sufficient:

    Code:
    char sentence[150];
    The same applies to plat in lwords(), but this time it's much worse since you never free() it. Result: memory leak. BTW, lwords() is just as prone to a buffer overrun as gets() is...
    Last edited by Eri523; February 23rd, 2012 at 08:53 PM. Reason: Fixed major code oops that Paul's post #3 pointed me to... :o
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  3. #3
    Join Date
    Apr 1999
    Posts
    27,449

    Re: fgets don't work as I expected with this code,need help

    Quote Originally Posted by AwArEnEsS View Post
    I have a problem with the codes below.I am trying to do an exercise from a C book.
    Your C book doesn't teach you arrays?
    Code:
    char* sentence=(char*) malloc(150);
    Why don't you just use an array of char? What's the reason to dynamically allocate memory? You know exactly how big the array is.
    Code:
    char sentence[150];
    You do the same coding in other places, and to top it all off, you never call "free()" anywhere in your code, causing a memory leak.

    Let me guess -- you see a function that requires a pointer as a parameter, and you believe you need to declare a pointer and pass it to the function, am I correct? Well if that's the case, you're making the beginner mistake of believing that functions that require pointers means that you must explicitly declare a pointer. That is not true -- the function requires an address. The name of the array serves as the address:
    Code:
    char sentence[150];
    //...
    fgets(sentence, 50, stdin);
    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; February 23rd, 2012 at 08:54 PM.

  4. #4
    Join Date
    Oct 2009
    Posts
    40

    Re: fgets don't work as I expected with this code,need help

    Thanks for your answers.

    I used pointers instead of arrays,because using arrays is easier but I have not yet understood the pointers topic exactly,so I use them to get more familiar with them and learn more about them.

  5. #5
    Join Date
    Apr 1999
    Posts
    27,449

    Re: fgets don't work as I expected with this code,need help

    Quote Originally Posted by AwArEnEsS View Post
    Thanks for your answers.

    I used pointers instead of arrays,because using arrays is easier but I have not yet understood the pointers topic exactly,so I use them to get more familiar with them and learn more about them.
    The issue is that you're using pointers for the wrong reasons. It isn't just about learning pointers, you need to learn when to use them. Allocating memory when you know the exact size of the array at compile time is not a use-case for declaring pointers and using "malloc".

    You can learn about pointers without dynamically allocating memory. You introduced memory leaks in your program for really no reason.

    Regards,

    Paul McKenzie

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured