strcmp() And if

E

Eirik

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;

}
 
M

Martin Dickopp

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
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
 
J

JakeP

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
 
D

Dalbosco Jean-François

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");
}
 
T

Thomas Pfaff

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.
 
J

Jens.Toerring

Eirik said:
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
 
J

Joe Wright

Eirik said:
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;
}
 
C

CBFalconer

Joe said:
Eirik said:
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.
 
L

Lew Pitcher

Eirik said:
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.
 
A

Anupam

Lew Pitcher said:
Eirik said:
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";
 
L

Lew Pitcher

Anupam said:
Lew Pitcher said:
Eirik said:
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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,577
Members
45,054
Latest member
LucyCarper

Latest Threads

Top