C - OR in IF statements not working has I want - c

I've started learning C really recently in school, and I'm having a problem which I can't see where's the mistake.
I'm currently learning functions, and I have to develop a program that calculates the area of some geometric shapes with multiple functions. That's not going so well, but the problem I have is related with OR in IF statements. I'm trying to make the user select specific charecters, otherwise it will show "Invalid option, try again". The problem is that even if the users chooses the correct chars, the "warning" will show.
Sorry for bad english.
int menu()
{
char opc;
do
{
printf("Areas\n");
printf("\nTriangle (nr): \t\t\tRectangle (nr): \n");
printf("\nCircle (nr): \t\t\t\tSquare (nr): ");
printf("\n\n\t\tOPIONS");
printf("\n\n\t(T)riangle\n\t(R)ectangle\n\t(S)quare\n\t(C)ircle\n\t(E)nd\n\n");
scanf(" %c", &opc);
if((opc!='t') || (opc != 'c') || (opc != 'r') || (opc != 's') || (opc !='e'))
{
printf("\nInvalid option, try again\n");
}
}
while(opc!='e');
return opc;
}

You want:
if((opc!='t') && (opc != 'c') && (opc != 'r') && (opc != 's') && (opc !='e'))
In your code, opc can have only one value always at least 5 conditions will be true. If one of the conditions is true, the whole expression is true. So it is always the true despite the value of opt

't'!='c', 'c'!='r' etc so no letter is correct - you meet the condition for all letters.

you need to use && instead of || .because if the first condition is true ,I mean user input a character other than 't' ,compiler won't check next condition and whole expression will get true.

Related

If else not read third condition in C

I have a task named ''Discounted Coffee Machine'' with these conditions:
if(p<a){
printf("\nYour balance is not enough.");
printf("\nRemaining balance: %d",p);
}
else if(p>=a && dis!=dis2){
printf("\nEnjoy your Latte. ");
printf("\nRemaining balance: %d",p-a);
}
else if(p>=a && dis==dis2){
printf("\nThe discount has been applied.\nEnjoy your Latte.");
printf("\nRemaining balance: %f",(float)p-(float)a*0.9);
}
But, if I enter the correct discount code, it doesn't read the second else if. It only reads the first else if. How can I solve this?
I tried with the second else if like only else, but it's not working. I also tried with ',' and '||'.
dis and dis2 are character arrays
char dis[]="ostim";
char dis2[5];
dis!=dis2 compares the addresses of those 2 different arrays and so dis!=dis2 is always true. Code needs to compare the strings at those addresses. #Chris Dodd
Use strcmp() which returns 0 when the strings are the same.
Replace dis!=dis2 with strcmp(dis, dis2) != 0 or simply
// else if(p>=a && dis!=dis2){
else if(p>=a && strcmp(dis, dis2)) {
Likewise for else if(p>=a && dis==dis2).

When checking the validity of date of birth separated by dashes, an error rises when entering characters, and i can't solve that issue

from the requirements of my final project is to validate the scanned date of birth in the following format (DD-MM-YYYY).
the date of birth is a struct formed of 3 integers, day, month and year. So, I scan it from the user as follow:
scanf("%d-%d-%d",&dob.day,&dob.month,&dob.year);
However, when I enter a character, of course it enters an infinite loop.
I tried to use the flushinput concept (as I've used it with other scanned integers). It prevents the infinite loop. However, when re-scanning (through a certain loop), it keeps showing the "INVALID EMAIL" message, even though the entered email is correct! I guess this arises due to the presence of the dashes in the input.
So, can anybody tell me what to do?
Here's the part of the code where the issue arises (without the flushinput function):
void dobCheck(DATE dob) ///validates date of birth and rescans it if wrong
{
while(1)
{
if (dob.year<1806 || dob.year>2021 || dob.month<1 || dob.month>12 || dob.day<1 || dob.day >31)
{
dobCheckAct(dob); continue;
}
if ((dob.year%4)==0 && dob.month ==2 && dob.day >29)
{
dobCheckAct(dob); continue;
}
if (dob.year%4)!=0 && dob.month ==2 && dob.day >28)
{
dobCheckAct(dob); continue;
}
if (dob.month == 4 ||dob.month == 6 || dob.month == 9 || dob.month == 11) && dob.day> 30)
{
dobCheckAct(dob); continue;
}
break;
}
}
void dobCheckAct(DATE dob) ///action taken in case of invalid date of birth
{
printf("\a\n**INVALID DATE OF BIRTH!\n");
scanf("%d-%d-%d",&dob.day,dob.month,dob.year);
}
Thanks in advance!!

Something strange with if() in c

This is for a school project I'm working on, it's just a small part of the code but for some reason the program doesn't seem to go inside the if() no matter what the input is. I've tried anything and everything I know of (also used the isalpha() function) but it just won't run the commands inside the if().
do
{
flag=1;
gets(input.number);
printf("\n%s\n",input.number);
for(i=0;i<strlen(input.number);i++)
{
printf("yolo1\n"); //debug
if(input.number[i]<48 || input.number[i]>57) //PROBLEM HERE
{
printf("\nyolo2\n"); //debug
flag=-1;
break;
}
}
if(strlen(input.number)<1000 || strlen(input.number)>9999 || flag==-1) printf("\nINVALID INPUT\n\nARI8MOS: ");
}while(strlen(input.number)<1000 || strlen(input.number)>9999 || flag==-1);
Can you guys help me out here??? I've been staring and the code for the better part of 3 days now....
I presume you declared char input.number[].
Your condition in if says that you only want to get into its body if the character is NOT a digit. This is somehow contradictory to the name input.number of the variable (but perhaps you are just checking for incorrect characters here...)
To better see what is happening with the condition, you can choose to print the values of its components, like this:
printf("%c[%d]", input.number[i], input.number[i]);
printf("%d, %d, %d\n", input.number[i]<48 , input.number[i]>57, input.number[i]<48 || input.number[i]>57);
(you will se a 0 for false and 1 for true)
BTW: You could write the same condition in a more readable manner, using char constants like this:
input.number[i]<'0' || input.number[i]>'9')

If you have to put breaks in the if statements, why do we need to bother with conditions in the while operation?

This is just a general question really.
I wrote this originally
do
{
scanf("%i", &Carselect);
if (Carselect == 1)
{
mass = 1100;
velomax = 200;
}
else if (Carselect == 2)
{
mass = 1888;
velomax = 415
}
else if (Carselect == 3)
{
mass = 18000;
velomax = 129;
}
else
{
printf("Error in input. Please enter 1, 2 or 3.\n");
}
}
while (Carselect != 1 || Carselect != 2 || Carselect != 3);
And I got stuck in the loop. I put breaks in the statements for the valid conditions and that allowed me to get out, like this
do
{
scanf("%i", &Carselect);
if (Carselect == 1)
{
mass = 1100;
velomax = 200;
break;
}
else if (Carselect == 2)
{
mass = 1888;
velomax = 415;
break;
}
else if (Carselect == 3)
{
mass = 18000;
velomax = 129;
break;
}
else
{
printf("Error in input. Please enter 1, 2 or 3.\n");
}
}
while (Carselect != 1 || Carselect != 2 || Carselect != 3);
but I thought that the conditions for while were repeat conditions, so as soon as Carselect equals 1, 2 or 3 it will exit the loop. If you have to put breaks in the if statements, why do we need to bother with conditions in the while operation?
What is there, on the machine level or otherwise, that requires this seemingly trivial bit of logic?
Edit (as the question's title is changed):
The checking condition in the while/do-while loop is the one that is primarily checked to determine if the program is to stay in or to get out of the while/do-while loop - not the break statement.
The break statement is normally used if:
you want to get out of the while/do-while block before it is executing every statement in the block or
when certain exceptional termination condition is reached before you loop through your entire loop iteration or
You create an infinite loop and you capture an error which makes you unable to continue the loop or
Some other other cases which I might not be aware of...
Essentially, break-statement is not normally used to terminate the while/do-while block as long as the program follows (for lack of better term) "standard/main" path in the loop block.
In contrast, condition in the while/do-while loop is used to terminate the loop when the program follows "standard/main" path in the loop block.
Original:
You should change your inequality check (!=) into NOT equality check (==).
while (!(Carselect == 1 || Carselect == 2 || Carselect == 3));
This is because what you really want is for the loop to continue as long as
the Carselect is not (1 or 2 or 3)
Alternatively, you could change the or operator (||) to and operator (&&) which results in the same logic:
while (Carselect != 1 && Carselect != 2 && Carselect != 3);
the Carselect is not 1 and not 2 and not 3
In C break takes you to the statement immediately following } of the containing block, and continue takes you to to the statement immediately following { of the containing block. Both are useful in a long block, for example if an error condition occurs, or if a simpler input is detected, and not all the processing of the complete block is required, but you want to continue and get the next input.

Parameters inside the function

I have a work to do in which I have to keep a loop inside the function expecting the following parameters:
-"i" to insert
-"s" to search
-"q" to quit
How do I keep this loop? I've looked up some options and it seems to be possible using a while or a switch, but I am not sure which is the best way to read those chars (with a fscanf perhaps?). I am also not sure how to read the things after the parameter "i" as the input would be "i word 9", so after detecting the i to insert I have to read a string and an int.
Anyone has any idea how to do this? I am sorry is this seems simple, but I am new to programming.
edit: Here is what I have so far
while (loop) {
fscanf(stdin,"%c",&par);
if (strcmp(&par,"i")){
scanf("%s %d",palavra,p);
raiz = insere(raiz,&palavra,p);
}
else if (strcmp(&par,"b")){
scanf("%s",palavra);
busca(raiz,&palavra);
}
else if (strcmp(&par,"q"))
loop = 0;
}
edit 2: This is what I have now, I am having problems reading the string and integer when the parameter is i, somehow it crashes the function
while (1) {
c = getchar();
if (c == 'f')
break;
else if (c == 'i'){
fscanf(stdin,"%s",&palavra);
scanf("%d",&p);
raiz = insere(raiz,palavra,p);
}
else if (c == 'b') {
scanf("%s",palavra);
busca(raiz,palavra);
}
}
Thanks in advance!
The code you have doesn't look too bad compared to what I believe you want. You can replace the "while (loop)" with "while (1)" and then your exist code "loop = 0;" with "break;" which is a bit more standard way of doing things. Also "fscanf(stdin..." is the same as "scanf(..." ... scanf will read from stdin by default. You might want to check the docs for strcmp because it returns 0 for an exact match and I don't think that will do what you want in your 'if' statements. You should be able to use scanf to read in the values you want, is it giving you an error?
You are using 3 separated scans. That means you can't input this "i word 9", but input one command or parameter at the time separated by EOL(pressing enter).. i, enter, word, enter, 9, enter ... Then the function should actually get further in those "if"s. With those scans you also should consider printing information about expected inputs ("Choose action q/i/f")
And I would recommend using something to test those inputs.
if (scanf("%d", &p) == 0) {
printf("Wrong input");
break;
}

Resources