Apo
Apo

Reputation: 11

While with multiple conditions

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

Answers (4)

user3629249
user3629249

Reputation: 16540

the following proposed code:

  1. cleanly compiles
  2. only calls scanf() once per each outer loop
  3. prompts the user for the desired input

and 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

xing
xing

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

John Bode
John Bode

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

ncarrier
ncarrier

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

Related Questions