strcmp() And if

Discussion in 'C Programming' started by Eirik, Dec 13, 2003.

  1. Eirik

    Eirik Guest

    Shouldn't this code work? If not, why shouldn't it?

    #include <stdio.h>

    int main(void)

    {

    char yesno[10];
    char *yes = "yes";
    char *no = "no";

    printf("Select: yes or no\n");
    fgets(yesno, sizeof(yesno), stdin);

    if(strcmp(yes, yesno) == 0)
    {
    printf("yes\n");
    }
    if(strcmp(no, yesno) == 0)
    {
    printf("no\n");
    }

    return 0;

    }
     
    Eirik, Dec 13, 2003
    #1
    1. Advertising

  2. (Eirik) writes:

    > Shouldn't this code work? If not, why shouldn't it?


    That depends on how you define "work". If the program receives the
    characters 'y', 'e', and 's', immediately followed by an end-of-file
    condition, on standard input, it prints "yes" followed by a newline
    character. If it receives 'n' and 'o', again followed by an end-of-file
    condition, it prints "no" followed by a newline character. If that is
    what the program is supposed to do, then it works.

    If `fgets' reads a full line, then the program cannot print either "yes\n"
    or "no\n", because `fgets' stores the final newline character if there is
    one.

    > #include <stdio.h>


    Since the program uses `strcmp', I recommend that you also include
    <string.h>.

    > int main(void)
    >
    > {
    >
    > char yesno[10];
    > char *yes = "yes";


    Since the pointer itself is not modified, and the memory pointed to
    (a string literal) cannot be modified, I recommend that you make both
    constant:

    const char *const yes = "yes";

    > char *no = "no";


    Likewise.

    > printf("Select: yes or no\n");


    The simpler `puts' function would also have been possible here.

    > fgets(yesno, sizeof(yesno), stdin);


    As explained above, `fgets' stores the final newline character if there is
    one before end-of-file or an error occur. Also, you might want to check
    the return value: it is a null pointer if an error occurs or end-of-file
    occurs before at least one character has been read.

    > if(strcmp(yes, yesno) == 0)
    > {
    > printf("yes\n");


    Again, `puts' would also have been possible.

    > }
    > if(strcmp(no, yesno) == 0)


    Since this condition cannot be true if the previous condition has already
    been true, you could avoid an unnecesary test by writing

    else if (strcmp (no, yesno) == 0)

    > {
    > printf("no\n");


    Again, `puts' would also have been possible.

    > }
    >
    > return 0;
    >
    > }



    Martin
     
    Martin Dickopp, Dec 13, 2003
    #2
    1. Advertising

  3. Eirik

    JakeP Guest

    because you enter no followed by a carridge return.

    try defining these and re-running the code :eek:)

    char yesno[10];
    char *yes = "yes\n";
    char *no = "no\n";

    JohnO



    On 13 Dec 2003 06:39:34 -0800, (Eirik)
    wrote:





    >Shouldn't this code work? If not, why shouldn't it?
    >
    >#include <stdio.h>
    >
    >int main(void)
    >
    >{
    >
    > char yesno[10];
    > char *yes = "yes";
    > char *no = "no";
    >
    > printf("Select: yes or no\n");
    > fgets(yesno, sizeof(yesno), stdin);
    >
    > if(strcmp(yes, yesno) == 0)
    > {
    > printf("yes\n");
    > }
    > if(strcmp(no, yesno) == 0)
    > {
    > printf("no\n");
    > }
    >
    > return 0;
    >
    >}
     
    JakeP, Dec 13, 2003
    #3
  4. fgets include the first CR caracter that the user type to validate
    his answer that's why strcmp returns 1 and not 0.

    To avoid that you can do :

    if(strncmp(yes, yesno, 3) == 0)
    {
    printf("yes\n");
    }

    --
    Un Véritable lui, code en fortran.

    "Eirik" <> a écrit dans le message de news:
    ...
    > Shouldn't this code work? If not, why shouldn't it?
    >
    > #include <stdio.h>
    >
    > int main(void)
    >
    > {
    >
    > char yesno[10];
    > char *yes = "yes";
    > char *no = "no";
    >
    > printf("Select: yes or no\n");
    > fgets(yesno, sizeof(yesno), stdin);
    >
    > if(strcmp(yes, yesno) == 0)
    > {
    > printf("yes\n");
    > }
    > if(strcmp(no, yesno) == 0)
    > {
    > printf("no\n");
    > }
    >
    > return 0;
    >
    > }
     
    Dalbosco Jean-François, Dec 13, 2003
    #4
  5. Eirik

    Thomas Pfaff Guest

    (Eirik) writes:

    > Shouldn't this code work? If not, why shouldn't it?
    >
    > #include <stdio.h>
    >
    > int main(void)
    > {
    > char yesno[10];
    > char *yes = "yes";
    > char *no = "no";
    >
    > printf("Select: yes or no\n");
    > fgets(yesno, sizeof(yesno), stdin);


    If you enter "yes" then yesno will contain "yes\n",

    > if(strcmp(yes, yesno) == 0)
    > {
    > printf("yes\n");


    so you won't get here.
     
    Thomas Pfaff, Dec 13, 2003
    #5
  6. Eirik

    -berlin.de Guest

    Eirik <> wrote:
    > Shouldn't this code work? If not, why shouldn't it?


    > #include <stdio.h>


    > int main(void)


    > {


    > char yesno[10];
    > char *yes = "yes";
    > char *no = "no";


    > printf("Select: yes or no\n");
    > fgets(yesno, sizeof(yesno), stdin);


    > if(strcmp(yes, yesno) == 0)
    > {
    > printf("yes\n");
    > }
    > if(strcmp(no, yesno) == 0)
    > {
    > printf("no\n");
    > }


    > return 0;


    > }


    Depends on what you mean with "work". It will work in the sense that
    the program is going to run, but not in the sense that it will print
    out "yes" when you enter "yes" or "no" when you enter "no".

    The problem is that fgets() also stores the final '\n' character in
    your 'yesno' buffer, which you get from pressing the <ENTER> key.
    So you either have to strip it off from the 'yesno' buffer or you
    have to compare against "yes\n" and "no\n" to get the expected
    result.
    Regards, Jens

    --
    \ Jens Thoms Toerring ___ -berlin.de
    \__________________________ http://www.physik.fu-berlin.de/~toerring
     
    -berlin.de, Dec 13, 2003
    #6
  7. Eirik

    Joe Wright Guest

    Eirik wrote:
    >
    > Shouldn't this code work? If not, why shouldn't it?
    >
    > #include <stdio.h>
    >
    > int main(void)
    >
    > {
    >
    > char yesno[10];
    > char *yes = "yes";
    > char *no = "no";
    >
    > printf("Select: yes or no\n");
    > fgets(yesno, sizeof(yesno), stdin);
    >
    > if(strcmp(yes, yesno) == 0)
    > {
    > printf("yes\n");
    > }
    > if(strcmp(no, yesno) == 0)
    > {
    > printf("no\n");
    > }
    >
    > return 0;
    >
    > }


    You forgot string.h and that fgets() returns the '\n'.

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

    int main(void)
    {
    char yesno[10];
    char *yes = "yes\n";
    char *no = "no\n";
    printf("Select: yes or no\n");
    fgets(yesno, sizeof yesno, stdin);

    if (strcmp(yes, yesno) == 0) {
    printf("yes\n");
    }
    if (strcmp(no, yesno) == 0) {
    printf("no\n");
    }
    return 0;
    }

    --
    Joe Wright http://www.jw-wright.com
    "Everything should be made as simple as possible, but not simpler."
    --- Albert Einstein ---
     
    Joe Wright, Dec 13, 2003
    #7
  8. Eirik

    CBFalconer Guest

    Joe Wright wrote:
    > Eirik wrote:
    > >
    > > Shouldn't this code work? If not, why shouldn't it?
    > >
    > > #include <stdio.h>
    > > int main(void)
    > > {
    > > char yesno[10];
    > > char *yes = "yes";
    > > char *no = "no";
    > >
    > > printf("Select: yes or no\n");
    > > fgets(yesno, sizeof(yesno), stdin);
    > >
    > > if(strcmp(yes, yesno) == 0)
    > > {
    > > printf("yes\n");
    > > }
    > > if(strcmp(no, yesno) == 0)
    > > {
    > > printf("no\n");
    > > }
    > > return 0;
    > > }

    >
    > You forgot string.h and that fgets() returns the '\n'.
    >
    > #include <stdio.h>
    > #include <string.h>
    >
    > int main(void)
    > {
    > char yesno[10];
    > char *yes = "yes\n";
    > char *no = "no\n";
    > printf("Select: yes or no\n");
    > fgets(yesno, sizeof yesno, stdin);
    >
    > if (strcmp(yes, yesno) == 0) {
    > printf("yes\n");
    > }
    > if (strcmp(no, yesno) == 0) {

    else if (strcmp(no, yesno) == 0) { /* replace above ***/
    > printf("no\n");
    > }

    else printf("Don't understand \"%s\"\n", yesno); /* ADD **/
    > return 0;
    > }


    See recommended mods above.

    --
    Chuck F () ()
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net> USE worldnet address!
     
    CBFalconer, Dec 13, 2003
    #8
  9. Eirik

    Eirik Guest

    Thank you for all replies!

    Eirik


     
    Eirik, Dec 14, 2003
    #9
  10. Eirik

    Lew Pitcher Guest

    Eirik wrote:
    > Shouldn't this code work? If not, why shouldn't it?
    >
    > #include <stdio.h>
    >
    > int main(void)
    >
    > {
    >
    > char yesno[10];
    > char *yes = "yes";


    Here, your yes variable is a pointer to a four character array, such that
    *(yes+0) == 'y'
    *(yes+1) == 'e'
    *(yes+2) == 's' and
    *(yes+3) == '\0'

    > char *no = "no";


    Similarly, your no variable is a pointer to a three character array, such that
    *(no+0) == 'n'
    *(no+1) == 'o' and
    *(no+2) == '\0'


    > printf("Select: yes or no\n");
    > fgets(yesno, sizeof(yesno), stdin);


    fgets() stops reading after an EOF or a newline. If a newline is read, it is
    stored in the buffer. A \0 is stored after the last character in the buffer.

    If your hosted environment is consistant with most environments, fgets() will
    have captured a buffer that
    a) has a newline character following the input data, and
    b) has a \0 after the newline character.

    Assuming the user entered "no", then yesno will be string of four characters
    yesno[0] will be 'n'
    yesno[1] will be 'o'
    yesno[2] will be '\n' and
    yesno[3] will be '\0'


    > if(strcmp(yes, yesno) == 0)


    strcmp() performs a character by character comparison. Even if the user entered
    "yes", if the entry was terminated by a newline, then yesno will carry "yes\n",
    but yes will point to a string "yes". These are not equal (yesno carries a '\n'
    where yes carries a '\0'), and the test fails.

    > {
    > printf("yes\n");
    > }
    > if(strcmp(no, yesno) == 0)


    Similarly, if the user entered "no", and the entry was terminated by a newline,
    then yesno will carry "no\n", but no will point to the string "no". Again, the
    comparison fails because '\n' is not equal to '\0'.

    > {
    > printf("no\n");
    > }
    >
    > return 0;
    >
    > }


    One way to fix this would be to change

    > char *yes = "yes";
    > char *no = "no";


    to

    char *yes = "yes\n";
    char *no = "no\n";


    --
    Lew Pitcher

    Master Codewright and JOAT-in-training
    Registered Linux User #112576 (http://counter.li.org/)
    Slackware - Because I know what I'm doing.
     
    Lew Pitcher, Dec 14, 2003
    #10
  11. Eirik

    Anupam Guest

    Lew Pitcher <> wrote in message news:<6s4x6-4.ca>...
    > Eirik wrote:
    > > Shouldn't this code work? If not, why shouldn't it?
    > >
    > > #include <stdio.h>
    > >
    > > int main(void)
    > >
    > > {
    > >
    > > char yesno[10];
    > > char *yes = "yes";

    >
    > Here, your yes variable is a pointer to a four character array, such that

    Nitpick :: The yes variable is a pointer to a character .. specifically to
    the first character in the string "yes". No type information is stored in
    it. The declaration for a pointer to a four character array would be :
    char (* p4array)[4];

    > *(yes+0) == 'y'
    > *(yes+1) == 'e'
    > *(yes+2) == 's' and
    > *(yes+3) == '\0'
    >
    > > char *no = "no";

    >
    > Similarly, your no variable is a pointer to a three character array, such that

    Likewise.

    > *(no+0) == 'n'
    > *(no+1) == 'o' and
    > *(no+2) == '\0'
    >
    >
    > > printf("Select: yes or no\n");
    > > fgets(yesno, sizeof(yesno), stdin);

    >
    > fgets() stops reading after an EOF or a newline. If a newline is read, it is
    > stored in the buffer. A \0 is stored after the last character in the buffer.
    >
    > If your hosted environment is consistant with most environments, fgets() will
    > have captured a buffer that
    > a) has a newline character following the input data, and
    > b) has a \0 after the newline character.
    >
    > Assuming the user entered "no", then yesno will be string of four characters
    > yesno[0] will be 'n'
    > yesno[1] will be 'o'
    > yesno[2] will be '\n' and
    > yesno[3] will be '\0'
    >
    >
    > > if(strcmp(yes, yesno) == 0)

    >
    > strcmp() performs a character by character comparison. Even if the user entered
    > "yes", if the entry was terminated by a newline, then yesno will carry "yes\n",
    > but yes will point to a string "yes". These are not equal (yesno carries a '\n'
    > where yes carries a '\0'), and the test fails.
    >
    > > {
    > > printf("yes\n");
    > > }
    > > if(strcmp(no, yesno) == 0)

    >
    > Similarly, if the user entered "no", and the entry was terminated by a newline,
    > then yesno will carry "no\n", but no will point to the string "no". Again, the
    > comparison fails because '\n' is not equal to '\0'.
    >
    > > {
    > > printf("no\n");
    > > }
    > >
    > > return 0;
    > >
    > > }

    >
    > One way to fix this would be to change
    >
    > > char *yes = "yes";
    > > char *no = "no";

    >
    > to
    >
    > char *yes = "yes\n";
    > char *no = "no\n";
     
    Anupam, Dec 15, 2003
    #11
  12. Eirik

    Lew Pitcher Guest

    Anupam wrote:
    > Lew Pitcher <> wrote in message news:<6s4x6-4.ca>...
    >
    >>Eirik wrote:
    >>
    >>>Shouldn't this code work? If not, why shouldn't it?
    >>>
    >>>#include <stdio.h>
    >>>
    >>>int main(void)
    >>>
    >>>{
    >>>
    >>> char yesno[10];
    >>> char *yes = "yes";

    >>
    >>Here, your yes variable is a pointer to a four character array, such that

    >
    > Nitpick :: The yes variable is a pointer to a character .. specifically to
    > the first character in the string "yes". No type information is stored in
    > it. The declaration for a pointer to a four character array would be :
    > char (* p4array)[4];


    Yes, of course. :)


    My only excuse is that I tried to simplify the explanation somewhat.


    [snip]

    --
    Lew Pitcher

    Master Codewright and JOAT-in-training
    Registered Linux User #112576 (http://counter.li.org/)
    Slackware - Because I know what I'm doing.
     
    Lew Pitcher, Dec 17, 2003
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Shane Peck

    strcmp problem

    Shane Peck, Sep 19, 2003, in forum: C++
    Replies:
    6
    Views:
    2,383
    Kevin Goodsell
    Sep 22, 2003
  2. muser

    strcmp

    muser, Oct 3, 2003, in forum: C++
    Replies:
    6
    Views:
    1,156
    Frank Schmitt
    Oct 9, 2003
  3. Andrej Hocevar

    please help with strcmp()

    Andrej Hocevar, Jul 19, 2003, in forum: C Programming
    Replies:
    3
    Views:
    349
    Gordon Burditt
    Jul 19, 2003
  4. blueblueblue2005

    memcmp() and strcmp()

    blueblueblue2005, Jul 3, 2005, in forum: C++
    Replies:
    4
    Views:
    2,235
    Jack Klein
    Jul 4, 2005
  5. coinjo
    Replies:
    4
    Views:
    541
    red floyd
    Mar 1, 2006
Loading...

Share This Page