'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);
}
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 |
