Problem while defining conditions for multiple variables in C - c

I'm trying to write a program in C that receives three integers and uses This Method
But I only want the inputs to be in the range of 1-100 (including 1 and 100)
#include <stdio.h>
int main(){
int a , b , c = 50;
do{
scanf("%d %d %d", &a, &b, &c);
}
while((a > 100 || a < 1)&& (b > 100 || b < 1) && (c > 100 || c < 1));
if (a+b > c && a+c>b && b+c>a){
printf("%d\n", a+b+c);
}
else {
printf("invalid\n");
}
And it somehow doesn't consider the conditions
for example if I enter something like 1000 -5 4 It won't reprompt me for a new input
But the weird thing is that if i only consider one of the conditions it will work fine with that one variable! for example if i put something like while((a > 100 || a < 1); in there, it will then reject an input like 1000 2 4
How do I make it that it considers the conditions for all the variables?
Any help would be appreciated!

To check for any of the variable for range, change
while((a > 100 || a < 1)&& (b > 100 || b < 1) && (c > 100 || c < 1));
^^
// Will produce a FALSE value if 'a' is within expected range, and due to
// short-circuit, it'll not evaluate other conditions.
to
while((a > 100 || a < 1) || (b > 100 || b < 1) || (c > 100 || c < 1));
That said, couple of other points:
int a , b , c = 50; only initializes c, other variables are uninitialised and contain indeterminate values. Be a little more explicit, declare and define each variable in separate line (not a technical requirement, sake of readability and maintainability while being technically correct).
Always check for the success of scanf(), before using the scanned values. Better, do away with scanf() for user inputs and use fgets() instead.

more readable :
while(!( 1 <= a && a <= 100 && 1 <= b && b <= 100 && 1 <= c && c <= 100));

Your loop will only continue if all three of a, b, and c are out of range - in your example of 1000 -5 4, the condition (c > 100 || c < 1) evaluates to false (0), so the whole expression evaluates to false and the loop exits.
You need to change the sense of the test, such that it will continue if any of a, b, or c are out of range. There are a couple of ways to do this:
while ( (a < 1 || a > 100) || (b < 1 || b > 100) || (c < 1 || c > 100) );
Changing the && to || means that the expression will evaluate to true and the loop will continue if any one of a, b, or c are out of range.
Another option:
while ( !(1 <= a && a <= 100) && (1 <= b && b <= 100) && (1 <= c && c <= 100 ) );
This will cause the loop to exit if all three of a, b, and c are in range.
You should also check the result of scanf to make sure you read all 3 inputs:
do
{
if ( scanf ( "%d %d %d", &a, &b, &c ) != 3 ) )
{
if ( feof( stdin ) || ferror( stdin ) )
{
fputs( "Error or EOF on input, exiting", stderr );
return EXIT_FAILURE;
}
else
{
fputs( "Bad input detected, clearing input stream", stderr );
/**
* Read and discard everything up to the next newline character
*/
while ( getchar() != '\n' )
; // empty loop
/**
* Unconditionally branch back to the beginning of the loop since
* at least one of a, b, and c wasn't read at all (i.e., don't
* rely on the test since what you're testing isn't valid).
*/
continue;
}
}
} while ( (a < 1 || a > 100) || (b < 1 || b > 100) || (c < 1 || c > 100 ) );

Related

Connect Four Check Winner

So to change my question. It refuses to recognize that there are four twos in a row. It recognizes that there are four ones in a row but that happens after the four twos. Why is this happening?
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 1 1 1 1 0 0
1 2 2 2 2 0 0
int checkFour(int a, int b, int c, int d){
if (a == b == c == d){
return 1;
}
else{
return 0;
}
return 0;
}
//check for the horizontal win
int checkHorizontal(){
for(int i=0; i < rows; i++){
for(int j=0; j < column - 3; j++){
if ((board[i][j] != 0) && (board[i][j+1] != 0) && (board[i][j+2]!= 0) && (board[i][j+3] != 0)){
if (checkFour(board[i][j],board[i][j+1],board[i][j+2],board[i][j+3]) == 1){
printf("Game Over\n");
exit(0);
}
}
}
}
}
What am I doing wrong?
if (a == b == c == d){ does not work the way you might think. The result of a comparison in C is a boolean value of 0 or 1. Given that == operator has left-to-right associativity, your statement can be re-written as:
if ((((a == b) == c) == d)
This appears to give correct results when they are all 1. This is because it ends up comparing the values (1) to the result of the comparison operation, also (1).
(((a == b) == c) == d) a == b -> 1
((1 == c) == d) 1 == c -> 1
(1 == d) 1 == d -> 1
The correct way is to use logical AND.
if (a == b && a == c && a == d)
All three comparisons need to evaluate to true for the entire statement to be true.
Note that there are other combinations that work. Ex:
if (a == b && b == c && c == d)
By the way, you can shorten the entire function to
int checkFour(int a, int b, int c, int d){
return a == b && b == c && c == d;
}
The problem is that you misunderstood the mechanism of C. the code if (a == b == c == d) wouldn't take if abcd are all values equal then return 1. because C computes from left to right(same priority), so it would compute a == b first, the result is 1 or 0, then take this result to compare with c, the second result also is 1 or 0, finally take second result to compare with d and the final result is come out.
The right code is like this:
if ((a == b) && (d == c) && (b == c))
return 1;
else
return 0;

Why wont this print any output? (c programming language)

Not sure why nothing is coming out, compiler finds no errors, it just runs and terminates a few seconds later, no output.
I'll give the source code and the input file's text.
Source code:
letterArray.c
#include <stdio.h>
/* displays a histogram of the frequencies
of letters in input */
main()
{
int c, i, nwhite, nother;
int nletter[26];
nwhite = nother = 0;
for (i = 0; i < 26; ++i)
nletter[i] = 0;
while ((c = getchar()) != EOF)
if (c == 'a' || c == 'b' || c ==
'c' || c == 'd' || c == 'e' || c == 'f' ||
c == 'g' || c == 'h' || c == 'i' || c ==
'j' || c == 'k' || c == 'l' || c == 'm' ||
c == 'n' || c == 'o' || c == 'p' || c ==
'q' || c == 'r' || c == 's' || c == 't' ||
c == 'u' || c == 'v' || c == 'w' || c ==
'x' || c == 'y' || c == 'z')
++nletter[c];
else if (c == ' ' || c == '\n' || c
== '\t')
++nwhite;
else
++nother;
printf("Letter: a b c d e f g h i j
k l m n o p q r s t u v w x y z
\nOccurences:");
for (i = 0; i < 26; ++i)
printf(" %d", nletter[i]);
printf("\nwhite space = %d, other =
%d\n", nwhite, nother);
}
Text input: input.txt
abcdefg hijklmnop qrstuv wxyzz
I'm pretty new to c, and to programming in general. Any help would be appreciated.
Your compiler should be warning you that the index for your nletter array will be out of bounds -- which will invoke Undefined Behavior..
The problem causing you to write beyond the bounds of nletter is your failure to insure the indexing you use runs 0-25. Specifically you attempt:
++nletter[c];
where c will contain the ASCII value from 'a' - 'z' (or 97 - 122) see: ASCIItable.com. That is well above the usable indexes available (0 - 25) resulting from your declaration of: int nletter[26]; (recall, arrays are indexed from 0 to n-1 in C).
To prevent writing beyond the bounds of your array, you need to normalize the indexes such that 'a' will correspond to 0 and 'z' will correspond to 25. You do this by simply subtracting 'a' from the value of c, e.g.
++nletter[c - 'a'];
although I prefer the post-increment operator here, so:
nletter[c - 'a']++;
(the choice of the increment operator is yours -- the result is the same)
Putting it altogether, and adding a few clean-ups as described in the comments below, you could do something like:
#include <stdio.h>
int main (void) /* main() is a function that return type int */
{
int c, i, nwhite, nother;
int nletter[26] = {0}; /* {0} will initialize nletter */
nwhite = nother = 0;
while ((c = getchar()) != EOF) {
if ('a' <= c && c <= 'z')
nletter[c - 'a']++; /* you want indexes from 0-25 */
else if (c == ' ' || c == '\n' || c== '\t')
nwhite++;
else
nother++;
}
printf ("Letter: a b c d e f g h i j k "
"l m n o p q r s t u v w x y z\n"
"Occurences:");
for (i = 0; i < 26; ++i)
printf ("%2d", nletter[i]); /* use the field-width modifier to */
/* insure output of 2 spaces per-int */
printf("\nwhite space = %d, other = %d\n", nwhite, nother);
return 0;
}
(Note: you can simplify further by including ctype.h and checking islower(c) instead of 'a' <= c && c <= 'z' and using isspace(c) instead of c == ' ' || c == '\n' || c== '\t', but since your Question didn't specify whether you could use anything but stdio.h I left the manual checks in place.)
Example Use/Output
$ echo "abcdefg hijklmnop qrstuv wxyzz" | ./bin/letterfreq
Letter: a b c d e f g h i j k l m n o p q r s t u v w x y z
Occurences: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2
white space = 4, other = 0
(if testing on windows, omit the quotation marks or you will see other = 2)
If you are just getting started, then always compile with "warnings-enabled" and read and fix all warnings -- do not accept code until it compiles cleanly -- without a single warning. That will catch most problems before you end up scratching your head for hours. For gcc/clang, that means adding, at minimum, -Wall -Wextra to your compile string (you can add -pedantic for a few more, and adding -Wshadow is helpful). For VS, use /W3 -- the /Wall for VS contains quite a few non-code related suggestions as warnings.
A compile string for this code would look like:
gcc
gcc -Wall -Wextra -pedantic -Wshadow -std=c11 -Ofast -o letterfreq letterfreq.c
VS
cl /nologo /W3 /Ox /Feletterfreq /Tc letterfreq.c
In either case, the code should compile without warning.

Why does this following program print "Yes" instead of "No"?

Why does this following program print "Yes" instead of "No"?
None of the variables is initialized to 2.
bool hello = 0;
int a = 1;
int b = 3;
int c = 4;
int d = 5;
if (a || b || c || d == 2) {
hello = 1;
}
if (hello == 1) {
printf("Yes");
}
if (hello == 0) {
printf("No");
}
return 0;
}
The statement
if (a || b || c || d == 2)
is equivalent to:
if (a != 0 || b != 0 || c != 0 || d == 2)
The equality comparison does not automatically distribute across all the variables. If you want to do that, you need to perform all the comparisons explicitly:
if (a == 2 || b == 2 || c ==2 || d == 2)
The expression (a || b || c || d == 2) evalutates to true because it treats a, b, c as booleans, and any non-zero integer is true.
You have given logical operator in the expression It means that if non zero value came then the expression is true. Then hello=1 is set and in next f statement it prints YES
You just meet the short circuit behavior of logical expressions OR.
The order of evaluation of logical OR || is left to right.
So in the following expression:
left || right
if left = true then right will never going to be executed (short circuit). In your code exactly same happened.
As you know, any non zero value treated as true in C, hence, a which is 1 is true. So, take a look:
if (a || b || c || d == 2)
if (true || bla bla bla) //rights are not even checked!
if (true)
hello = 1;
Tada! So the program print "Yes"!
None of the variables is initialized to 2.
Yes of course! But your if condition is not going to check that. To do so, try this:
if (a == 2 || b == 2 || c ==2 || d == 2) {
//...
because if judge num is not zero , if think this is true. so your code
if (a || b || c || d == 2)
like
if ( true || true || true || false)
the result is true, programe print "YES"

How to write a while statement in c?

I should write a C while statement that continues while x is both larger than 10 and a multiple of either 6 or 7. I only need to include the actual while statement, not the entire loop!
I know it may look funny to you, but this is what I have so far.
#include<stdio.h>
int main(){
int x;
while (x > 10, x % 7 = 0 || x % 6 = 0) {
printf("%d\n", x);
}
}
Logical and is &&. As an operator, , is "ignore the result of the thing to the left".
Your Boolean logic and comparison both use the wrong syntax. It should be like this:
while (x > 10 && (x % 7 == 0 || x % 6 == 0)) {
The comma (,) is not a valid Boolean operator. What you wanted is && (logical AND). You need parentheses around the other two expressions because AND (&&) has higher precedence than OR (||).
And = is for setting values; == is for comparing them.
Finally, as others pointed out, you don't set x anywhere in the code that you have posted. So, your loop will not run. And you don't modify x in the loop, so, if you ever get into the loop, you will never get out.
The program can look like
#include <stdio.h>
int main( void )
{
int x;
printf( "Enter an integer number: " );
scanf( "%d", &x );
while ( x > 10 && ( x % 7 == 0 || x % 6 == 0 ) )
{
printf( "%d\n", x );
printf( "Enter next integer number: " );
scanf( "%d", &x );
}
}
Or you could enlarge the condition in the while loop the following way (to check that the input is correct)
#include <stdio.h>
int main( void )
{
int x;
printf( "Enter an integer number: " );
while ( scanf( "%d", &x ) == 1 && x > 10 && ( x % 7 == 0 || x % 6 == 0 ) )
{
printf( "%d\n", x );
printf( "Enter next integer number: " );
}
}
As for your condition in the while loop then it has two errors
while (x > 10, x % 7 = 0 || x % 6 = 0)
It uses the comma operator instead of logical operator && and it uses the assignment operator as for example x % 7 = 0 instead of the comparison operator x % 7 == 0. Also variable x was not initialized.
Your while statement should read
while (x > 10 && (x % 7 == 0 || x % 6 == 0))
Note the use of && for "boolean and", and == for "equality comparison".
I should Write a C while statement that continues while x is both
larger than 10 and a multiple of either 6 or 7. I Only need to include
the actual while statement, not the entire loop!
Let's analyze the condition that will go in the while() statement:
x is both larger than 10 and a multiple of either 6 or 7
Can be expressed as
x is greater than 10 AND a multiple of 6 OR multiple of 7
So let's code that in C:
x is greater than 10
x>10
AND
&&
x multiple of 6 OR x multiple of 7
(x%6)==0 || (x%7)==0
Then, all together
x>10 && ( (x%6)==0 || (x%7)==0 )
So your while sentence is like this:
while (x>10 && ( (x%6)==0 || (x%7)==0 ))
{
stuff...
}
Here can be the Solution Ava
while (x > 10 && (x % 7 == 0 || x % 6 == 0)) {

C Programming: What conditions do I put for an if statements for numbers 1 to 35 inclusive?

Okay I need help with translating sentences to condition statements in C.
For example, if I want my input to be from 1 to 35 (inclusive), and only want odd integer inputs, how would I go about making a conditional statements?
Is it:
int n;
while(1){
printf("What is the value for n you wish to use (please use an odd number?: ");
scanf("%d", &n);
if(n%2=0 && n<=35 && n>=1)
if(n<1)
break;
}
if (n%2=0 && n<=35 && n>=1)
is (almost) the condition for even numbers, those exactly divisible by 2. Note that the equality operator is ==. For odd, you want
if (n%2==1 && n<=35 && n>=1)
With this, you do not need any more if statements.
This n%2=0 should be (for odd numbers) n%2 == 1
And if you want to break on a number not matching your conditions, use something like this in the loop:
if(!((n%2 == 1) && (n<=35) && (n>=1)))
break;
}
Now if you want to break from a loops if any one of following condition get satisfies
The number must be above 1
The number must be below 35
The number must be odd
Then you can write:
if(n%2==1 || n>=35 || n<=1) break;
First, let's define the tests for 1 to 35 inclusive. C supports short circuiting, we should test the simple things -
if (n > 0 && n < 36) /* <---- 1 to 35 */
if (n >= 1 && n <= 35) /* <---- 1 to 35 */
or
#define MIN 1
#define MAX 35
if (n >= MIN && n <= MAX) /* MIN to MAX */
However, your code is incorrect. The second if will ever evaluate to true since the first requires n>=1
if(n%2=0 && n<=35 && n>=1)
if(n<1)
break;
I believe you wanted
if (n > 35 || n < 1) {
break;
}
A test for even should just continue (and not end the loop), or you could test for odd and just display those,
if (n % 2 == 0) continue;
or
if (n % 2 != 0) printf("%i\n", n);

Resources