When I am trying to get the input for my variable, it is only meeting one of the requirements (ie: the < 1 requirement) and skips the other requirement even though im using the && operator.
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int x;
do {
x = get_int("what is the height of the pyramid?:");
} while (x > 0 && x < 8);
printf("%i", x);
}
I tried just using the x < 8 for the requirement but it still went through when I entered 9, 10, 11 etc.
If you want x to be between 0 and 8 (both ends exclusive), then you need to repeatedly ask for input when this condition is not satisfied.
In other words, when x is outside this range it means x is less than or equal to 0 OR greater than or equal to 8.
That said, I believe the proper input range for that problem set is actually 1-8 (both ends inclusive):
do {
x = get_int("What is the height of the pyramid?: ")
} while (x < 1 || x > 8);
The test is exactly the opposite of your intent. The do/while condition should test a condition for repeating the input and write while (!(x > 0 && x < 8)); or equivalently: while (x < 1 || x >= 8);
It is unclear what your requirements are, but it seems the number should be between 1 and 7 inclusively. If 8 should be included, the test should be modified as while (!(x > 0 && x <= 8)); or equivalently: while (x < 1 || x > 8);
do/while loops are often confusing and error prone. I suggest using a for(;;) aka for ever loop and break statements when conditions are met:
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int x;
for (;;) {
x = get_int("What is the height of the pyramid? ");
if (x == INT_MAX) {
printf("Input error or end of file\n");
return 1;
}
if (x > 0 && x < 8) {
break
}
printf("The height should be between 1 and 7\n");
}
printf("%i\n", x);
return 0;
}
Related
for example, if I enter 12, I want to get 81 41 as the set bits in 12 are 1100
This is what I have for now, I do not think I am implementing the for loop correctly
#include <stdio.h>
void bin(unsigned n)
{
char list[6];
int x = 0, y = 1;
/* step 1 */
if (n > 1)
bin(n / 2);
/* step 2 */
list[x] = n % 2;
x++;
/*for(int i = 0; i < x; i++) {
printf("%d\n",list[i]);
}*/
for(int i = 0; i < 5; i++) {
if(list[i] == 1 && i == 5) {
printf("32%i",y);
}
if(list[i] == 1 && i == 4) {
printf("16%i",y);
}
if(list[i] == 1 && i == 3) {
printf("8%i",y);
}
if(list[i] == 1 && i == 2) {
printf("4%i",y);
}
if(list[i] == 1 && i == 1) {
printf("2%i",y);
}
if(list[i] == 1 && i == 0) {
printf("1%i",y);
}
}
}
I checked that I was correctly storing the bytes in the array, and it outputted correctly, but when I try to look for them one at a time in a loop, it seems to get stuck on the 32 bit integer, so for 12, it would print 321 321
This program has Undefined Behaviour from accessing uninitialized values of list. I'm going to refactor this code so its easier to talk about, but know this refactored code is still incorrect.
x is always 0. y is always 1. x++ has no effect. This function can be rewritten as:
void bin(unsigned n)
{
char list[6];
if (n > 1)
bin(n / 2);
list[0] = n % 2;
for (int i = 0; i < 5; i++) {
if (list[i] == 1) {
switch (i) {
case 5: printf("321"); break;
case 4: printf("161"); break;
case 3: printf("81"); break;
case 2: printf("41"); break;
case 1: printf("21"); break;
case 0: printf("11"); break;
}
}
}
}
There are some problems here.
Firstly, list is not shared between calls to bin, nor are any other variables.
In every call to bin, only list[0] is assigned a value - all others indices contain uninitialized values. You are (un)lucky in that these values are seemingly never 1.
With your example of 12 as the starting value:
When you initially call bin(12), what happens is:
bin(12) calls bin(6), bin(6) calls bin(3), bin(3) calls bin(1).
Starting from the end and working backwards, in bin(1):
n = 1, so list[0] = n % 2; assigns 1. The loop checks each element of list for the value 1, finds it when the index (i) equals 0, and prints 11.
This is repeated in bin(3), as 3 % 2 is also 1, and again this result is assigned to the first element of list. Again, we print 11.
In bin(6), 6 % 2 is 0. The loop finds no elements of list that equal 1. Nothing is printed.
And again, this is repeated in bin(12), as 12 % 2 is 0. Nothing is printed.
To reiterate, it is pure luck that this program appears to work. Accessing list[1] through list[4] (i < 5 ensures you never access the last element) in each function call is Undefined Behaviour. It is generally not worth reasoning about a program once UB has been invoked.
When dealing with bits, it would be a good time to use some bitwise operators.
Here is a program that more-or-less does what you have described.
It assumes 32-bit unsigned (consider using fixed width types from <stdint.h> to be more precise).
This program works by repeatedly shifting the bits of our initial value to the right b number of places and testing if the rightmost bit is set.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
unsigned num = argc > 1 ? atoi(argv[1]) : 42;
unsigned b = 32;
while (b--)
if ((num >> b) & 1)
printf("%u1 ", 1 << b);
putchar('\n');
}
$ ./a.out 12
81 41
#include <stdio.h>
int main()
{
int x = 2, y = 0;
int m = (y |= 10);
int z = y && m;
printf("%d\n", z);
return 0;
}
Above program gives me output as 1. Below code is giving me output 0 but what is the reason for different outputs here?
#include <stdio.h>
int main()
{
int x = 2, y = 0;
int z = y && (y |= 10);
printf("%d\n", z);
return 0;
}
In
int z = (y |= 10);
y is masked with 10 so set to 10, so y && m is a boolean worth 1 because both y and m are non-zero, assigned to z
Now, in
int z = y && (y |= 10);
y == 0 so && short-circuits, not evaluating the right hand part and not changing the value of y. Therefore, z is set to 0.
Had you used:
int z = y & (y |= 10);
this would have depended on how/in which order the compiler evaluates the operands (implementation defined behaviour to get 0 or 10)
note that && short-circuiting doesn't evaluate the second parameter if the first is zero for a very good reason:
if ((pointer != NULL) && pointer->value == 12) { do_something(); }
this condition checks if the value is 12 but only if the pointer is non-NULL. If the second expression was evaluated first, this could crash.
I'm having some trouble doing a Nim game program. So far I have a program that will show a pyramid of pipes. It looks like the "start position" pyramid on this picture.
http://www.mathsisfun.com/puzzles/images/b-nim.gif
Anyways, I'm having trouble moving around this, whenever I try moving around, my cursor will move in completely erratic ways. Thid will make the game totally unplayable. I'm not sure if it is a problem with my counting variables or even some smaller thing I'm totally missing, anyways here's what I have:
#include <stdlib.h>
int nim()
{
char *tab;
if ((tab = malloc(sizeof(char) * 20 + 4)) == NULL)
return (-1);
tab = " | \n ||| \n ||||| \n |||||||\n"; /* this is indeed a nasty way to do it :P */
putstr(tab);
}
int move_normally()
{
char bffr[10];
int x;
int y;
x = 0;
y = 0;
while (42 && x <= 6 && y <= 3)
{
read(0, bffr, 10);
putstr(tgoto(tgetstr("cm", NULL), x, y);
if (bffr[2] == 66 && y <= 3 && x <= 6)
y++
else if (bffr[2] == 65 && x <= 6 && y <= 3 && (y - 1) >= 0)
y = y - 1;
else if (bffr[2] == 67 && x <= 6 && y <= 3)
x++
else if (bffr[2] == 68 && x <= 6 && y <= 3 && (x - 1) >= 0)
x++
}
}
So, is there something I'm missing here? everything else works almost perfectly and I can't get my hands on why this is giving trouble. Also, are there any other ways to do this? I'm open to any alternative way.
I'm very new to this, and i'm trying to create a text based minesweeper.
I want the player to decide how big he want the grid to be.
My problem is, that the if-statement, that should make sure, the user types in a number from 1 to 10 doesn't work. Please have a look.
scanf ("%i/%i",&x,&y);
if (0 < x < 11 && 0 < y < 11)
{
printf ("you have selected %i by %i\n",x,y);
for (i = 0; i < x; i++)
{
for (j = 0; j < y; j++)
{
grid[x][y] = 'O';
printf ("%c ", grid[x][y]);
}
printf ("\n");
}
}
else
printf ("Wrong gridsize");
C does not support double comparisons like:
0 < x < 11
you should write instead
0 < x && x < 11.
It may be misleading, because the first statement is syntaxically correct (it compiles), but it does not do what you may believe: check both boundaries like in a mathematical expression (what python does for instance).
It's like if you had written
(0 < x) < 11
The first binary expression returns a boolean (well, really an int in C, a boolean in C++). This boolean once casted to int is 0 or 1, always below 11, henceforth the expression is always true.
Of course the same is true for checking y boundaries. Now you should be able to fix the problem by yourself.
The if statement has to be like
if ((x > 0 && x < 11) && (y > 0 && y < 11))
you have written wrong if statement.
Here is correct form.
if ((x > 0 && x < 11) && (y > 0 && y < 11))
Here are the relational operators
> greater than 5 > 4 is TRUE
< less than 4 < 5 is TRUE
>= greater than or equal 4 >= 4 is TRUE
<= less than or equal 3 <= 4 is TRUE
== equal to 5 == 5 is TRUE
!= not equal to 5 != 4 is TRUE
C does not support double comparisons.
In your scanf statement remove / operator change it to
scanf ("%i%i",&x,&y);
And what your if statement is doing is what you expect to do
if (0 < x < 11 && 0 < y < 11)
first when you enter the value x and y (x = 4 and y = 6)
It checks if x is greater than 0 (which is true ) so 1 is substituted in place of 0 < x
now its something like this for compiler 1 < 11
next it checks that which is also true
similarly for y whichever value you enter will always be true.
0 < x < 11
means
(0 < x)<11. If x is 5, 0 < x will be 1 (true). Next evaluation will be 1 < 11, that will be true so the result is true.
But, if x = 20, 0<20 is 1, 1<11 is true as well, but you would expect a false result.
#include <stdio.h>
int main()
{
int X = 200;
float Y = 1500;
printf("Enter your initial Balance and the Amount to be Withdrawn. Note the Values should lie between 0 and 2000");
scanf("%d", "%e", &X, &Y);
if ((0 < X < 2000) && (0 < Y < 2000)) {
if ((X < Y) && (X % 5 == 0)) {
Y = Y - X;
Y = Y - 0.5;
} else {
printf("%f", Y);
}
printf("%f", Y);
} else {
printf("The Input is Wrong");
}
return 0;
}
The Code basically asks for some number X. Subtracts it from Y and an additional amount 0.5 from Y. We have to give the as Y.
The Code is giving Runtime Error which could possibly be due to More Memeory than allowed being used.
Can anyone give any tips on how to reduce memory usage or see if there is an error in the program?
scanf("%d,%e", &X, &Y);
(apart from the scanf() with the double format string, which has been handled by others)
if ((0 < X < 2000) && (0 < Y < 2000)) {
That does not work this way is C. You could try:
if (X > 0 && X < 2000 && Y > 0 && Y < 2000) {
Also note that you don't need the extra parentheses.
The same for the other line
if ((X < Y) && (X % 5 == 0)) {
Which could be:
if (X < Y && X % 5 == 0) {
Sometimes the rules of precedence are not that bad at all...
I don't know if this is homework...
... but this example might help clarify a few things:
#include <stdio.h>
int
main(int args, char *argv[])
{
int new_balance, old_balance;
float withdrawal;
/* Get input */
printf("Enter your initial Balance and the Amount to be Withdrawn.\n");
printf("Note the values should lie between 0 and 2000\n");
while (scanf("%d %f", &old_balance, &withdrawal) != 2) {
printf ("please enter two valid floating point numbers\n");
}
/* Validate input */
if ( (old_balance < 0.0) || (old_balance > 2000.0) ) {
printf ("error: balance(%d): must be between 0.0 and 2000.0\n",
old_balance);
return 1;
}
if ( (withdrawal < 0.0) || (withdrawal > 2000.0) ) {
printf ("error: withdrawal(%f): must be between 0.0 and 2000.0\n",
withdrawal);
return 1;
}
/* Compute balance */
new_balance = old_balance - withdrawal;
/* Print results */
printf ("Withdrawal: %f; old balance: %d, new balance: %d.\n",
withdrawal, old_balance, new_balance);
return 0;
}
I'm not at all sure what the requirement was with the "0.5" stuff, so I left it out. My guess is that you wanted to "round up to the nearest dollar". In which case "%" is definitely not the way to do it.
The original program might have compiled - but it almost certainly wasn't "correct".
And the original program, as far as I could tell, should have run just about anywhere - I didn't see anything likely to cause an "out of memory condition".
'Hope that helps .. at least a little...