If else not read third condition in C - 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).

Related

C - OR in IF statements not working has I want

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.

Nested if statement in C - why doesn't it evaluate the last else if?

The following code does not execute the last else if statement when you assign to choice value 3.
#include<stdio.h>
#include<stdlib.h>
int main() {
puts("Specify with a number what is that you want to do.");
puts("1. Restore wallet from seed.");
puts("2. Generate a view only wallet.");
puts("3. Get guidance on the usage from within monero-wallet-cli.");
unsigned char choice;
choice = getchar();
if ( choice == '1' ) {
system("nice -19 ~/monero-x86_64-linux-gnu-v0.17.2.0/monero-wallet-cli --testnet --restore-deterministic-wallet");
exit(0);
}
else if ( choice == '2' ) {
system("nice -19 ~/monero-x86_64-linux-gnu-v0.17.2.0/monero-wallet-cli --testnet --generate-from-view-key wallet-view-only");
exit(0);
}
else if ( choice == '3' ) {
puts("Specify with a number what is that you want to do.");
puts("1. Get guidance in my addresses and UTXOs");
puts("2. Pay");
puts("3. Get guidance on mining.");
unsigned char choicetwo = getchar();
if ( choicetwo == '1' ) {
printf("Use \033address all\033 to get all your addresses that have any balance, or that you have generated at this session.");
printf("Use \033balance\033 to get your balance");
printf("Use \033show_transfers\033 to get ");
printf("Use \033show_transfers\033 out to get ");
printf("Use \033show_transfers in\033 to get your balance");
}
}
return 0;
}
I get the following output When I enter 3:
Specify with a number what is that you want to do.
1. Restore wallet from seed.
2. Generate a view only wallet.
3. Get guidance on the usage from within monero-wallet-cli.
3
Specify with a number what is that you want to do.
1. Get guidance in my addresses and UTXOs
2. Pay
3. Get guidance on mining.
I'm really blocked, something is missing and I have no clue why it does not proceed to take the input from the user for the second time.
When you enter "3" for the first input, you're actually inputting two characters: the character '3' and a newline. The first getchar function reads "3" from the input stream, and the second one reads the newline.
After accepting the first input, you'll want to call getchar in a loop until you read a newline to clear the input buffer.
choice = getchar();
while (getchar() != '\n');

C - segmentation fault when comparing integers

here is a part of my code. When I run my code, it's requesting an input from user and then matching it with another integer which recorded in my structure. When user input is matching, it is working correct. But when user enters a wrong input, it gives a segmentation fault. In where, I should make changes on my code?
long int userInput,endCheck; // Input from user
int flag=0; // check for match
int status;
int c; // controlling ctrl+D
int position= 999; // position of where the user input and data matched
LABEL:
printf("\n\t---------------------------------------\n");
printf("\n\nPlease enter the student ID which you want to find(3-times CTRL+D for finish):\n");
scanf("%d",&userInput);
if( (c=getchar()) == EOF){
exit(0);
}
for(i=0;i<lines,flag==0;i++){
if(index[i].id == userInput){
position=i;
flag=1;
}else{
position=999;
}
}
if(flag==0){
printf("id not found");
}
studentInfo info; // for storing the information which we will take between determined offsets
if(position!= 999){
if ( (pos = lseek(mainFile,index[position].offset , SEEK_SET)) == -1)/*going to determined offset and setting it as starting offset*/
{ perror("classlist"); return 4; }
while ( (ret= read(mainFile,&info, sizeof(info))) > 0 ){
printf("\n\nStudent ID: %d, Student Name: %s\n\n",info.id,info.name);
break;// to not take another students' informations.
}
}
flag=0;
goto LABEL;
printf("Program is terminated");
The right way to do that loop with the unwanted comma is like this. When you find the right index[i].id you can exit the loop early by using break.
for(i=0;i<lines;i++){
if(index[i].id == userInput){
position=i;
flag=1;
break;
}
}
You don't need the else branch as position is set to 999 from the outset of the code. But really you shouldn't use position in this fashion. What if you have more than 999 records? You're already using flag to identify if you've set position to a valid value. You should replace any instance of if(position!= 999) with if(flag).
Or since position is a signed int, you could use a negative value and ditch the flag.
The reason can be the fact that you are reaching an index that doesn't exist in the end of cycle, in the moment of the "if" statement with iterator "i".
Or in the last if, where you access a "position" index of the array. Check those limits.
Also, try GDB, is useful for solving this kind of problems.

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.

C: Scanf in while loop executes only once

I am trying something simple in C, a program to get the exchange and do some conversions.
To make sure scanf gets the right type I placed it into a while loop, which continues to ask for input until a number is inserted.
If I enter a character instead of a number it does not ask again for an input.
exRate = 0;
scanfRes = 0;
while(exRate <= 0){
printf("Enter the exchange rate:");
while(scanfRes != 1){
scanfRes = scanf(" %f", &exRate);
}
if(scanfRes == 1 && exRate > 0){
break;
}
printf("Exchange rate must be positive.\n");
}
UPDATE: As this is a course assignment, I was not supposed to use anything outside of the taught material. When I asked the academic staff about handling unexpected input, I got an answer that this is a scenario I am not supposed to take into consideration.
The answers and help in the comments is all useful and I added 1 to all useful suggestions. The staff answer makes this question no longer needed.
Change handling of scanf() result.
If the input is not as expected, either the offending input data needs to be read or EOF should be handled.
for (;;) {
printf("Enter the exchange rate:");
scanfRes = scanf("%f", &exRate);
if (scanfRes == 0) {
printf("Exchange rate must be numeric.\n");
// somehow deal with non-numeric input, here just 1 char read & tossed
// or maybe read until end-of-line
fgetc(stdin);
} else if (scanfRes == EOF) {
// Handle EOF somehow
return;
} exRate > 0){
break;
}
printf("Exchange rate must be positive.\n");
}
Note: the " " in " %f" is not needed. "%f" will consume leading white-space.

Resources