Assigning multidimensional array from a function call to a variable - c

Hi guys I have a question
How do I pass a Multi-dimensional Array from a Function to the main function and from there we want to pass it to another function.
float array2[][3] = get_sizes(numbers);
The compiler says that the string above is an error because getsizes is an invalid initaliser.
Can somebody tell us what we are doing wrong?
Thank you in advance.
EDIT
int main()
{
float anzahl = get_number();
if(feof(stdin))
{
return 0;
}
int anzahl2 = anzahl;
float array2[][3] = get_sizes(anzahl);
if (feof(stdin))
{
return 0;
}
triangulation(array2, anzahl2);
return 0;
}
int get_number(void)
{
printf("Please enter the number of triangles to check: ");
int anzahl = 0;
char check = 0;
int ret = 0;
while(!(ret == 2 && check == '\n'))
{
ret = scanf("%d%c", &anzahl, &check);
if (feof(stdin))
{
return 0;
}
if (check != '\n')
{
printf("[ERR] Invalid number of triangles.\n");
printf("Please enter the number of triangles to check: ");
my_flush();
}
if((check == '\n' && anzahl > UCHAR_MAX) || (check == '\n' && anzahl <= 0))
{
printf("[ERR] Invalid number of triangles.\n");
printf("Please enter the number of triangles to check: ");
ret = 3;
}
}
return anzahl;
void my_flush(void)
{
while(getchar() != '\n')
{
}
}
int vgl(const void *a, const void *b)
{
int aa, bb;
aa = *(int *)a;
bb = *(int *)b;
return (aa - bb);
float get_sizes(int anzahl)
{
float array [3] = {0,0,0};
float array2[100][3];
while(anzahl>0)
{
char check = 0;
int ret = 0;
while(!(ret == 2 && check == '\n'))
{
printf("Please enter the first number of the triplet: ");
ret = scanf("%f%c",&array[0], &check);
if (feof(stdin))
{
return 0;
}
if (check != '\n')
{
printf("[ERR] Invalid number of triangles.\n");
my_flush();
}
if((check == '\n' && array[0] <= 0.0)|| (check == '\n' && array[0] >=
FLT_MAX))
{
printf("[ERR] Invalid number of triangles.\n");
ret = 3;
}
}
check = 0;
ret = 0;
while(!(ret == 2 && check == '\n'))
{
printf("Please enter the second number of the triplet: ");
ret = scanf("%f%c",&array[1], &check);
if (feof(stdin))
{
return 0;
}
if (check != '\n')
{
printf("[ERR] Invalid number of triangles.\n");
my_flush();
}
if((check == '\n' && array[0] <= 0.0)|| (check == '\n' && array[0] >=
FLT_MAX))
{
printf("[ERR] Invalid number of triangles.\n");
ret = 3;
}
}
check = 0;
ret = 0;
while(!(ret == 2 && check == '\n'))
{
printf("Please enter the third number of the triplet: ");
ret = scanf("%f%c",&array[2], &check);
if (feof(stdin))
{
return 0;
}
if (check != '\n')
{
printf("[ERR] Invalid number of triangles.\n");
my_flush();
}
if((check == '\n' && array[0] <= 0.0)|| (check == '\n' && array[0] >=
FLT_MAX))
{
printf("[ERR] Invalid number of triangles.\n");
ret = 3;
}
}
qsort(array, 3, sizeof(array[3]), vgl);
array2[anzahl][0]=array[0];
array2[anzahl][1]=array[1];
array2[anzahl][2]=array[2];
anzahl--;
}
return array2;
float triangulation(float array2[100][3], int anzahl2)
{
int number = 1;
while(anzahl2>0)
{
if(array2[anzahl2][0] == 1 && array2[anzahl2][1] == 1 && array2[anzahl2]
[2] == 2)
{
printf("Tripelt %d (a=%f, b=%f, c=%f)is NO triangle.\n", number,
array2[anzahl2][0], array2[anzahl2][1], array2[anzahl2][2]);
}
else
{
printf("Tripelt %d (a=%f, b=%f, c=%f)is a triangle.\n", number,
array2[anzahl2][0], array2[anzahl2][1], array2[anzahl2][2]);
if(array2[anzahl2][0] == array2[anzahl2][1] && array2[anzahl2][0] ==
array2[anzahl2][2] && array2[anzahl2][1]== array2[anzahl2][2])
{
printf("It is an equilateral triangle.\n");
printf("It is a isosceles triangle.\n");
}
else if(array2[anzahl2][0] == array2[anzahl2][1] || array2[anzahl2][0] ==
array2[anzahl2][2] || array2[anzahl2][1]== array2[anzahl2][2])
{
printf("It is a isosceles triangle.\n");
}
else if(((array2[anzahl2][0])*(array2[anzahl2][0])) + ((array2[anzahl2]
[1])*(array2[anzahl2][1])) == ((array2[anzahl2][2])*(array2[anzahl2][2])))
{
printf("It is a right triangle.\n");
}
}
anzahl2--;
number++;
}
}
This is the whole code i'ts long
and we aren't allowed to use global variables

Here is a demonstrative program that shows how in general it can be done.
#include <stdio.h>
#include <stdlib.h>
#define N 3
float ( * get_sizes( size_t n ) )[N]
{
float ( *a )[N] = malloc( n * sizeof( float[N] ) );
for ( size_t i = 0; i < n; i++ )
{
for ( size_t j = 0; j < N; j++ )
{
a[i][j] = i * N + j;
}
}
return a;
}
void display( float( *a )[N], size_t n )
{
for ( size_t i = 0; i < n; i++ )
{
for ( size_t j = 0; j < N; j++ )
{
printf( "%4.1f ", a[i][j] );
}
putchar( '\n' );
}
}
int main(void)
{
size_t n = 4;
float ( *a )[N] = get_sizes( 4 );
display( a, n );
free( a );
return 0;
}
The program output is
0.0 1.0 2.0
3.0 4.0 5.0
6.0 7.0 8.0
9.0 10.0 11.0
That is you need to allocate the array dynamically.

This simple code indicates you how to send a bi-dimensional array to a function. The function func1 retrieves the value in float a pointed by int x and int y. The same should be done also for more than two dimensions.
#include <stdio.h>
float func1(float *,int x, int y,int mx, int my);
float func1(float * a,int x, int y,int mx, int my)
{
if (x>=mx)
return 0;
if (y>=my)
return 0;
return a[x*my+y];
}
int main(void)
{
#define _MX 4
#define _MY 3
int x, y;
float a[_MY][_MX] = {
{0.0,0.1,0.2,0.3},
{1.0,1.1,1.2,1.3},
{2.0,2.1,2.2,2.3}
};
for(x=0;x<_MX;x++) {
for(y=0;y<_MY;y++){
// With cast
printf("x =%2d y =%2d => v = %f\n",x,y,func1((float *)a,x,y,_MX,_MY));
}
}
puts("---------------------------------");
for(x=0;x<_MX;x++) {
for(y=0;y<_MY;y++){
// Without cast
printf("x =%2d y =%2d => v = %f\n",x,y,func1(a[0],x,y,_MX,_MY));
}
}
return 0;
}

Related

My problem with the size of the number in the My_Mastermind minigame

can you help me with the size of the digits, for example, when I enter 01234, then everything works as it should, but it shouldn’t, the limit of digits should be within four.When I enter some four-digit number, everything works as it should work. But when some five-digit, six-digit or even more, then everything works as if it should be, but it should not work like that. And when I enter numbers that are less than four-digit, for example 123 , then it gives an error and it's good. But when I enter numbers that are more than four digits, it does not give an error and works as if it should be so.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
typedef struct s_mastermind {
int my_attempt;
char* my_code;
} my_mastermind;
my_mastermind* settings_function(my_mastermind* mastermind, int argc, char** argv);
int checking_for_correctness_num(char* _string);
int wrong_input(int progress,char* num_code);
my_mastermind* my_function();
int check_function(char* string);
char* input_function();
int mis_placed_pieces(char* bit, char* num_code);
int well_placed_pieces(char* bit, char* num_code);
int code_checker(char* bit, char* num_code);
char* size_of_function(char* strye);
char* my_strcpy(char* num1, char* num2) {
for(int i = 0; num2[i] != 0; i++) {
num1[i] = num2[i];
}
return num1;
}
int my_strlen(char* num1) {
return (*num1) ? my_strlen(++num1) + 1 : 0;
}
my_mastermind* my_function() {
my_mastermind* num = malloc(sizeof(my_mastermind));
num->my_code = malloc(5);
num->my_code[4] = '\0';
my_strcpy(num->my_code, "");
num->my_attempt = 10;
return num;
}
my_mastermind* settings_function(my_mastermind* mastermind, int argc, char** argv) {
char* bit;
for(int i = 0; i < argc;) {
if (my_strlen(argv[i]) == 2 && argv[i][0] == '-') {
if(argv[i][1] == 'c') {
char* num_code = argv[i + 1];
if(wrong_input(argc,num_code) != 0) {
break;
}
my_strcpy(mastermind->my_code, num_code);
}else if(argv[i][1] == 't') {
if(checking_for_correctness_num(argv[i + 1]) == 0) {
mastermind->my_attempt = check_function(argv[i + 1]);
}
} else {
printf("WRONG FLAG RESTART THE GAME!!!\n");
}
}
i += 1;
}
return mastermind;
}
int wrong_input(int progress,char* num_code) {
// if(my_strlen(num_code) != 4) {
// printf("Code bigger than 4\n");
// }
if(checking_for_correctness_num(num_code) == 1) {
printf("Wrong input!\n> ");
fflush(stdout);
char* code = input_function();
char* variable = size_of_function(code);
free(code);
int results = 1;
if(wrong_input(progress,variable) == 0) {
results = code_checker(num_code, variable);
}
free(variable);
return results;
}
return 0;
}
int checking_for_correctness_num(char* _string) {
for(int i = 0; _string[i] != '\0'; i++) {
if(!(_string[i] >= '0' && _string[i] <= '9')) {
return 1;
}
}
return 0;
}
int check_function(char* string) {
int check_num = 0;
for(int i = 0; string[i] != '\0'; i++) {
check_num = check_num * 10 + (string[i] - '0');
}
return check_num;
}
char* input_function() {
char* getting = malloc(101);
getting[100] = '\0';
read(0, getting, 100);
fflush(stdout);
return getting;
}
int game_progress(int progress, char* bit) {
printf("Round: %d\n> ", progress);
fflush(stdout);
char* code = input_function();
char* variable = size_of_function(code);
free(code);
int results = 1;
if(wrong_input(progress,variable) == 0) {
results = code_checker(bit, variable);
}
free(variable);
return results;
}
void game_action(my_mastermind* mastermind) {
int current_try = 0;
for (;current_try < mastermind->my_attempt;) {
int results = game_progress(current_try, mastermind->my_code);
current_try += 1;
if(results == 0) {
printf("Congratz! You did it!\n");
break;
}
}
}
int code_checker(char* bit, char* num_code) {
int good_w = well_placed_pieces(bit, num_code);
int not_good_m = mis_placed_pieces(bit, num_code);
if(good_w == 3 || good_w == 2 || good_w == 1 || not_good_m == 3 || not_good_m == 2 || not_good_m == 1){
printf("Well placed pieces: %d\nMisplaced pieces: %d\n---\n", good_w,not_good_m);
}
if(good_w == 4) {
return 0;
} else {
return 1;
}
}
int well_placed_pieces(char* bit, char* num_code) {
int number = 0;
for(int i = 0; i < 4; i++) {
if (bit[i] == num_code[i]) {
number += 1;
}
}
return number;
}
int mis_placed_pieces(char* bit, char* num_code) {
int number = 0;
int i = 0;
int j = 0;
while(i < 4) {
i++;
if (bit[i] == num_code[i]) {
number += 1;
}
}
return number;
}
char* size_of_function(char* strye) {
char* new_string = malloc(5);
new_string[4] = '\0';
for(int i = 0; i < 4;i++){
new_string[i] = strye[i];
}
return new_string;
}
int main(int argc, char** argv) {
printf("Will you find the secret code?\n---\n");
my_mastermind* mastermind = my_function();
settings_function(mastermind, argc, argv);
game_action(mastermind);
free(mastermind);
return 0;
}
The problem is that you size_of_function assumes the input string is exactly 4 character long, not counting the '\0'. You should either check if the input string and return a error via a NULL pointer, or fully copy the string and check later.
Returning a NULL pointer require the least modification. You can do it by checking the input string size first :
char* size_of_function(char* strye) {
if(my_strlen(strye) != 4)
return NULL;
char* new_string = malloc(5);
new_string[4] = '\0';
for(int i = 0; i < 4;i++){
new_string[i] = strye[i];
}
if (strye[4] == '\r' || strye[4] == '\n' || strye[4] == '\0')
return new_string;
free(new_string);
return NULL;
}
Then, in wrong_input(), check if num_code is NULL :
int wrong_input(int progress,char* num_code) {
if(num_code == NULL || checking_for_correctness_num(num_code) == 1) {
printf("Wrong input!\n> ");
fflush(stdout);
char* code = input_function();
char* variable = size_of_function(code);
free(code);
int results = 1;
if(wrong_input(progress,variable) == 0) {
results = code_checker(num_code, variable);
}
free(variable);
return results;
}
return 0;
}
It is critical to check if num_code is NULL before calling checking_for_correctness_num(). In C the || operator evaluates the left operand first and skip the second operand evaluation if the first one is true. This way we can ensure that we never pass a NULL pointer to checking_for_correctness_num().
wrong_input() is called recursively and allocates memory without freeing it before calling itself. This can eat up memory fast and is generality considered to be bad practice.
Also, you've implemented my_strlen() as a recursive function, which isn't necessary. Using a loop is better :
int my_strlen(char* num1) {
int index = 0;
while(num1[index++]); //Note that 'index' is post-incremented
return index - 1; //Subtract one to account for the last post increment
}

Array of structures lose data while passing it in C

I don't understand why printq() function prints 0, but when I access it back in main() it prints. I don't understand what I am doing wrong, I tried using pointers, but I get some different error in the priority queue. I want to print elements in array pq[10].
EDIT: I realized that the elements are stored but when I use pq[R].data it prints
but when I use pq[i].data in printq() and put it inside for loop, it prints zero.
#include <stdio.h>
int F = -1, R = -1;
int item, max = 10;
struct prioq {
int data;
int prio;
};
struct prioq pq[10] = { 0 };
void printq()
{
int i = 0;
printf("%d,", pq[i].data);
printf("QUEUE :");
for (i = 0; i < max; i++) {
printf("%d,", pq[i].data);
}
printf("\n");
printf("PRIO :");
for (i = 0; i < max; i++) {
printf("%d,", pq[i].prio);
}
}
void enqueue(int item, int p, struct prioq pq[])
{
if (F == -1 && R == -1 || F > R) {
F == 0;
R == 0;
pq[R].data = item;
pq[R].prio = p;
printf("%d", pq[R].data);
printf("%d", pq[R].prio);
printq();
} else if (R == max-1 || R > max) {
printf("overflow\n");
} else if (R < max) {
R++;
pq[R].data = item;
pq[R].prio = p;
printq();
}
}
void dequeue(struct prioq pq[])
{
int large = 0;
if (F == -1) {
printf("underflow\n");
} else {
int i;
for (i = 0; i < max; i++) {
if (pq[i].prio > large) {
large = i;
}
}
}
item = pq[large].data;
pq[large].prio = 0;
pq[large].data = 0;
printf("item deleted: %d\n", item);
printq();
}
void main()
{
int item = 0;
int c = 0, p = 0;
do {
printf("choose your option\n");
printf("1.Insert, 2.Delete, 3.Exit\n" );
scanf("%d", &c);
switch (c) {
case 1:
printf("Enter the priority and element to insert\n");
scanf("%d %d", &item, &p);
enqueue(item,p,pq);
printf("%d", pq[R].data);
printf("%d", pq[R].prio);
break;
case 2:
dequeue(pq);
break;
default:
c = 3;
break;
}
} while (c != 3);
printf("exited\n");
}
In your enqueue function, change the == in the F and R assignments to =.
void enqueue(int item, int p, struct prioq pq[])
{
if (F == -1 && R == -1 || F > R) {
F = 0; // Here
R = 0; // And here
pq[R].data = item;
pq[R].prio = p;
printf("%d", pq[R].data);
printf("%d", pq[R].prio);
printq();
} else if (R == max-1 || R > max) {
printf("overflow\n");
} else if (R < max) {
R++;
pq[R].data = item;
pq[R].prio = p;
printq();
}
}

Minesweeper in C [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
The game works perfectly, but I want to add a timer that measures and shows at the end of the game, the time the player's game lasted.
The code is a classic game of minesweeper where the user gives the coordinates of the point he wants to discover from the board, the game is made in c, not in C#.
The game consists of clearing all the squares of a two-dimensional arrangement that do not hide a mine. Some squares will have a random mine while others will not. The user is asked to position a box in the two-dimensional arrangement, if he does not find a mine he will continue the game until he wins, otherwise he will finish the game and the user will lose.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define FLUSH fflush(stdin)
void difficulty( void );
void beginner( void );
void intermediate( void );
void expert( void );
void minefield_generator( void );
void print_minefield( void );
void guess( void );
void boom( void );
void print_final_minefield( void );
void win( void );
void play_again( void );
void game_over( void );
int x, y;
int M, N;
float diff;
int total_mines = 0;
int mines = 0;
int minefield[30][30]; //This 2-D array contains all of the mines, numbers and blank spaces
int blank_minefield[30][30]; //This contains the minefield full of '|-|' characters
int final_minefield[30][30];
int main()
{
printf("\t\tWelcome to Minesweeper\n");
difficulty();
return 0;
}
void difficulty( void ) //Function for choosing the difficulty level
{
diff = 0;
while( (diff != 1) && (diff != 2) && (diff != 3) && (diff != 4))
{
printf("\t\tChoose a difficulty level(1-3) or 4 for a custom game:");
scanf("%f", &diff);
FLUSH;
if( (diff != 1) && (diff != 2) && (diff != 3) && (diff != 4))
{
printf("\t\tPlease enter either 1, 2, 3 or 4\n");
}
}
if( diff == 1 ) //If, else if and else statements that each go to the respective difficulty
{
beginner();
}
else if( diff == 2 )
{
intermediate();
}
else if( diff == 3 )
{
expert();
}
else if( diff == 4)
{
custom();
}
}
void beginner( void ) //Gives the minefield the 'beginner' grid and mines
{
M = 9;
N = 9;
total_mines = 10;
minefield_generator();
guess();
}
void intermediate( void ) //Gives the minefield the 'intermediate' grid and mines
{
M = 16;
N = 16;
total_mines = 40;
minefield_generator();
guess();
}
void expert( void ) //Gives the minefield the 'expert' grid size and mines
{
M = 16;
N = 30;
total_mines = 99;
minefield_generator();
guess();
}
void custom( void )
{
M = 0;
N = 0;
total_mines = 0;
printf("\t\tPlease enter the size of the dimensions you want\n");
printf("\t\tFirst value:\n");
scanf("%d", &M);
printf("\t\tSecond value:\n");
scanf("%d", &N);
printf("\t\tNumber of mines you want to assign to the board:\n");
scanf("%d", &total_mines);
minefield_generator();
guess();
}
void minefield_generator( void ) //Function that generates the minefield
{
int i = 0, j = 0;
srand( time( NULL ) ); //Starts the random no. generator
while( j < N ) //Nested loop for making the blank minefield and final minefield
{
while( i < M)
{
minefield[i][j] = '-';
blank_minefield[i][j] = minefield[i][j];
final_minefield[i][j] = minefield[i][j];
i++;
}
i = 0;
j++;
}
mines = 0;
while( mines < total_mines ) //Randomly generates the mines into the minefield
{
i = rand()%(M);
j = rand()%(N);
if( minefield[i][j] != '*') //If statement that checks if there is a mine already there and doesn't place a mine if there is
{
minefield[i][j] = '*';
final_minefield[i][j] = minefield[i][j];
mines++;
}
}
i = 0;
j = 0;
while( j < N ) //While loop that generates the numbers for any adjacent mines
{
while( i < M)
{
if( minefield[i][j] != '*')
{
minefield[i][j] = 0;
}
if((minefield[i-1][j-1] == '*') && (minefield[i][j] != '*'))
{
minefield[i][j]++;
}
if((minefield[i-1][j] == '*') && (minefield[i][j] != '*'))
{
minefield[i][j]++;
}
if((minefield[i][j-1] == '*') && (minefield[i][j] != '*'))
{
minefield[i][j]++;
}
if((minefield[i-1][j+1] == '*') && (minefield[i][j] != '*'))
{
minefield[i][j]++;
}
if((minefield[i+1][j-1] == '*') && (minefield[i][j] != '*'))
{
minefield[i][j]++;
}
if((minefield[i+1][j] == '*') && (minefield[i][j] != '*'))
{
minefield[i][j]++;
}
if((minefield[i][j+1] == '*') && (minefield[i][j] != '*'))
{
minefield[i][j]++;
}
if((minefield[i+1][j+1] == '*') && (minefield[i][j] != '*'))
{
minefield[i][j]++;
}
i++;
}
i = 0;
j++;
}
i = 0;
j = 0;
}
void print_minefield(void) // This function prints the minefield
{
int i = 0, j = 0, z = 0;
while( z < M ) // This while loop prints out the line of co-ordinates along the x axis of the minefield
{
if( z == 0 )
{
printf("\t");
}
printf("|%d|\t", z);
z++;
}
printf("\n\n");
while( j < N ) // Loop that prints out each character in the minefield
{
printf("|%d|\t", j);
while( i < M)
{
if( blank_minefield[i][j] == '-')
{
printf("|%c|\t", blank_minefield[i][j]);
}
else if( minefield[i][j] == 0 ) // This changes any spaces with values of zero to the character 'B'
{
blank_minefield[i][j] = 'B';
printf("|%c|\t", blank_minefield[i][j]);
}
else
{
printf("|%d|\t", blank_minefield[i][j]);
}
i++;
}
printf("\n");
i = 0;
j++;
}
}
void guess( void )
{
int q = 0, i=0, j=0, match=0;
print_minefield();
while( j < N ) // While loop for testing whether or not the user has cleared the minefield
{
while( i < M )
{
if(minefield[i][j] == blank_minefield[i][j])
{
match++;
}
i++;
}
i = 0;
j++;
}
if( match == (( M * N ) - total_mines)) // If the user has cleared the minefield, the win() function is run
{
win();
}
printf("\nEnter the x value, then a space, then the y value:");
scanf("%d %d", &x, &y); // Reading in the co-ordinates for the guess
FLUSH;
if( (x >= M) || (x < 0) || (y < 0) || (y >= N) )
{
printf("\nPlease enter a value inside the grid\n");
guess();
}
if( minefield[x][y] == '*' ) // Runs the boom() function if the user selects a mine
{
boom();
}
if( blank_minefield[x][y] != '-' )
{
printf("\nPlease enter a value that has not already been entered\n");
guess();
}
else // Checks if the adjacent spaces are blank, then changes the values in the blank_minefield array. Because they are changed, they will now print out in the print_minefield function
{
blank_minefield[x][y] = minefield[x][y];
if( minefield[x][y] == 0 )
{
if( minefield[x-1][y-1] == 0 )
{
blank_minefield[x-1][y] = minefield[x-1][y];
}
if( minefield[x-1][y] == 0 )
{
blank_minefield[x-1][y] = minefield[x-1][y];
}
if( minefield[x][y-1] == 0 )
{
blank_minefield[x][y-1] = minefield[x][y-1];
}
if( minefield[x-1][y+1] == 0 )
{
blank_minefield[x-1][y+1] = minefield[x-1][y+1];
}
if( minefield[x+1][y-1] == 0 )
{
blank_minefield[x+1][y-1] = minefield[x+1][y-1];
}
if( minefield[x+1][y] == 0 )
{
blank_minefield[x+1][y] = minefield[x+1][y];
}
if( minefield[x][y+1] == 0 )
{
blank_minefield[x][y+1] = minefield[x][y+1];
}
if( minefield[x+1][y+1] == 0 )
{
blank_minefield[x+1][y+1] = minefield[x+1][y+1];
}
}
guess();
}
}
void boom( void ) // Runs the print_final_minefield function, then the play_again function
{
print_final_minefield();
printf("\n\t\tYou hit a mine at %d,%d\n\t\tYOU LOSE!!!!", x, y);
play_again();
}
void print_final_minefield( void ) // Prints the minefield, showing where all of the mines are placed
{
int i = 0, j = 0, z = 0;
while( z < M )
{
if( z == 0 )
{
printf("\t");
}
printf("|%d|\t", z);
z++;
}
printf("\n\n");
while( j < N )
{
printf("|%d|\t", j);
while( i < M)
{
printf("|%c|\t", final_minefield[i][j]);
i++;
}
printf("\n");
i = 0;
j++;
}
}
void win( void ) // Runs the play_again function
{
printf("\n\n\n\t\t\tYOU WIN!!!!!\n\n\n");
play_again();
}
void play_again( void ) // Gives the user the option to play again
{
char option[2];
printf("\n\t\tWould you like to play again(Y/N)?:");
scanf("%c", &option[0]);
FLUSH;
if((option[0] == 'Y') || (option[0] == 'y')) // Restarts the program from after the welcome message
{
difficulty();
}
else if( (option[0] == 'N') || (option[0] == 'n'))
{
game_over();
}
else
{
printf("Please enter either Y or N");
play_again();
}
}
void game_over( void ) // Ends the program
{
printf("\n\n\t\tGame Over");
exit(1);
}
Use the function clock() to catch the moment’s clock, and then use the macro CLOCKS_PER_SEC to calculate how many second has gone by. Like this:
int timeInSeconds;
clock_t start = clock(), end,total;
...
end = clock();
total = end - start;
timeInSeconds = total/CLOCKS_PER_SEC;

Printing string pointers in c

So, essentially I have two files:
File 1:
//
// main.c
// frederickterry
//
// Created by Rick Terry on 1/15/15.
// Copyright (c) 2015 Rick Terry. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int size (char *g) {
int ofs = 0;
while (*(g+ofs) != '\0') {
++ofs;
}
return ofs;
}
int parse(char *g) {
// Setup
char binaryConnective;
int negated = 0;
// Looking for propositions
int fmlaLength = size(g);
if(fmlaLength == 0) {
return 1;
}
if(fmlaLength == 1) {
if(g[0] == 'p') {
return 1;
} else if (g[0] == 'q') {
return 1;
} else if (g[0] == 'r') {
return 1;
} else {
return 0;
}
}
// Now looking for negated preposition
if(fmlaLength == 2) {
char temp[100];
strcpy(temp, g);
if(g[0] == '-') {
negated = 1;
int negatedprop = parse(g+1);
if(negatedprop == 1) {
return 2;
}
}
}
// Checking if Binary Formula
char arrayleft[50];
char arrayright[50];
char *left = "";
char *right = "";
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int binarypresent = 0;
if(fmlaLength != 1 && fmlaLength != 2) {
if(g[0] == '-') {
int negatedBinary = parse(g+1);
if(negatedBinary == 1 || negatedBinary == 2 || negatedBinary == 3) {
return 2;
} else {
return 0;
}
}
int i = 0;
int l = 0;
int p = strlen(g);
for(l = 0; l < strlen(g)/2; l++) {
if(g[l] == '(' && g[p-l-1] == ')') {
i++;
}
}
for(int q = i; q < strlen(g); q++) {
if(g[q] == '(') {
numLeft++;
} else if(g[q] == ')') {
numRight++;
}
arrayleft[q] = g[q];
//printf("%c", arrayleft[i]);
//printf("%s", left);
if((numRight == numLeft) && (g[q+1] == 'v' || g[q+1] == '>' || g[q+1] == '^')) {
arrayleft[q+1] = '\0';
bclocation = q+1;
binaryConnective = g[q+1];
binarypresent = 1;
// printf("The binary connecive is: %c\n", binaryConnective);
break;
}
}
if(binarypresent == 0) {
return 0;
}
int j = 0;
for(int i = bclocation+1; i < strlen(g)-1; i++) {
arrayright[j] = g[i];
j++;
}
arrayright[j] = '\0';
left = &arrayleft[1];
right = &arrayright[0];
//printf("Printed a second time, fmla 1 is: %s", left);
int parseleft = parse(left);
// printf("Parse left result: %d\n", parseleft);
if(parseleft == 0) {
return 0;
}
int parseright = parse(right);
if(parseright == 0) {
return 0;
}
// printf("Parse right result: %d\n", parseleft);
if(negated == 1) {
return 2;
} else {
return 3;
}
}
return 0;
}
int type(char *g) {
if(parse(g) == 1 ||parse(g) == 2 || parse(g) == 3) {
if(parse(g) == 1) {
return 1;
}
/* Literals, Positive and Negative */
if(parse(g) == 2 && size(g) == 2) {
return 1;
}
/* Double Negations */
if(g[0] == '-' && g[1] == '-') {
return 4;
}
/* Alpha & Beta Formulas */
char binaryConnective;
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int binarypresent = 0;
int i = 0;
if(g[0] == '(') {
i++;
}
if(g[0] == '-') {
i++;
if(g[1] == '(') {
i++;
}
}
for(i; i < strlen(g); ++i) {
if(g[i] == '(') {
numLeft++;
} else if(g[i] == ')') {
numRight++;
}
if(numRight == numLeft) {
if(g[i+1] == 'v' || g[i+1] == '>' || g[i+1] == '^') {
bclocation = i+1;
binaryConnective = g[i+1];
binarypresent = 1;
break;
}
}
}
/* Connective established */
if(binaryConnective == '^') {
if(g[0] == '-') {
return 3;
} else {
return 2;
}
} else if(binaryConnective == '>') {
if(g[0] == '-') {
return 2;
} else {
return 3;
}
} else if (binaryConnective == 'v') {
if(g[0] == '-') {
return 2;
} else {
return 3;
}
}
}
return 0;
}
char bin(char *g) {
char binaryConnective;
char arrayLeft[50];
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int i = 0;
if(g[0] == '(') {
i++;
}
if(g[0] == '-') {
i++;
if(g[1] == '(') {
i++;
}
}
for(i; i < strlen(g); ++i) {
if(g[i] == '(') {
numLeft++;
} else if(g[i] == ')') {
numRight++;
}
int j = 0;
arrayLeft[j++] = g[i];
if(numRight == numLeft) {
if(g[i+1] == 'v' || g[i+1] == '>' || g[i+1] == '^') {
arrayLeft[i+1] = '\0';
bclocation = i+1;
binaryConnective = g[i+1];
return binaryConnective;
}
}
}
return binaryConnective;
}
char *partone(char *g) {
char binaryConnective;
char arrayLeft[50];
char arrayRight[50];
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int i = 0;
if(g[0] == '(') {
i++;
}
if(g[0] == '-') {
i++;
if(g[1] == '(') {
i++;
}
}
int j = 0;
for(i; i < strlen(g); ++i) {
if(g[i] == '(') {
numLeft++;
} else if(g[i] == ')') {
numRight++;
}
arrayLeft[j] = g[i];
if(numRight == numLeft) {
if(g[i+1] == 'v' || g[i+1] == '>' || g[i+1] == '^') {
arrayLeft[j+1] = '\0';
bclocation = i+1;
binaryConnective = g[i+1];
break;
}
}
j++;
}
int m = 0;
for(int k = bclocation+1; k < strlen(g)-1; k++) {
arrayRight[m] = g[k];
m++;
}
arrayRight[m] = '\0';
char* leftSide = &arrayLeft[0];
// printf("%s\n", leftSide);
// printf("%s\n", rightSide);
int k = 0;
k++;
return leftSide;
}
char *parttwo(char *g) {
char binaryConnective;
char arrayLeft[50];
char arrayRight[50];
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int i = 0;
if(g[0] == '(') {
i++;
}
if(g[0] == '-') {
i++;
if(g[1] == '(') {
i++;
}
}
int j = 0;
for(i; i < strlen(g); ++i) {
if(g[i] == '(') {
numLeft++;
} else if(g[i] == ')') {
numRight++;
}
arrayLeft[j] = g[i];
if(numRight == numLeft) {
if(g[i+1] == 'v' || g[i+1] == '>' || g[i+1] == '^') {
arrayLeft[j+1] = '\0';
bclocation = i+1;
binaryConnective = g[i+1];
break;
}
}
j++;
}
int m = 0;
int n = size(g) - 1;
if(g[strlen(g)-1] != ')') {
n++;
}
for(int k = bclocation+1; k < n; k++) {
arrayRight[m] = g[k];
m++;
}
arrayRight[m] = '\0';
char* leftSide = &arrayLeft[0];
char* rightSide = &arrayRight[0];
// printf("%s\n", leftSide);
// printf("%s\n", rightSide);
return rightSide;
}
char *firstexp(char *g) {
char* left = partone(g);
char leftArray[50];
int i = 0;
for(i; i < strlen(left); i++) {
leftArray[i] = left[i];
}
leftArray[i] = '\0';
char binConnective = bin(g);
int typeG = type(g);
if(typeG == 2) {
if(binConnective == '^') {
return &leftArray;
} else if(binConnective == '>') {
return &leftArray;
}
} else if(typeG == 3) {
if(binConnective == 'v')
return &leftArray;
}
char temp[50];
for(int i = 0; i < strlen(leftArray); i++) {
temp[i+1] = leftArray[i];
}
temp[0] = '-';
char* lefttwo = &temp[0];
if(typeG == 2) {
if(binConnective == 'v') {
return lefttwo;
}
} else if(typeG == 3) {
if(binConnective == '>' || binConnective == '^') {
return lefttwo;
}
}
return "Hello";
}
char *secondexp(char *g) {
// char binaryConnective = bin(g);
// char* right = parttwo(g);
// char rightArray[50];
// int i = 0;
// for(i; i< strlen(right); i++) {
// rightArray[i+1] = right[i];
// }
// rightArray[i] = '\0';
// int typeG = type(g);
// if(type(g) == 2) {
// if(binaryConnective == '^') {
// return &rightArray;
// }
// } else if(type(g) == 3) {
// if(binaryConnective == 'v' || binaryConnective == '>') {
// return &rightArray;
// }
// }
return "Hello";
}
typedef struct tableau tableau;
\
\
struct tableau {
char *root;
tableau *left;
tableau *right;
tableau *parent;
int closedbranch;
};
int closed(tableau *t) {
return 0;
}
void complete(tableau *t) {
}
/*int main(int argc, const char * argv[])
{
printf("Hello, World!\n");
printf("%d \n", parse("p^q"));
printf("%d \n", type("p^q"));
printf("%c \n", bin("p^q"));
printf("%s\n", partone("p^q"));
printf("%s\n", parttwo("p^q"));
printf("%s\n", firstexp("p^q"));
printf("Simulation complete");
return 0;
}*/
File 2:
#include <stdio.h>
#include <string.h> /* for all the new-fangled string functions */
#include <stdlib.h> /* malloc, free, rand */
#include "yourfile.h"
int Fsize = 50;
int main()
{ /*input a string and check if its a propositional formula */
char *name = malloc(Fsize);
printf("Enter a formula:");
scanf("%s", name);
int p=parse(name);
switch(p)
{case(0): printf("not a formula");break;
case(1): printf("a proposition");break;
case(2): printf("a negated formula");break;
case(3): printf("a binary formula");break;
default: printf("what the f***!");
}
printf("\n");
if (p==3)
{
printf("the first part is %s and the second part is %s", partone(name), parttwo(name));
printf(" the binary connective is %c \n", bin(name));
}
int t =type(name);
switch(t)
{case(0):printf("I told you, not a formula");break;
case(1): printf("A literal");break;
case(2): printf("An alpha formula, ");break;
case(3): printf("A beta formula, ");break;
case(4): printf("Double negation");break;
default: printf("SOmewthing's wrong");
}
if(t==2) printf("first expansion fmla is %s, second expansion fmla is %s\n", firstexp(name), secondexp(name));
if(t==3) printf("first expansion fmla is %s, second expansion fmla is %s\n", firstexp(name), secondexp(name));
tableau tab;
tab.root = name;
tab.left=0;
tab.parent=0;
tab.right=0;
tab.closedbranch=0;
complete(&tab);/*expand the root node then recursively expand any child nodes */
if (closed(&tab)) printf("%s is not satisfiable", name);
else printf("%s is satisfiable", name);
return(0);
}
If you look at the first file, you'll see a method called * firstexp(char * g).
This method runs perfectly, but only if another method called * secondexp(char * g) is commented out.
If * secondexp(char * g) is commented out, then *firstexp runs like this:
Enter a formula:((pvq)>-p)
a binary formula
the first part is (pvq) and the second part is -p the binary connective is >
A beta formula, first expansion fmla is -(pvq), second expansion fmla is Hello
((pvq)>-p) is satisfiableProgram ended with exit code: 0
otherwise, if *secondexp is not commented out, it runs like this:
Enter a formula:((pvq)>-p)
a binary formula
the first part is (pvq) and the second part is -p the binary connective is >
A beta formula, first expansion fmla is \240L, second expansion fmla is (-
((pvq)>-p) is satisfiable. Program ended with exit code: 0
As you can see, the outputs are completely different despite the same input. Can someone explain what's going on here?
In the commented-out parts of secondexp and in parttwo, you return the address of a local variable, which you shouldn't do.
You seem to fill a lot of ad-hoc sized auxiliary arrays. These have the problem that they might overflow for larger expressions and also that you cannot return them unless you allocate them on the heap with malloc, which also means that you have to free them later.
At first glance, the strings you want to return are substrings or slices of the expression string. That means that the data for these strings is already there.
You could (safely) return pointers into that string. That is what, for example strchr and strstr do. If you are willing to modify the original string, you could also place null terminators '\0' after substrings. That's what strtok does, and it has the disadvantage that you lose the information at that place: If you string is a*b and you modify it to a\0b, you will not know which operator there was.
Another method is to create a struct that stores a slice as pointer into the string and a length:
struct slice {
const char *p;
int length;
};
You can then safely return slices of the original string without needing to worry about additional memory.
You can also use the standard functions in most cases, if you stick to the strn variants. When you print a slice, you can do so by specifying a field width in printf formats:
printf("Second part: '%.*s'\n", s->length, s->p);
In your parttwo() function you return the address of a local variable
return rightSide;
where rightSide is a pointer to a local variable.
It appears that your compiler gave you a warning about this which you solved by making a pointer to the local variabe arrayRight, that may confuse the compiler but the result will be the same, the data in arrayRight will no longer exist after the function returns.
You are doing the same all over your code, and even worse, in the secondexp() function you return a the address of a local variable taking it's address, you are not only returning the address to a local variabel, but also with a type that is not compatible with the return type of the function.
This is one of many probable issues that your code may have, but you need to start fixing that to continue with other possible problems.
Note: enable extra warnings when compiler and listen to them, don't try to fool the compiler unless you know exactly what you're doing.

qsort works incorrectly (compare function)

I write program which sort numbers like 23.44 12.4223. And almost everything works fine but it does not sort correctly numbers for instance 24.321 and 24.33 i mean for my rpgoram 24.321 is greater than 24.33
Infile contains numbers like 34.5 123.55. 56. .43 564.3
Here's my code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define NUMBER_CHUNK 13
char* getNumber(FILE* fp)
{
int length;
int current = 0;
int c;
char *number, *number2;
number = (char*)malloc(sizeof(char)*NUMBER_CHUNK);
if(!number)
{
printf("Error while allocating memory!\n");
return NULL;
}
length = NUMBER_CHUNK;
while(!isspace(c = fgetc(fp)) && !feof(fp))
{
if(isdigit(c) || c == '.')
{
number[current] = c;
current++;
if(current >= length)
{
length+=NUMBER_CHUNK;
number2 = (char*)realloc(number,sizeof(char*)*length);
if(number2 == NULL)
{
free(number2);
return NULL;
}
else number2 = number;
}
}
else
{
return NULL;
}
}
number[current] = '\0';
return number;
}
int compare(const void *str1, const void *str2)
{
char* curr1;
char* curr2;
int value = 0;
size_t len1 = 0;
size_t len2 = 0;
curr1=*(char**)str1;
curr2=*(char**)str2;
while(*curr1=='0' || *curr1=='.') curr1++;
while(*curr2=='0' || *curr2=='.') curr2++;
while(*curr1 || *curr2)
{
while(*curr1 == '.')
curr1++;
while(*curr2 == '.')
curr2++;
if(value == 0)
{
value = *curr1 - *curr2;
}
if(*curr1)
{
curr1++;
len1++;
}
if(*curr2)
{
curr2++;
len2++;
}
}
if(len1 != len2)
{
return (len1 > len2) ? 1 : -1;
}
return value;
}
int main(int argc, char** argv)
{
FILE* fp;
char** tab;
int i = 0;
int lines = 0;
int length = 10;
if(argc != 2)
{
printf("Incorrent syntax! Use ./program_name input_file\n");
return 1;
}
if(!(fp = fopen(argv[1],"r")))
{
printf("Could not open the file! Please try again!\n");
return 2;
}
tab = (char**)malloc(length*(sizeof(char*)));
if(!tab)
{
printf("Could not allocate memory!\n");
free(tab);
return 3;
}
while(!feof(fp))
{
tab[i] = getNumber(fp);
if(i >= length)
{
length += 10;
tab = (char**)realloc(tab,sizeof(char*));
if(tab == NULL)
{
free(tab);
return 5;
}
}
if(tab[i] == NULL)
{
printf("Incorrect character in the infile! Terminating\n");
free(tab);
return 4;
}
if(*tab[i] == '\0')
{
free(tab[i]);
i--;
}
i++;
lines = i;
}
printf("\nBEFORE\n");
for(i = 0 ; i < lines; i++)
{
printf("%s\n", tab[i]);
}
qsort(tab, lines, sizeof(char*), compare);
printf("\nAFTER\n");
for(i = 0; i < lines; i++)
{
printf("%s\n",tab[i]);
free(tab[i]);
}
printf("\n");
free(tab);
fclose(fp);
return 0;
}
In your program 24.321 is greater than 24.33 because length of 24.321 is greater than length of 24.33.
You should stop increasing length when you read ..
Fix:
//UPDATE
while(*curr1=='0') curr1++;
while(*curr2=='0') curr2++;
//END OF UPDATE
char dot1 = 0, dot2 = 0;
char err1 = 0, err2 = 0;
while(*curr1 || *curr2)
{
if(*curr1 == '.') ++dot1; //UPDATE2
if(*curr2 == '.') ++dot2; //UPDATE2
while(*curr1 == '.')
curr1++;
while(*curr2 == '.')
curr2++;
if(value == 0)
{
value = *curr1 - *curr2;
}
if(*curr1)
{
if(*curr1 < '0' || *curr1 > '9') err1 = 1;
curr1++;
if(!dot1) len1++;
}
if(*curr2)
{
if(*curr2 < '0' || *curr2 > '9') err2 = 1;
curr2++;
if(!dot2) len2++;
}
}
if(err1 || err2 || dot1 > 1 || dot2 > 1) exit(1); // UPDATE2
UPDATE:
I updated code. Now before main comparison while only zeros are skipped. Dots will be skipped at the beginning of main while and fix with dot1 and dot2 will work.
UPDATE2:
To check if numbers are correct you should count dots and check if all chars are dots or digits.
Be aware that for longer bad numbers (more than 255 dots) my code could not work correctly (because dot1 is 1 byte long). If you need to handle these cases you should check if dot1/dot2 are equal to 1 and change err1/err2 to 1 instead of increasing dot1/dot2.
Your problem is here:---
if(len1 != len2)
{
return (len1 > len2) ? 1 : -1;
}
For strings "24.321" len1 = 6 ,"24.33" len2 = 5 so the longest string wins.
I thing your algorithm will also encounter problems with 123.45 vs 23.456 as you are basically ignoring the decimal point.
You could try converting to floating point (use function atof() or strtof() ) to convert the string to a real real number then compare.
Or simply return "less than" if you encounter a '.' in the first string before you encounter it in the second string.

Resources