Reputation: 11
This is my code.The user enters a string and if the input is 1,2 or * it displays error.The problem is that the condition is satisfied for all the numbers of which the first digits are 1,2 amd 3.(11,12,22...).I used also strlen and sizeof function to count the digits and create a condition that works but when i printed strlen the output was 1 for every number.
I don't understand if the problem is my multiple conditions or the use of scanf
Here is my code
#include < stdio.h >
int main (void)
{
char choice;
int i=0;
do
{
scanf("%s", &choice);
while(choice !='1' && choice !='2' && choice !='*' )
{
printf("error");
scanf("%s",&choice);
}
}while (choice !='0');
return 0;
}
I would be very thankful for any help. I am quite new in programming, so forgive me if the question is stupid.
Upvotes: 0
Views: 632
Reputation: 16540
the following proposed code:
scanf()
once per each outer loopand now the code:
#include <stdio.h> // scanf(), printf(), perror()
#include <stdlib.h> // exit(), EXIT_FAILURE
int main (void)
{
char choice;
do
{
printf( "enter 0:" );
if( 1 != scanf(" %c", &choice) )
{
perror( "scanf failed" ); // to stderr:
// enclosed text + reason OS thinks it failed
exit( EXIT_FAILURE ); // once failed, it will continue to fail
// so exit program with error indication
}
// implied else, scanf successful
// what about other user inputs?
if(choice !='1' && choice !='2' && choice !='*' )
{
printf("error\n"); // trailing '\n'
// so immediately displayed on terminal
// note: should use: 'fprintf( stderr, ... )'
// because error messages should
// be output to 'stderr', not 'stdout'
}
} while (choice !='0');
return 0;
} // end function: main
Upvotes: 0
Reputation: 2528
Consider using fgets
to obtain input, then parse with sscanf
. Using int choice
allows you to distinguish between 1 and 11...
#include <stdio.h>
int main( void) {
char input[99] = "";
int choice = 0;
do {
printf ( "Enter 0 to quit\n");
if ( fgets ( input, sizeof input, stdin)) {
if ( 1 == sscanf ( input, "%d", &choice)) {
if ( choice == 1 || choice == 2 || choice == 3) {
printf ( "error\n");
}
else {
printf ( "you entered %d\n", choice);
}
}
else {
if ( 0 == strcmp ( input, "*\n")) {
printf ( "error\n");
}
//sscanf could not parse an int
choice = -1;
}
}
else {
break;// fgets failed
}
} while ( choice != 0);
return 0;
}
Upvotes: 1
Reputation: 123578
You've declared choice
as a char
object - it's only large enough to store a single character value. If you're entering a string like "123"
on input, only the leading '1'
is stored to choice
and the remaining input is written to memory immediately following choice
, which may cause a runtime error if you clobber anything important.
If you want to read and store the input as a string of characters, then you need to declare choice
as an array of char
, sized to hold at least one more character than the maximum input size - IOW, if you expect the maximum string to be 3 characters long, then choice
must be declared as char choice[4];
.
If you want to read and store the input as an integer, then you must declare choice as int
instead of char
, and you need to use the %d
conversion specifier instead of %s
.
Upvotes: 1
Reputation: 475
I propose you the following code:
#include <stdio.h>
#include <string.h>
int main (void)
{
char choice[201];
do
{
scanf("%200s", choice);
if (strcmp(choice, "1") == 0 ||
strcmp(choice, "2") == 0 ||
strcmp(choice, "3") == 0)
printf("error");
} while (strcmp(choice, "0") != 0);
return 0;
}
%s
waits for a char *
argument, your &choice
was right, but scanf will write a whole string at the address pointed to, which can (will) contain more than one char. By giving the address of a char variable, you provided it with the room for only one char.
You can't compare strings with a comparison operator, you have to use, for example, the strcmp
function, which returns 0 if it's two argument do match and non-zero otherwise.
If I properly understood your intent, there is no need for two nested while loop. The two scanf
calls aren't needed either.
The 200
in the %200s
scanf format string, limits the number of chars which will be written in the array you have provided the address of.
This array is of size 201
to account for the extra '\0' byte, terminating C strings.
To write properly this code, one should test the return of scanf, to check if something has been parsed with success. Please refer to the man page of scanf to see how to check if the parsing went successfully.
Upvotes: 1