Struggling with arrays and scaning things into them - c

I am working on my homework for my computer science class and this code is part of a large chunk that is not yet written, my question is on the syntax for my arrays and reading floats into them. We have not gone over this yet but I knew this should be possible based on other programming languages that I have learned. Also on the second if statement would that syntax be right or would it be something else like if (answer == "Y" || "y").
#include <stdio.h>
#include <stdbool.h>
int main()
{
float test_scores[100], ts;
char answer;
bool repeat = true;
while (repeat)
{
printf("Enter in a test score:\n");
if (ts>=0 && ts<=110)
{
scanf("%f", &test_scores[ts]);
printf("You have entered in: %.2f\n", test_scores[ts]);
}
printf("Would you like to add another test score: Y/N\n");
if ((answer = "Y" || "y"))
{
scanf("%c", &answer);
printf("You have chosen to enter in another score.\n");
}
else
{
repeat = false;
}
}
return 0;
}

scanf("%c", &answer);
if ((answer = "Y" || "y"))
two lines - plenty problems.
ALways check the result of the scanf
answer = "Y" || "y" assigns the result of the logical expression which checks if the pointer to string literal "Y" is not NULL, which is 1. As a || b id a is true evaluates to true the second part is not eveluted. So the answer will be assigned with the integer 1. if ((answer = "Y" || "y")) is always true.
answer is char. "Y" and "y" are strings and those cannot be compared (at least let us make this simplifying assumption)
it has to be:
if (answer == 'Y' || answer == 'y')
test_scores[ts]: ts is float but only integers can be used as array subscripts.
I did not analyze the logic of the program.
Generally, I would suggest a good C book as you need to learn the basic topics.

Related

If statement executing regardless of the condition [duplicate]

This question already has answers here:
Program not recognizing character inputs in if-else statements
(5 answers)
Closed 1 year ago.
I'm writing a C program that asks the user for a variety of inputs, one is a Yes or No question. If you put Y, or y, the If statement is supposed to execute. However, no matter what you input, it goes through with the If statement.
double phonePrice;
double phoneTax;
double phoneTotal;
double phoneApplePrice;
double phoneSubtotal;
double temp;
int yearsAppleCare;
char userAnswer;
//prompting for price
printf("Enter the price of the phone> ");
scanf("%f", &phonePrice);
fflush(stdin);
//prompting for iphone
printf("Is the phone an iPhone (Y/N) ?> ");
scanf("%c", &userAnswer);
fflush(stdin);
//nested if statements asking for apple care amount
if(userAnswer=="Y"||"y")
{
printf("Enter the number of years of AppleCare> ");
scanf("%d", &yearsAppleCare);
if(yearsAppleCare<=0)
{
printf("You must choose at least 1 year of AppleCare");
return 0;
}
}
Any help with this would be appreciated.
For starters this call
fflush(stdin);
has undefined behavior. Remove it.
Instead of this call
scanf("%c", &userAnswer);
use
scanf(" %c", &userAnswer);
^^^^
to skip white spaces in the input buffer as for example the new line character '\n'.
Also for double variables use the conversion specifier %lf. For example
scanf("%lf", &phonePrice);
The condition in the if statement
if(userAnswer=="Y"||"y")
is equivalent to
if( ( userAnswer=="Y" ) || ( "y" ) )
As the string literal "y" that is implicitly converted to a pointer to its first element is not equal to a null pointer then the condition always evaluates to logical true.
You need to write
if( userAnswer == 'Y' || userAnswer == 'y' )
using integer character constants 'Y' and 'y' instead of the string literals.
Error is here:
//nested if statements asking for apple care amount
if(userAnswer=="Y"||"y")
{
Should be:
//nested if statements asking for apple care amount
if(userAnswer == "Y" || userAnswer == "y")
{
Wait! No!
Should be:
//nested if statements asking for apple care amount
if( strcmp(userAnswer, "Y") == 0 || strcmp(userAnswer, "y") == 0)
{
Why?
What does == mean?
In C language, == means the two objects are equal. In the case of strings, the objects are char*, I.e. pointers to char. These will be equal if and only if the memory address is the same. This will not be true in this case.
Why? Because one string is compiled into the program and initialised as the program starts, and the other is provided by the user into temporary memory. These will be at different addresses so the pointers will not be the same.
What you probably want is to compare the contents of the memory locations pointed to by the two pointers.
For that purpose the strcmp function is provided. This function returns zero if the strings are the same. You may also want to consider stricmp.

declaration shadows a local variable in c

I am using the cs50 library and ide and when trying to compile this program I get errors saying that the variable 'answer' has already been declared and I don't know how to solve this any answers would be appreciated I am really stuck on this as I have just began to learn how to program the error log is:
char.c:9:14: error: declaration shadows a local variable [-Werror,-Wshadow]
char answer = get_char("are you okay")
char.c:6:10: note: previous declaration is here
char answer;
char.c:20:12: error: variable 'answer' is uninitialized when used here [-Werror,-Wuninitialized]
while (answer != 'y' && answer != 'Y' && answer != 'n' && answer != 'N');
char.c:6:16: note: initialize the variable 'answer' to silence this warning
char answer;
The code is:
#include <cs50.h>
#include <stdio.h>
int main(void)
{
char answer;
do
{
char answer = get_char("are you okay Y/N ");
if (answer == 'y' || answer == 'Y')
{
printf("you are okay");
}
else if (answer == 'n' || answer == 'N')
{
printf("you are not okay ");
}
}
while (answer != 'y' && answer != 'Y' && answer != 'n' && answer != 'N');
}
Note, the warning messages in your post are very helpful. Do not be shy about simply following their suggestions in-order one-by-one. (They are what I used to make the suggestions below.)
The shadow is caused by the second declaration of answer inside the do block:
char answer;// original declaration (the shadow)
do
{
char answer = get_char("are you okay Y/N ");//2nd declaration (being shadowed)
To Fix, do this
char answer;// leave this declaration to allow proper scope
do
{
answer = get_char("are you okay Y/N ");// uses same instance of 'answer' (no shadowing)
^^^^ removed second instance of `char`
There is a C specific discussion on variable shadowing here, and another more broad discussion here
Within the compound statement of the do-while loop you need to use the same variable answer that is declared before the loop.
char answer;
do
{
answer = get_char("are you okay Y/N ");
if (answer == 'y' || answer == 'Y')
{
printf("you are okay");
}
else if (answer == 'n' || answer == 'N')
{
printf("you are not okay ");
}
}
while (answer != 'y' && answer != 'Y' && answer != 'n' && answer != 'N');
Otherwise this declaration within the compound statement of the do while loop
char answer = get_char("are you okay Y/N ");
hides the declaration of the variable with the same name before the while loop and moreover this variable is not alive outside the loop.
Pay attention to that the do-while loop is defined in C the following way
do statement while ( expression ) ;
For example you may write
do ; while ( expression );
where a sub-statement of the do-while statement is the null statement ;.
If you use a compound statement as the sub-statement like
do { /*...*/ } while ( expression );
then this compound statement forms its one scope and all variables with automatic storage duration are not alive outside the compound statement.
Also instead of call printf like this
printf("you are okay");
it is better to use a call of puts like
puts("you are okay");
because the call of puts also appends an output of the new line character '\n'.
try removing the char in
char answer = get_char("are you okay Y/N ");
as it is declared outside the loop
and initilize it to char answer="";

Else If condition given precedence over while condition?

Please excuse this beginner's question. I've just started programming and I'm using C for the code below.
The purpose of this code is for the computer to guess a number the user has picked. The computer will narrow down the numbers available based on queues like 'too low' or 'too high'.
computer_guess(int answer)
{
int lownum, highnum, guess, answer;
//Instructions
printf("Please use 'h' for too high or 'l' for too low ");
printf("for incorrect guess. Use 'c' if the guess is right.\n");
guess = (lownum + highnum)/2;
printf("\n %d. \n", guess);
printf("Is this the right number?");
do
{
answer = getchar();
if (answer == 'h')
{
guess = (lownum + (highnum -1))/2;
printf("%d \n", guess);
}
else if (answer == 'l') //If the computer's guess is too high.
{
guess = ((lownum + 1) + highnum)/2;
printf("%d \n", guess);
}
else if (answer != '\n')//If the user enters letters other than 'h' or 'l', an error message will be returned.
{
fflush(stdin);
printf("Invalid. Please use either h (too high), l (too low) or c (correct).");
}
} while (answer != 'c');
if (answer == 'c')//If the correct answer is given, the game will end.
{
printf("The computer has guessed the right number.");
}
return 0;
}
The problem I'm running into is that my code seems to ignore my while condition (while (answer != 'c')). In my output, even if I enter 'c', it prints the Error statement in the last "else if" block and statement about being right.
This is the output:
Invalid. Please use either h (too high), l (too low) or c (correct). The computer has guessed the correct answer!
What do I need to do to make sure the error isn't printed when 'c' is entered?
Thank you!
Statements of your program are executed in the order pre-defined by C standard. This includes the computation of the while condition of the do/while loop.
The loop checks the condition upon reaching the end of loop's body. This includes execution of all if statements inside the loop, along with their else branches. Since you have no special handling for 'c' inside your loop, if (answer != '\n') branch gets executed, and gives the printout that you see.
You can fix this by using a "forever" loop, and handling 'c' input inside its body:
for (;;) {
answer = getchar();
if (answer == 'c') {
break;
}
... // The rest of your code goes here
}

The code "should" work, but the program stops working

I'm a beginner with a few hours of expirience and I'm trying to make a really simple program to get familiar withe IF command. I came up with this code:
#include<stdio.h>
int main()
{
char ans;
char n;
char y;
printf("Do you want to exit?\n");
scanf("%c\n",ans);
if (ans == y)
{
printf("As you wish!\n");
return 0;
}
else (ans == n);
{
printf("You'll exit anyways!\n");
return 0;
}
}
I think it should work, but after I type something the program stops workig! Thanks in advance!
The
if (ans == y)
should read
if (ans == 'y')
The former compares ans to the value of the uninitialized variable y, whereas the latter checks whether ans contains the character 'y'.
The same goes for 'n'.
The y and n variables are unnecessary and can be removed.
Also, the following line is incorrect:
else (ans == n);
It should read
else if (ans == 'n')
(I've added the if and have removed the semicolon.)
Finally, the scanf() should read:
scanf("%c",&ans);
else (ans == n);
This doesn't give expected results. Remove the ; and the condition.
else may only take a body of code. It does not handle conditions.
If you want conditions, use else if:
else if (ans == 'n')
More errors:
if (ans == y)
y in here refers to the variable, which is declared but has no value. Surely you want to refer to the character 'y':
if (ans == 'y')
Also, scanf expects a pointer, so instead of ans, use &ans.
It needs to write to the memory address of the value. It doesn't care about the value.
You'll learn about pointers eventually. (Assuming you haven't gone over them in your few hours of experience)
There are three main errors.
You should pass pointers to the scanf function, so you have to add an ampersand before ans (&ans).
There is a trailing ; at the end of the else statement.
y refers to a variable (which does not exist), whereas you want to compare ans against the character 'y'.

Comparing user-inputted characters in C

The following code snippets are from a C program.
The user enters Y or N.
char *answer = '\0';
scanf (" %c", answer);
if (*answer == ('Y' || 'y'))
// do work
I can't figure out why this if statement doesn't evaluate to true.
I checked for the y or n input with a printf and it is there, so I know I'm getting the user input. Also when I replace the the condition of the if statement with 1 (making it true), it evaluates properly.
I see two problems:
The pointer answer is a null pointer and you are trying to dereference it in scanf, this leads to undefined behavior.
You don't need a char pointer here. You can just use a char variable as:
char answer;
scanf(" %c",&answer);
Next to see if the read character is 'y' or 'Y' you should do:
if( answer == 'y' || answer == 'Y') {
// user entered y or Y.
}
If you really need to use a char pointer you can do something like:
char var;
char *answer = &var; // make answer point to char variable var.
scanf (" %c", answer);
if( *answer == 'y' || *answer == 'Y') {
answer shouldn't be a pointer, the intent is obviously to hold a character. scanf takes the address of this character, so it should be called as
char answer;
scanf(" %c", &answer);
Next, your "or" statement is formed incorrectly.
if (answer == 'Y' || answer == 'y')
What you wrote originally asks to compare answer with the result of 'Y' || 'y', which I'm guessing isn't quite what you wanted to do.
For a start, your answer variable should be of type char, not char*.
As for the if statement:
if (answer == ('Y' || 'y'))
This is first evaluating 'Y' || 'y' which, in Boolean logic (and for ASCII) is true since both of them are "true" (non-zero). In other words, you'd only get the if statement to fire if you'd somehow entered CTRLA (again, for ASCII, and where a true values equates to 1)*a.
You could use the more correct:
if ((answer == 'Y') || (answer == 'y'))
but you really should be using:
if (toupper(answer) == 'Y')
since that's the more portable way to achieve the same end.
*a You may be wondering why I'm putting in all sorts of conditionals for my statements. While the vast majority of C implementations use ASCII and certain known values, it's not necessarily mandated by the ISO standards. I know for a fact that at least one compiler still uses EBCDIC so I don't like making unwarranted assumptions.
Because comparison doesn't work that way. 'Y' || 'y' is a logical-or operator; it returns 1 (true) if either of its arguments is true. Since 'Y' and 'y' are both true, you're comparing *answer with 1.
What you want is if(*answer == 'Y' || *answer == 'y') or perhaps:
switch (*answer) {
case 'Y':
case 'y':
/* Code for Y */
break;
default:
/* Code for anything else */
}

Resources