'How can fix this value bug?

I have problem about wrong values. How can i control input data. If user enter char value , my code is give error. I'm beginner coder so i couldn't fix it. Waiting for your advice.(I'm sharing some of it because my code doesn't fit)

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

#define PI 3.14 // We define pi number with this code.

int main() {
    printf(" Welcome to the geometric shapes calculator. \n (Press the number you want to operate from 1 to 9.) ");
    char lastChoice[30];

    do {
        printf("\n Please choose the geometric shapes you want to calculate");
        printf("\n GEOMETRIC SHAPES \n 1-Square \n 2-Triangle \n 3-Rectangle \n 4-Parallelogram \n 5-Rhombus \n 6-Circle \n 7-Trapezoid \n");
        int choice1;
        scanf("%d", &choice1);
        if (choice1 > 7 || choice1 < 1) {
            printf("\n You chose wrong operate.");
            printf("\n Do you want to do calculation ? \n (Please press y if you want to continue to calculation)");
            scanf("%s", &lastChoice);
        }

        if (choice1 == 1) {
            printf("Please choose the measurement you want to calculate. \n ");
            printf("\n 1-Perimeter \n 2-Area \n 3-Volume \n 4-All of them \n");
            int choice2;
            scanf("%d", &choice2);
            if (choice2 == 1) {
                printf("Please write the length of edge. \n");
                float squareEdge;
                scanf("%f", &squareEdge);
                printf("Perimeter of the square : %.2f", 4 * squareEdge);
            }
            if (choice2 == 2) {
                printf("Please write the length of edge. \n");
                float squareEdge;
                scanf("%f", &squareEdge);
                printf("Area of the square : %.2f", squareEdge * squareEdge);
            }
            if (choice2 == 3) {
                printf("2D geometric shapes have not volume. \n");
                printf("\n Do you want to do calculation ? \n (Please press y if you want to continue to calculation.)");
                scanf("%s", lastChoice);
              }
       }
     }while (strcmp(lastChoice, "y")==0);
}
c


Solution 1:[1]

Pay attention to your compiler warnings.

main.c:19:21: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[30]’ [-Wformat=]
   19 |             scanf("%s", &lastChoice);
      |                    ~^   ~~~~~~~~~~~
      |                     |   |
      |                     |   char (*)[30]
      |                     char *

Name of the array is already a pointer to the first element, you shouldn't be taking the address of it.

scanf( "%s", lastChoice );

Also, scanf is not the tool for taking user input. Please seek alternatives. see

Solution 2:[2]

How can i control input data. If user enter char value ,

Although a bit much for a beginner, consider using helper functions to get user input and avoid scanf() everywhere.

Read using fgets() and then parse the input string.

Example for reading a limited range int.

#include <ctype.h>
#include <strlib.h>

// Return 0 on success
// EOF on end-of-file
// 1 on unrecoverable error
int read_int(int *result, int min, int max) {
  char buf[100];
  while (fgets(buf, sizeof buf, stdin)) {
    char *endptr;
    errno = 0;
    long val = strtol(buf, &endptr, 10); 
    unsigned char *end = endptr;
    while (isspace(*end)) end++; 
    // If conversion, no overflow, no junk at end of string, in range
    if (endptr > buf && errno == 0 && *end == '\0' && val >= min && val <= max) {
      *result = (int) val;
      return 0; // no error
    }
    printf("\n You chose invalid `int`.\n"); 
    printf("Do you want to do calculation ? \n"
    printf(" (Please press y if you want to continue to calculation)\n");
    TBD code and then return 1 or continue;
  }
  return EOF;
}

Likewise for other inputs like read_float(), etc.


Or check scanf() return value:

    for (;;) {
      int count = scanf("%d", &choice1);
      if (count == EOF) {
        return EXIT_FAILURE;  // stdin is closed
      } 
      if (count == 1 && choice1 >= 1 && choice1 <= 7) {
        break; // Success!
      }

      // Get rest of line in some fashion including that non-numeric input.
      int ch;
      while ((ch = gethar()) != '\n' && ch &= EOF) {
        ;
      }

      printf("\nYou chose wrong operate.\n");
      printf(" Do you want to do calculation ? \n");
      printf(" (Please press y if you want to continue to calculation)");

      unsigned char lastChoice[30];
      count = fgets(lastChoice, sizeof lastChoice, stdin);
      if (count == NULL || toupper(lastChoice) != 'Y')  {
        return EXIT_FAILURE;
      }
    }

Even with this approach, I recommend a helper function.


User input is evil. Do not trust it until well vetted.

Solution 3:[3]

You may want to use the function in the following URL to read user input: https://codereview.stackexchange.com/questions/273624/get-input-from-stdin-and-discard-extra-characters/274464#274464

scanf() is not a good choice for getting user input.

The code from the link is below:


/*
 * get_input_from_stdin_and_discard_extra_characters(char *str, long size):
 *
 * Function get_input_from_stdin_and_discard_extra_characters() reads at most
 * 'size - 1' characters into 'str' from stdin and then appends the null
 * character ('\0'). If 'size' is 0 then this function will discard all input
 * and return NULL. So, to discard all input, this function can be called with
 * 'str' having value NULL and 'size' having value 0.
 * In all cases, reading input stops after encountering a newline ('\n') or EOF
 * even if 'size - 1' characters have not been read. If a newline ('\n') or EOF
 * is read then it is replaced by null character ('\0'). If there are extra
 * characters in input, they are read and discarded.
 * In all cases, 'str' or NULL is returned.
 */
char *get_input_from_stdin_and_discard_extra_characters(char *str, long size)
{

    int c = 0;
    long i = 0;

    // If 'size' is 0 then this function will discard all input and return NULL.
    // No need to check 'str' if 'size' is 0.
    if (size == 0) {
        // discard all input
        while ((c = getchar()) && (c != '\n') && (c != EOF));
        return NULL;
    }

    if (!str)
        return str;

    if (size < 0)
        return NULL;

    for (i = 0; i < (size - 1); i = i + 1) {

        c = getchar();

        if ((c == '\n') || (c == EOF)) {
            str[i] = 0;
            return str;
        }

        str[i] = (char)(c);

    } // end of for loop

    str[i] = 0;

    // discard rest of input
    while ((c = getchar()) && (c != '\n') && (c != EOF));

    return str;

} // end of get_input_from_stdin_and_discard_extra_characters

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 melonduofromage
Solution 2
Solution 3