I wanted to make a function with structs to simplify rational numbers , one member is the numerator(int) and the other is the denominator(int) but the program stucks at input!!
I am aware that scanf() is a bit risky but I thought its just a couple of integers!
#include <stdio.h>
#include <stdlib.h>
typedef struct rational{
int num;
int den;
}rational;
rational makerational(int num,int den);
void printrational(rational r);
int main()
{
int a,b;
printf("\n\n Input integers for fraction:");
scanf(" %d%d",&a,&b);
printrational(makerational(a,b));
}
rational makerational(int a,int b){
int live=1;
rational r;
r.num=a;
r.den=b;
while(live){
if(!(r.num%2 && r.den%2)){
r.num/=2;
r.den/=2;
}else if(!(r.num%3 && r.den%3)){
r.num/=3;
r.den/=3;
}else if(!(r.num%5 && r.den%5)){
r.num/=5;
r.den/=5;
}else if(!(r.num%7 && r.den%7)){
r.num/=7;
r.den/=7;
}else live--;
}
return r;
}
void printrational(rational r){
printf("\nFRACTION -> %d/%d\n",r.num,r.den);
}
You getting stuck in an infinite loop here:
while(live){
if(!(r.num%2 && r.den%2)){
r.num/=2;
r.den/=2;
}
…
}
For example, when r.num == 1 and r.den == 2, consider what's happening:
Iteration 1
r.num % 2 == 1 % 2 == 1
r.den % 2 == 2 % 2 == 0
!(1 && 0) == 1
r.num / 2 == 1 / 2 == 0
r.den / 2 == 2 / 2 == 1
Iteration 2
r.num % 2 == 0 % 2 == 0
r.den % 2 == 1 % 2 == 1
!(0 && 1) == 1
r.num / 2 == 0 / 2 == 0
r.den / 2 == 1 / 2 == 0
Iteration 3 to infinity and beyond…
r.num % 2 == 0 % 2 == 0
r.den % 2 == 0 % 2 == 0
!(0 && 0) == 1
r.num / 2 == 0 / 2 == 0
r.den / 2 == 0 / 2 == 0
Change the expressions in the branching statements to something like this to correct your logic:
while(live)
{
if((r.num % 2 == 0) && (r.den % 2 == 0))
{
r.num /= 2;
r.den /= 2;
}
…
}
Problem is, when you enter 8 20, numbers change like fallowing;
4 10
2 5
1 2
0 1
0 0 <--- here is the infinite loop
reason is, integer rounds down the number, you should add a control statement for the case that numbers reach 0
Related
I want to be able to request the entry of 4 digits between 0 and 1 but when I do the test it still asks me to enter the screen despite entering 1001 or others.
#include <stdio.h>
int main(void) {
int n,n1,n2,n3,mod0,mod1,mod2,mod3;
do {//1025
printf("Ingresar un numero de 4 digitos: "); scanf("%d",&n);
n1 = n/10; //<- 102
mod0 = n%10; // <- mod 5
n2 = n1/10; // <- 10
mod1 = n1%10; // <- mod 2
n3 = n2/10; // <- 1
mod2 = n2%10; // <- 0
mod3 = n3%10; // 1
if ((mod3 != 1 || mod3 != 0) && ( mod2 !=1 || mod2 != 0) && (mod1 != 1 || mod1 != 0) && (mod0 !=1 || mod0 != 0)){
printf("Ingresar digitos binarios\n");
}
}while((mod3 != 1 || mod3 != 0) && ( mod2 !=1 || mod2 != 0) && (mod1 != 1 || mod1 != 0) && (mod0 !=1 || mod0 != 0));
return 0;
}
It keeps asking for digits, since you have the scanf inside the loop. Placing printf("Ingresar un numero de 4 digitos: "); scanf("%d",&n); above your do-while loop will solve your problem.
Also, you should look at the conditions of your loop. Isn’t it easier to loop until n == 0?
Example:
n = 1025, mod = 0
while n != 0:
mod = n % 10 (makes 5)
n = n / 10 (makes 102)
Check if mod is 0 or 1
repeat for next digits
In the example you will seperate each last digit from n and check whether it is a 0 or 1.
EDIT: This link explains what I want to show with the example. Instead of printing the digits, you should check if it is a 0 or 1.
We were having a quiz of sorts and had the following question where we had to find the error, or if there's none, the output of the given code:
#include <stdio.h>
int main(void) {
int n = 012;
b: printf("%d\n",n--);
if(n!=0){
n--;
goto b;
}
return 0;
}
I don't see anything wrong with this in theory but this leads to an infinite loop with the variable going way below 0. Could anyone help me with this?
#include <stdio.h>
int main(void) {
int n = 012;
b: printf("%d\n",n);
if(n!=0){
n--;
goto b;
}
return 0;
}
This would work. The version you posted does not work because it will never get to 0. It is subtracting once in the if statement, and once in the printf.
You should only have one n-- statement. otherwise even if it reaches 0, when it get the first n-- it will be decremented one more time and will become -1. (so it will never match 0).
Hence, please change your code to
#include <stdio.h>
int main(void) {
int n = 012;
b: printf("%d\n",n--);
if(n!=0){
goto b;
}
return 0;
}
The condition if (n != 0) is always getting satisfied.
On each iteration the number n decreases by 2.
So when n = 2, it gets decremented once after printf("%d\n",n--)
then the condition if (n != 0) is true, as n = 1
Inside the condition block n is decremented once again, n = 0
So the next time before reaching the condition if (n != 0), n equals to -1,
which leads to an infinite loop.
In C 012 is an octal base number, in decimal it is equal to 10.
This code:
#include <stdio.h>
int main(void) {
int n = 012;
b: printf("%d\n",n--);
if(n!=0){
n--;
goto b;
}
return 0;
}
Does this:
print n (10)
subtract 1 of n (n = 10 - 1 = 9)
check if n != 0 (9 != 0 -> true)
subtract 1 of n (n = 9 - 1 = 8)
jump to b
print n (8)
subtract 1 of n (n = 8 - 1 = 7)
check if n != 0 (7 != 0 -> true)
subtract 1 of n (n = 7 - 1 = 6)
jump to b
print n (6)
subtract 1 of n (n = 6 - 1 = 5)
check if n != 0 (5 != 0 -> true)
subtract 1 of n (n = 5 - 1 = 4)
jump to b
print n (4)
subtract 1 of n (n = 4 - 1 = 3)
check if n != 0 (3 != 0 -> true)
subtract 1 of n (n = 3 - 1 = 2)
jump to b
print n (2)
subtract 1 of n (n = 2 - 1 = 1)
check if n != 0 (1 != 0 -> true)
subtract 1 of n (n = 1 - 1 = 0)
jump to b
print n (0)
subtract 1 of n (n = 0 - 1 = -1)
check if n != 0 (-1 != 0 -> true)
subtract 1 of n (n = -1 - 1 = -2)
jump to b
print n (-2)
...
...
... goes on infinitely
Note that when n will never equal to 0 when the program checks if n != 0, because in this evaluation n is always an odd number since two subtractions by 1 are made every time.
Change from b: printf("%d\n",n--); to b: printf("%d\n",n);.
or
Change from
if(n!=0){
n--;
goto b;
to
if(n!=0){
n;
goto b;
Because n-- equals n = n - 1.
Your program:
#include <stdio.h>
int main(void) {
int n = 012;
b: printf("%d\n",n--); // n = n - 1
if(n!=0){
n--; // n = n - 1
goto b;
}
return 0;
}
for out put [10, 8, 6, 4,2, 0]
#include <stdio.h>
int main(void) {
int n = 012;
b: printf("%d\n",n--);
if(n>0){
n--;
goto b;
}
return 0;
}
for [10,9,8,7,6,5,4,3,2,1]
#include <stdio.h>
int main(void) {
int n = 012;
b: printf("%d\n",n--);
if(n>0){
//n--;
goto b;
}
return 0;
}
hello my task to write test, which checks if the Minesweeper board (after choosing replay option) is different than the previous one.
first of all i wrote the main function the replay.
after that I tested it locally if it works and every game, every board was different. there was no issue.
so i started to write test cases and now im here.
TEST replay_board() {
Game *game = create_game();
Board *board = create_board(9, 9, 9);
game->board = board;
int k = 0;
printf("\n");
char mine_list[100];
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (game->board->tiles[i][j]->is_mine == true) {
mine_list[k] = '1';
printf("1");
} else {
mine_list[k] = '0';
printf("0");
}
k++;
}
}
printf("\n");
mine_list[k] = '\0';
replay_game(replay, game);
char mine_list2[100];
k = 0;
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (game->board->tiles[i][j]->is_mine == true) {
mine_list2[k] = '1';
printf("1");
} else {
mine_list2[k] = '0';
printf("0");
}
k++;
}
}
printf("\n");
mine_list2[k] = '\0';
int same = 0;
if (strcmp(mine_list, mine_list2) != 0) {
same = 0;
} else {
same = 1;
}
ASSERT_EQ(same, 0);
PASS();
destroy_game(game);
}
in every test it writes that the old boar is the same as the previous one, but locally i can see that they aren't the same.
i dont know its ideal to compare two strings, but it was the easiest way to compare them from structure
replay function
void replay_game(char* replay, Game* game) {
while (strcmp(replay, "yes") != 0 && strcmp(replay, "no") != 0 ) {
scanf("%s", replay);
if (strcmp(replay, "yes") != 0 || strcmp(replay, "no") != 0) {
printf("invalid value\n");
}
}
if (strcmp(replay, "yes") == 0) {
destroy_board(game->board);
game->game_state = PLAYING;
game->board = create_board(9, 9, 9);
game->player->score = 0;
}
}
create_board function
int generate_random_coordinates(int upper_range) {
return rand() % upper_range;
}
/**
* Generates random coordinates to row and column according to mine count value
* Randomly sets mines to the Board pointer
*/
void set_mines_randomly(Board *board) {
assert(board != NULL);
int board_mine_count = 0;
srand(time(NULL));
while (board_mine_count != board->mine_count) {
int random_row = generate_random_coordinates(board->row_count);
int random_column = generate_random_coordinates(board->column_count);
if (board->tiles[random_row][random_column]->is_mine == false) {
board->tiles[random_row][random_column]->is_mine = true;
board_mine_count++;
}
}
}
Board *create_board(int row_count, int column_count, int mine_count) {
Board *board = (Board *) calloc(1, sizeof(Board));
board->row_count = row_count;
board->column_count = column_count;
board->mine_count = mine_count;
for (int row = 0; row < board->row_count; row++) {
for (int column = 0; column < board->column_count; column++) {
board->tiles[row][column] = (Tile *) calloc(1, sizeof(Tile));
board->tiles[row][column]->tile_state = CLOSED;
board->tiles[row][column]->is_mine = false;
}
}
set_mines_randomly(board);
set_tile_values(board);
return board;
}
main
#include <stdlib.h>
#include <string.h>
#include "game.h"
#include "user_interface.h"
#include "board.h"
int main() {
char replay[] = "yes";
Game *game = create_game();
Board *board = create_board(9, 9, 9);
game->board = board;
read_player_name(game);
// impleting the replay function
while(strcmp(replay, "yes") == 0) {
play_game(game);
printf("Chcel by si znova zahrat? (yes/no)\n");
scanf("%3s", replay);
printf("\n");
// new part
char mine_list[100];
int k = 0;
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (game->board->tiles[i][j]->is_mine == true) {
mine_list[k] = '1';
//printf("1");
} else {
mine_list[k] = '0';
//printf("0");
}
k++;
}
}
mine_list[k] = '\0';
replay_game(replay, game);
char mine_list2[100];
k = 0;
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (game->board->tiles[i][j]->is_mine == true) {
mine_list2[k] = '1';
//printf("1");
} else {
mine_list2[k] = '0';
//printf("0");
}
k++;
}
}
mine_list2[k] = '\0';
printf("%s\n", mine_list);
printf("%s\n", mine_list2);
// new part ending heree
}
destroy_game(game);
exit(EXIT_SUCCESS);
}
running the main after losing
output
1 2 3 4 5 6 7 8 9
1 1 1 0 0 0 0 0 0 0
2 X 1 0 1 1 1 0 0 0
3 - 1 0 1 X 1 0 0 0
4 - 1 1 1 1 1 1 1 1
5 - X 1 0 0 0 1 X -
6 - - 2 1 1 1 2 - -
7 - - X - - X - - -
8 - X - - X - - - -
9 - - - - - - X - -
Ľutujem tom. Riešenie je nesprávne!
Vaše skóre je: 13
Chcel by si znova zahrat? (yes/no)
yes
after playing that for 2 minutes
1 2 3 4 5 6 7 8 9
1 0 0 0 0 0 1 - 1 0
2 0 0 0 0 1 3 X 2 0
3 0 0 0 0 1 X X 3 1
4 1 1 0 0 1 2 2 2 X
5 X 1 0 0 0 0 0 1 -
6 - 2 1 2 2 3 2 1 -
7 - - X - X X X - -
8 - - - - - - - 1 -
9 - - - - - - - - -
Ľutujem tom. Riešenie je nesprávne!
Vaše skóre je: 19
Chcel by si znova zahrat? (yes/no)
FAILED test result:
* Suite test_board:
......
000000000000001100000010001000100000000000001000100000100010000000000000000000000
000000000000001100000010001000100000000000001000100000100010000000000000000000000
F
FAIL replay_board: same != 0 (tests/test_board.c:125)
game.h
typedef enum {
FAILED,
PLAYING,
SOLVED,
} GameState;
typedef struct {
Board *board; /* Struct of the play field */
Player *player; /* Struct of user who is playing the Game */
GameState game_state; /* Enum for status of the Game */
} Game;
* create_game()*
Game *create_game() {
Game *game = (Game *) calloc(1, sizeof(Game));
Player *player = (Player *) calloc(1, sizeof(Player));
game->player = player;
game->player->score = 1;
game->game_state = PLAYING;
return game;
}
new ouput after uptadting the main with printf
1 2 3 4 5 6 7 8 9
1 - 1 0 0 0 0 0 0 0
2 X 1 0 0 0 0 1 1 1
3 - 1 0 0 0 0 1 X -
4 - 1 1 0 0 1 2 - -
5 - X 2 1 1 1 X - X
6 1 1 2 X 1 1 2 X X
7 0 0 1 1 1 0 1 3 X
8 0 0 0 0 0 0 0 1 1
9 0 0 0 0 0 0 0 0 0
Ľutujem asd. Riešenie je nesprávne!
Vaše skóre je: 17
Chcel by si znova zahrat? (yes/no)
yes
000000000100000000000000010000000000010000101000100011000000001000000000000000000
000000001100000000000000000000100011000000000000000010010000000000001000000010000
1 2 3 4 5 6 7 8 9
1 - - - - - - - - -
2 - - - - - - - - -
3 - - - - - - - - -
4 - - - - - - - - -
5 - - - - - - - - -
6 - - - - - - - - -
7 - - - - - - - - -
8 - - - - - - - - -
9 - - - - - - - - -
Here's the problem:
char* mine_list[100];
You defined mine_list as an array of char * instead of an array of char. Your compiler should have given you a number of warnings wherever you used it. Change it to an array of char:
char mine_list[100];
Did you check that replay_game("yes", game); actually changes game?
Either way, there's a much easier and correct way to do this.
Allocate a new board* pointer,copy the content of board to the new allocated memory using memcpy, and then call replay_game. Assuming this actually changes board variable you can now simply compare the two boards inside one nested loop.
I need to build a method in C that will return an int, take 3 ints as parameters. The first and second int are the starting and ending bit position. The third int is a 0 or 1 to determine the type of mask.
For example,
getMask(2, 6, 1);
//Set bits 2 to 6 to 1, set all others to zero
should set the bits 2 through 6 to a 1 and all other bits to zero.
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 1 0 0
So getMask(2, 6, 1) should return the integer 124.
And getMask(11, 31, 0) (set bits 11 to 31 to 0) should return 2047.
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 1 1 1 1 1 1 1
This is what I have currently:
#include <stdio.h>
int getM(int start, int end, int choice) {
if (choice == 1){
return ~(~0 << (end - start + 1)) << (start);
}
else if (choice == 0){
return ~(~1 << (end - start + 1)) << (start);
}
else{
return 0;
}
}
It works when I the choice is 1, but for 0 I am completely lost.
I currently get -2048 for getMask(11, 31, 0).
I know I can use ands and ors, but I cannot figure out how to use them the way I am doing this.
#AnttiHaapala is correct: choice==0 is just the bitwise negation of choice==1 for the same start and end. Therefore (as an MCVE):
#include <stdio.h>
int getM(int start, int end, int choice) {
if (choice == 1){
return ~(~0 << (end - start + 1)) << (start);
}
else if (choice == 0){
return ~getM(start, end, 1); /* Just use what you have, but ~ it */
}
else{
return 0;
}
}
int main() {
printf("2 6 1 %d\n", getM(2,6,1));
printf("11 31 0 %d\n", getM(11,31,0));
}
Here is the task I was given:
Write a function fact_calc that takes a string output argument and an integer input argument n and returns a string showing the calculation of n!. For example, if the value supplied for n were 6, the string returned would be
“6! x 6 x 5 x 4 x 3 x 2 x 1 x = 720”. Write a program that repeatedly prompts the user for an integer between 0 and 9, calls fact_calc and outputs the resulting string in a box of asterisks of the right size to surround the result. If the user inputs an invalid value, the program should display an error message and reprompt for valid input. Input of the sentinel -1 should cause the input loop to exit.
Here is my code:
#include <stdio.h>
/*Prototypes*/
void fact_calc(char [], int);
int main(void)
{
char calc[99];
int num1;
do{
printf("Enter an integer between 0 and 9 or -1 to quit: ");
scanf("%d", &num1);
fact_calc(calc, num1);
}while( num1 != -1 );
return (0);
} //end main
/*Place function definitions below*/
void fact_calc(char calc[], int num1)
{
if(num1 == 0)
char calc[] = "0! = 0 = 0";
else if(num1 == 1)
char calc[] = "1! = 1 = 0"
else if(num1 == 2)
char calc[99] = "2! = 2 x 1 = 2"
else if(num1 == 3)
char calc[99] = "3! = 3 x 2 x 1 = 6"
else if(num1 == 4)
char calc[99] = "4! = 4 x 3 x 2 x 1 = 24"
else if(num1 == 5)
char calc[99] = "5! = 5 x 4 x 3 x 2 x 1 = 120"
else if(num1 == 6)
char calc[99] = "6! = 6 x 5 x 4 x 3 x 2 x 1 = 720"
else if(num1 == 7)
char calc[99] = "7! = 7 x 6 x 5 x 4 x 3 x 2 x 1 = 5040"
else if(num1 == 8)
char calc[99] = "8! = 8 x 7 x 6 x 5 x 4 x 3 x 2 x 1 = 40320"
else if(num1 == 9)
char calc[99] = "9! = 9 x 8 x 7 x 6 x 5 x 4 x 3 x 2 x 1 = 362880"
else
printf("Invalid Entry");
}
I am getting the error:
expected
expression
ch...
^
I still have to print out the string but I can't figure out what the error means or what I am doing wrong. Thanks in advance for the help!
char calc[] = "1! = 1 = 0"
Don't you think you should be ending this line with a ;
char calc[] = "1! = 1 = 0";
Similar fix needs to be done for the rest of the lines
Your program is doing something strange. I doubt it does what you expect.
You are declaring variables inside the body of if statements. These variables will only be in scope for the body, and you don't do anything with them.
Your program can be made to work. I suggest simply making fact_calc() return literal strings rather than try to assign to variables.
/*Place function definitions below*/
char const *fact_calc(char calc[], int num1)
{
if(num1 == 0)
return "0! = 0 = 0";
else if(num1 == 1)
return "1! = 1 = 0";
else if(num1 == 2)
return "2! = 2 x 1 = 2";
else if(num1 == 3)
return "3! = 3 x 2 x 1 = 6";
else if(num1 == 4)
return "4! = 4 x 3 x 2 x 1 = 24";
else if(num1 == 5)
return "5! = 5 x 4 x 3 x 2 x 1 = 120";
else if(num1 == 6)
return "6! = 6 x 5 x 4 x 3 x 2 x 1 = 720";
else if(num1 == 7)
return "7! = 7 x 6 x 5 x 4 x 3 x 2 x 1 = 5040";
else if(num1 == 8)
return "8! = 8 x 7 x 6 x 5 x 4 x 3 x 2 x 1 = 40320";
else if(num1 == 9)
return "9! = 9 x 8 x 7 x 6 x 5 x 4 x 3 x 2 x 1 = 362880";
/* Invalid Entry */
return NULL;
}
Then your main function should declare a variable of type char const * to store the pointer returned by this function, and should check that the pointer is not set to NULL (and print "Invalid Entry" if the pointer was set to NULL).
You cannot assign strings (char arrays) in C. You should use strcpy() instead.
E.g.
strcpy(calc, "2! = 2 x 1 = 2");
Note that you should use strcpy() only if you are 100% certain calc is large enough to store the entire string. If not, use strncpy() instead. Example:
strncpy(calc, "2! = 2 x 1 = 2", 99);
calc[98] = '\0';
// a better way would be to pass 99 to your function, or to declare a macro
Finally, note that both 0! and 1! should be 1, not 0.