Since I am kind of a beginner to programming, I try to programm as much as possible. I saw a illustration on how an integer array saves its bytes. I tried to make this illustration in c, just for the learning and I wondered if there is a better way than i did it.
The code below works on its own and if there is a more efficient way, it still should have the same output.
I know that my code would be very challenging if the array would have 100 integers.
#include <stdio.h>
int main() {
int lange = 3;
int c[lange];
c[0] = 3;
c[1] = 1;
c[2] = 2;
for (int i = 0; i < lange*4; i++) {
printf("| ");
if (i == 0) {
printf("%d", c[0]);
}
else if (i==4) {
printf("%d", c[1]);
}
else if (i==8){
printf("%d",c[2]);
}
}
return 0;
}
This could be done more compactly by changing the if-tree in the loop to be just
if ((i % 4) == 0)
printf("%d", c[i/4]);
or you could print every byte by doing something like
printf("%d", (c[i/4] >> (i%4 * 8)) & 0xff);
You should use a #define C_LEN 3 and use that instead of your magic number 3. You loop prints out a '|' in every iteration so your loop body cannot really be simplified other than:
if(!(i % 4)) printf("%d", c[i/4]);
If you only want to print something for 0, 4 and 8 then you iterate by 4 instead of 1, or better iterate by 1 (see below).
The output is:
| 3| | | | 1| | | | 2| | |
If that is all you want, I would write a single print statement:
printf("| %d| | | | %d| | | | %d| | | ", c[0], c[1], c[2]);
Or if you want a loop on group at a time and just iterate to 3 times:
for (int i = 0; i < C_LEN; i++) {
printf("| %d| | | ", c[i]);
}
It seems that you are trying to print the elements of the array, based on multiple of 4.
You can generalize your program by creating an array of any size and have your for loop like this:
int index = 0;
for (int i = 0; i < lange*4; i++)
{
printf("| ");
if (i == 0)
{
index = 0;
}
else if((i % 4) == 0)
{
index = i/4;
}
else
{
continue;
}
printf("%d",c[index]);
}
Related
So we got this a school assignment. it is a chomp game and the requirements are these:
The program should have the functions below and pointers and structs are not allowed. Also it should have the global variables that I have declared (except for m and n. More global variables and functions is allowed to have if one wishes to.
a) initialize() Initialize every position in the matrix to 'O'. No parameters or return value.
b) print_board() Prints the matrix. No parameters or return value.
c) get_move() Scan a move from the player (row and col) and "return" it with an array. Parameters: Information about whos turn it is (Player 1 or Player 2), and an array with two elements where the move coordinates will be stored. No return value.
d) check_move() Controls if a move is legal (not outside the matrix and not a position that has already been eaten). Parameters: The move that is going to be checked (row and col). Return value: Result of the control.
e) update_board() Updates the matrix. Parameters: The new move (row and col). No return value.
... I feel like I am almost done, but when I enter the values, the board "paints" with a different result. And I don't know where I've done wrong.
Also, even though I don't need it for the assignment, any suggestions on how to improve the code are welcome!
Oh! And also, when I enter a coordinate into the terminal, it actually needs to be inversed (vertically at least) and it is 4 in the morning and I can't figure out how?
Thank you all in advance!
here is some output examples:
Welcome to Chomp!
+----------+
|OOOOOOOOOO|
|OOOOOOOOOO|
|OOOOOOOOOO|
|XOOOOOOOOO|
+----------+
Player 1: Your move, please! (row,col): 3,7
+----------+
|OOOOOO |
|OOOOOO |
|OOOOOO |
|XOOOOOOOOO|
+----------+
Player 2: Your move, please! (row,col): 3,1 <= Bad move!
+----------+
| |
| |
| |
|XOOOOOOOOO|
+----------+
Player 1: Your move, please! (row,col): 4,2 <= Good move!
+----------+
| |
| |
| |
|X |
+----------+
Player 2: Your move, please! (row,col): 4,2
Already taken!
Player 2: Your move, please! (row,col): 4,11
Illegal position!
Player 2: Your move, please! (row,col): 4,1
Game over, player 2 has been poisoned!
#include <stdio.h>
#include <string.h>
// Global variables
int height = 4;
int width = 10;
int player = 2;
int move[2] = {0};
char board[4][10];
int m;
int n;
void Initialize();
void PrintBoard();
void GetMove(int player, int move[2]);
int CheckMove(int move[2]);
void UpdateBoard(int move[2]);
int main(void)
{
Initialize();
while(1)
{
PrintBoard();
player = (player == 2) ? 1 : 2;
while(1)
{
GetMove(player, move);
int c = CheckMove(move);
if (c == 0)
{
UpdateBoard(move);
break;
}
else if (c == 1)
{
printf("\nAlready taken. Please try again! (row col): ");
continue;
}
else if (c == 2)
{
printf("\nYou lost!\n");
return 0;
}
else if (c == 3)
{
printf("\nIllegal move. Try again! (row col): ");
continue;
}
}
}
}
void Initialize()
{
memset(board, 'O' , sizeof(char) * height * width);
board[3][0] = 'X';
}
void PrintBoard()
{
printf("\n+----------+\n");
for (int i = 0; i < 4; i++)
{
for(int j = 0; j <= 11; j++)
{
if (j == 0 || j == 11)
{
printf("|");
}
else
{
printf("%c", board[i][j-1]);
}
}
printf("\n");
}
printf("+----------+\n");
}
void GetMove(int player, int move[2])
{
printf("\nPlayer %d: your move! (row col): ", player);
for (int i = 0; i < 2; i++) scanf(" %d", &move[i]);
}
int CheckMove(int move[2])
{
int check = 99;
if ((move[0] >= 1 && move[0] < 5) && (move[1] >= 1 && move[1] <= 10))
{
printf("move = %d %d\n", move[0], move[1]);
int m = move[0] - 1;
int n = move[1] - 1;
printf("move = %d %d\n", m, n);
// move[0] -= 1;
// move[1] -= 1;
// more checks
if (board[m][n] == 'Z')
{
check = 1;
}
else if(board[m][n] == 'X')
{
check = 2;
}
else
{
check = 0;
}
}
else { check = 3; }
return check;
}
void UpdateBoard(int move[2])
{
// int y = move[0];
// int x = move[1];
for (int i = m; i >= 0; i--)
{
for (int j = n; j < width; j++)
{
board[i][j] = 'Z';
}
}
}
you should update your post with the requirement and some example input with the output and the expected output.
but anyways, I have read your code and apparently you have only 2 problems:
in the line
int m = move[0] - 1;
int n = move[1] - 1;
actually, you are shallowing the global variables, even my compiler gave me this warning:
Declaration shadows a variable in the global scope
so instead, you should do:
m = move[0] - 1;
n = move[1] - 1;
this will make you global variables could be modified
in the lines:
for (int i = m; i >= 0; i--)
{
for (int j = n; j < width; j++)
{
board[i][j] = 'Z';
}
}
if the user chooses a specific row and column, this code will mark an entire row from position (m, n) with the value Z not only one cell
so you should do simply:
board[m][n] = 'Z';
with these being fixed, this is some example output:
+----------+
|OOOOOOOOOO|
|OOOOOOOOOO|
|OOOOOOOOOO|
|XOOOOOOOOO|
+----------+
Player 1: your move! (row col):1 2
move = 1 2
move = 0 1
+----------+
|OZOOOOOOOO|
|OOOOOOOOOO|
|OOOOOOOOOO|
|XOOOOOOOOO|
+----------+
Player 2: your move! (row col):2 1
move = 2 1
move = 1 0
+----------+
|OZOOOOOOOO|
|ZOOOOOOOOO|
|OOOOOOOOOO|
|XOOOOOOOOO|
+----------+
Player 1: your move! (row col):1 2
move = 1 2
move = 0 1
Already taken. Please try again! (row col):
Player 1: your move! (row col):3 1
move = 3 1
move = 2 0
+----------+
|OZOOOOOOOO|
|ZOOOOOOOOO|
|ZOOOOOOOOO|
|XOOOOOOOOO|
+----------+
Player 2: your move! (row col):4 1
move = 4 1
move = 3 0
You lost!
I'm working on a project The project in c and The point of it is to create a multiple threads and work with them ...
the problem is The program worked fine on my Macos but when I'm trying to work on the project form Kali VM or WSL (Windows Subsystem for Linux). the same code gaves me the following error
the error on kali VM
└─$ ./a.out 3 800 200 200 1200 134 ⨯
malloc(): corrupted top size
zsh: abort ./a.out 3 800 200 200 1200
The error on WSL
└─$ ./a.out 2 60 60 20
malloc(): corrupted top size
Aborted (core dumped)
you can check the full code here in this repo.
this is the main file of the code:
#include "philosophers.h"
int ft_error_put(char *messsage, int ret)
{
printf("%s\n", messsage);
return (ret);
}
int ft_parsing(char **av, t_simulation *simulation)
{
int num;
int i;
int j;
i = 1;
j = 0;
while (av[i])
{
j = 0;
num = 0;
while (av[i][j])
{
if (av[i][j] >= '0' && av[i][j] <= '9')
num = num * 10 + (av[i][j] - '0');
else
return (ft_error_put("Error: Number Only", 1));
j++;
}
if (i == 1)
{
simulation->philo_numbers = num;
simulation->forks = num;
simulation->threads = (pthread_t *)malloc(sizeof(pthread_t) * num);
}
else if (i == 2)
simulation->time_to_die = num;
else if (i == 3)
simulation->time_to_eat = num;
else if (i == 4)
simulation->time_to_sleep = num;
else if (i == 5)
simulation->eat_counter = num;
i++;
}
if (i == 5)
simulation->eat_counter = -1;
return (0);
}
void ft_for_each_philo(t_simulation *simulation, t_philo *philo, int i)
{
philo[i].index = i + 1;
philo[i].left_hand = i;
philo[i].right_hand = (i + 1) % simulation->philo_numbers;
philo[i].is_dead = NO;
if (simulation->eat_counter == -1)
philo[i].eat_counter = -1;
else
philo[i].eat_counter = simulation->eat_counter;
}
t_philo *ft_philo_init(t_simulation *simulation)
{
t_philo *philo;
int i;
i = -1;
philo = (t_philo *)malloc(sizeof(t_philo));
while (++i < simulation->philo_numbers)
ft_for_each_philo(simulation, philo, i);
return (philo);
}
void *ft_routine(void *arg)
{
t_philo *philo;
philo = (t_philo *)arg;
printf("thread number %d has started\n", philo->index);
sleep(1);
printf("thread number %d has ended\n", philo->index);
return (NULL);
}
int main(int ac, char **av)
{
int i;
t_simulation simulation;
t_philo *philo;
i = 0;
if (ac == 5 || ac == 6)
{
if (ft_parsing(av, &simulation))
return (1);
philo = ft_philo_init(&simulation);
while (i < simulation.philo_numbers)
{
simulation.philo_index = i;
pthread_create(simulation.threads + i, NULL,
ft_routine, philo + i);
i++;
}
i = 0;
while (i < simulation.philo_numbers)
{
pthread_join(simulation.threads[i], NULL);
i++;
}
}
return (0);
}
Your program was aborting on a pthread_create call.
But, the issue was a too short malloc call before that in ft_philo_init.
You were only allocating enough space for one t_philo struct instead of philo_numbers
Side note: Don't cast the return value of malloc. See: Do I cast the result of malloc?
Here is the corrected function:
t_philo *
ft_philo_init(t_simulation *simulation)
{
t_philo *philo;
int i;
i = -1;
// NOTE/BUG: not enough elements allocated
#if 0
philo = (t_philo *) malloc(sizeof(t_philo));
#else
philo = malloc(sizeof(*philo) * simulation->philo_numbers);
#endif
while (++i < simulation->philo_numbers)
ft_for_each_philo(simulation, philo, i);
return philo;
}
UPDATE:
thank you it's worked now, but can you explain why it work on macOS but it doesn't in kali? – DarkSide77
Well, it did not "work" on macOS either ...
When we index through an array and go beyond the bounds of the array, it is UB ("undefined behavior"). UB means just that: undefined behavior.
See:
Undefined, unspecified and implementation-defined behavior
Is accessing a global array outside its bound undefined behavior?
Anything could happen. That's because the philo array occupies a certain amount of memory. What is placed after that allocation? Let's assume philo is 8 bytes [or elements if you wish--it doesn't matter]:
| philo[8] | whatever |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| | | | | | | | | | | | | | | | |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
As long as we stay within bounds, things are fine (e.g.):
for (i = 0; i < 8; ++i)
philo[i] = 23;
If we go beyond the end, we have UB (e.g.):
for (i = 0; i < 9; ++i)
philo[i] = 23;
Here we went one beyond and modified the first cell of whatever.
Depending upon what variable was placed there by the linker, several behaviors are possible:
The program seems to run normally.
A value at whatever is corrupted and the program runs but produces incorrect results.
whatever is aligned to a page that is write protected. The program will segfault on a protection exception immediately.
The value corrupted at whatever has no immediate effect, but later the program detects the corruption.
The corruption eventually causes a segfault because a pointer value was corrupted.
On both systems, your program was doing the same thing. For an area we get from malloc, the whatever is an internal struct used by the heap manager to keep track of the allocations. The program was corrupting this.
On macOS, the heap manager did not detect this. On linux (glibc), the heap manager did better cross checking and detected the corruption.
I am trying to print each char of an array of matrices for a brick breaker game (the full message would be YOU LOSE). I am new to C and I don't feel too confident about using pointers; I feel that that may be the source of my problem. To try to solve the problem, I've read plenty of online guides on how to deal with strings in C; but the fact that I'm dealing with an array of arrays of arrays of chars makes this task quite a bit harder. If you know how to print matrices of strings (in yet another array) in C, or you have a better solution, please let me know!
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#define LETTER_WIDTH 13
#define LETTER_HEIGHT 6
char Y[LETTER_HEIGHT][LETTER_WIDTH] = {
"___ __\n",
"\\ \\__ / /\n",
"\\ \\ / /\n",
"| | |\n",
"| | |\n",
"|__|__|\n"};
char O[LETTER_HEIGHT][LETTER_WIDTH] = {
" _______ \n",
" / __ \\\n",
"| | | |\n",
"| |__| |\n",
" \\_______/\n"};
char *SENTENCE[2][LETTER_HEIGHT][LETTER_WIDTH] = {*Y, *O};
void printLetter(char letter[LETTER_HEIGHT][LETTER_WIDTH]) {
for (int i = 0; i < LETTER_HEIGHT; i++) {
for (int j = 0; j < LETTER_WIDTH; j++) {
printf("%c", letter[i][j]);
}
}
}
void printSentence() {
for (int i = 0; i < 2; i++) {
char letter[LETTER_HEIGHT][LETTER_WIDTH];
strcpy(*letter, **SENTENCE[i]);
printLetter(letter);
sleep(1);
}
}
int main() {
printSentence();
return 0;
}
Firstly this should be better
char* Y[LETTER_HEIGHT] = {
"___ __\n",
"\\ \\__ / /\n",
"\\ \\ / /\n",
"| | |\n",
"| | |\n",
"|__|__|\n"};
char* O[LETTER_HEIGHT] = {
" _______ \n",
" / __ \\\n",
"| | | |\n",
"| |__| |\n",
" \\_______/\n"};
Now these are arrays of size 6 (you must add one line because O now have height of 5) containing pointers to arrays of chars. Next
char** SENTENCE[2] = {Y, O};
You did some really weird things with this line before, this defines SENTENCE as 2 element array of pointers to array of pointers to char arrays (which are Y and O).
Next
void printLetter(char** letter) {
for (int i = 0; i < LETTER_HEIGHT; i++) {
printf("%s", letter[i]);
}
}
This function takes pointer to array of pointers to char arrays. Then goes 6 times and print each array as string. Next
void printSentence() {
for (int i = 0; i < 2; i++) {
printLetter(SENTENCE[i]);
sleep(1);
}
}
Here you can use simple for loop to pass to printLetter each pointer to array of pointers to char arrays (which are these letters) from SENTENCE.
or you have a better solution, please let me know!
Yes, there is a much simpler and, I would argue, better solution, it's to place the SENTENCE in a single 2D array and print it in one go, even if you are to use ncurses, this makes your job easier.
Note that with ncurses you can reposition the cursor so you can print each letter separately in one line, you wouldn't need to join them together like you try to do in SENTENCE.
#define LETTER_WIDTH 100
#define LETTER_HEIGHT 6
char SENTENCE[LETTER_HEIGHT][LETTER_WIDTH] = {
"__ __ ______ \n",
"\\ \\ / / / __ \\\n",
" \\ \\/ / | | | |\n",
" | | | | | |\n",
" | | | |__| |\n",
" |__| \\______/\n"};
void printSentence()
{
for (int i = 0; i < 6; i++)
{
printf("%s", SENTENCE[i]);
}
}
Output:
__ __ ______
\ \ / / / __ \
\ \/ / | | | |
| | | | | |
| | | |__| |
|__| \______/
This question already has answers here:
printing a square with diagonals
(4 answers)
Closed 3 years ago.
Guys i'm pretty stuck here. I'm trying to learn c and create some very basic code which asks the user to insert a number. Then, this number enters the following formula : 2x+1, then I want it to print a hollow square pattern with a different symbol for rows and columns, and add a + in the corners, diagonals, and a "X" in the middle.
I'm stuck in the very very beginning of the code. I don't know where should I even start. I mean I can't even learn how to make different symbols for the rows and columns.
I'm trying to learn and study it for 3 hours already, watched 20 different YouTube videos and read 20 different coding guides.
It's so frustrating..
Thanks.
I'm attaching a picture of my code & my output, and the desired output on the right.
the code itself:
int size;
printf("Please enter a number that will define the size of the square: \n");
scanf("%d", &size);
size = 2 * size + 1;
for (int i = 1; i <= size-2; i++) {
for (int j = 1; j <= size-2; j++) {
if (j == 1 || j == size - 1) {
printf("|");
}
else {
printf(" ");
}
if (i==1 || i==size-2){
printf("-");
}
else {
printf(" ");
}
}
printf("\n");
}
#include <stdio.h>
int main(void) {
int size;
printf("Please enter a number that will define the size of the square: \n");
scanf("%d", &size);
size = 2 * size + 1;
const char *spaces=" ";
const char *dashes="-----------------------------------------";
printf("+%.*s+\n", size, dashes);
for(int i=1; i<size/2+1; ++i)
{
printf("|%.*s\\%.*s/%.*s|\n", i-1, spaces, size-2*i, spaces,i-1, spaces);
}
printf("|%.*sX%.*s|\n", size/2, spaces, size/2, spaces);
for(int i=size/2+1; i<size; ++i)
{
printf("|%.*s/%.*s\\%.*s|\n", size-i-1, spaces, 2*(i-size/2)-1, spaces, size-i-1, spaces);
}
printf("+%.*s+\n", size, dashes);
return 0;
}
Example Run:
Please enter a number that will define the size of the square: 8
Success #stdin #stdout 0s 4568KB
+-----------------+
|\ /|
| \ / |
| \ / |
| \ / |
| \ / |
| \ / |
| \ / |
| \ / |
| X |
| / \ |
| / \ |
| / \ |
| / \ |
| / \ |
| / \ |
| / \ |
|/ \|
+-----------------+
I've been working on a program for my Algorithm Analysis class where I have to solve the Knapsack problem with Brute Force, greedy, dynamic, and branch and bound strategies. Everything works perfectly when I run it in Visual Studio 2012, but if I compile with gcc and run it on the command line, I get a different result:
Visual Studio:
+-------------------------------------------------------------------------------+
| Number of | Processing time in seconds / Maximum benefit value |
| +---------------+---------------+---------------+---------------+
| items | Brute force | Greedy | D.P. | B. & B. |
+---------------+---------------+---------------+---------------+---------------+
| 10 + 0 / 1290 + 0 / 1328 + 0 / 1290 + 0 / 1290 |
+---------------+---------------+---------------+---------------+---------------+
| 20 + 0 / 3286 + 0 / 3295 + 0 / 3200 + 0 / 3286 |
+---------------+---------------+---------------+---------------+---------------+
cmd:
+-------------------------------------------------------------------------------+
| Number of | Processing time in seconds / Maximum benefit value |
| +---------------+---------------+---------------+---------------+
| items | Brute force | Greedy | D.P. | B. & B. |
+---------------+---------------+---------------+---------------+---------------+
| 10 + 0 / 1290 + 0 / 1328 + 0 / 1599229779+ 0 / 1290 |
+---------------+---------------+---------------+---------------+---------------+
| 20 + 0 / 3286 + 0 / 3295 + 0 / 3200 + 0 / 3286 |
+---------------+---------------+---------------+---------------+---------------+
The same number always shows up, "1599229779." Notice that the output is only messed up the first time the Dynamic algorithm is run.
Here is my code:
typedef struct{
short value; //This is the value of the item
short weight; //This is the weight of the item
float ratio; //This is the ratio of value/weight
} itemType;
typedef struct{
time_t startingTime;
time_t endingTime;
int maxValue;
} result;
result solveWithDynamic(itemType items[], int itemsLength, int maxCapacity){
result answer;
int rowSize = 2;
int colSize = maxCapacity + 1;
int i, j; //used in loops
int otherColumn, thisColumn;
answer.startingTime = time(NULL);
int **table = (int**)malloc((sizeof *table) * rowSize);//[2][(MAX_ITEMS*WEIGHT_MULTIPLIER)];
for(i = 0; i < rowSize; i ++)
table[i] = (int*)malloc((sizeof *table[i]) * colSize);
table[0][0] = 0;
table[1][0] = 0;
for(i = 1; i < maxCapacity; i++) table[1][i] = 0;
for(i = 0; i < itemsLength; i++){
thisColumn = i%2;
otherColumn = (i+1)%2; //this is always the other column
for(j = 1; j < maxCapacity + 1; j++){
if(items[i].weight <= j){
if(items[i].value + table[otherColumn][j-items[i].weight] > table[otherColumn][j])
table[thisColumn][j] = items[i].value + table[otherColumn][j-items[i].weight];
else
table[thisColumn][j] = table[otherColumn][j];
} else {
table[thisColumn][j] = table[thisColumn][j-1];
}//end if/else
}//end for
}//end for
answer.maxValue = table[thisColumn][maxCapacity];
answer.endingTime = time(NULL);
for(i = 0; i < rowSize; i ++)
free(table[i]);
free(table);
return answer;
}//end solveWithDynamic
Just a bit of explanation. I was having trouble with the memory consumption of this algorithm because I have to run it for a set of 10,000 items. I realized that I didn't need to store the whole table, because I only ever looked at the previous column. I actually figured out that you only need to store the current row and x+1 additional values, where x is the weight of the current itemType. It brought the memory required from (itemsLength+1) * (maxCapacity+1) elements to 2*(maxCapacity+1) and possibly (maxCapacity+1) + (x+1) (although I don't need to optimize it that much).
Also, I used printf("%d", answer.maxValue); in this function, and it still came out as "1599229779." Can anyone help me figure out what is going on? Thanks.
Can't be sure that that is what causes it, but
for(i = 1; i < maxCapacity; i++) table[1][i] = 0;
you leave table[1][maxCapacity] uninitialised, but then potentially use it:
for(j = 1; j < maxCapacity + 1; j++){
if(items[i].weight <= j){
if(items[i].value + table[otherColumn][j-items[i].weight] > table[otherColumn][j])
table[thisColumn][j] = items[i].value + table[otherColumn][j-items[i].weight];
else
table[thisColumn][j] = table[otherColumn][j];
} else {
table[thisColumn][j] = table[thisColumn][j-1];
}//end if/else
}//end for
If that is always zero with Visual Studio, but nonzero with gcc, that could explain the difference.