I'm trying to sort some random points and the distance of the points from a user input point (consider it to be (0,0) i.e. the origin) on an XY coordinate system in a sort function by using pointers, when I remove the points sorting code from the sort function then distance sorting is fine, but when I try to sort the points as well as the distance the code doesn't work. I know a similar question about sorting points has been asked but I know the logic I want to implement it using pointers only. Could someone help?
Code
#include <stdio.h>
#include <math.h>
struct point {
float x, y;
};
void sort();
int main() {
int n;
printf("Enter the number of points in the system:");
scanf("%d", &n);
float d[n], xi, yi;
struct point p[n];
printf("\nEnter the X and Y coordinates of the points-\n");
for (int i = 0; i < n; i++) {
printf("Enter the X coordinate of point %d: ", i + 1);
scanf("%f", &p[i].x);
printf("Enter the Y coordinate of point %d: ", i + 1);
scanf("%f", &p[i].y);
}
printf("\nPoints entered are-\n");
for (int i = 0; i < n; i++) {
printf("%d- (%0.2f,%0.2f)\n", i + 1, p[i].x, p[i].y);
}
printf("\nEnter the X coordinate of point from which distance is to be calculated:");
scanf("%f", &xi);
printf("Enter the Y coordinate of point from which distance is to be calculated:");
scanf("%f", &yi);
for (int i = 0; i < n; i++) {
d[i] = fabs(sqrt(pow(((p[i].x) - xi), 2) + pow(((p[i].y) - yi), 2)));
}
printf("\nDistance- ");
for (int i = 0; i < n; i++) {
printf("%0.2f ", d[i]);
}
printf("\n");
sort(d);
printf("\n\nSorted distance- ");
for (int i = 0; i < n; i++) {
printf("%0.2f ", d[i]);
}
printf("\n\n");
for (int i = 0; i < n; i++) {
printf("%d- (%0.2f,%0.2f)\n", i + 1, p[i].x, p[i].y);
}
}
void sort(float *d, struct point *p) {
for (int i = 0; i < sizeof(d) / sizeof(float); i++) {
for (int j = 1; j < (sizeof(d) / sizeof(float)) - i; j++) {
if (*(d + i) > *(d + i + j)) {
float temp = *(d + i), pxtemp = (p + i)->x, pytemp = (p + i)->y;
*(d + i) = *(d + i + j);
*(d + i + j) = temp;
/*(p + i)->x = (p + i + j)->x;
(p + i + j)->x = pxtemp;
(p + i)->y = (p + i + j)->y;
(p + i + j)->y = pytemp;*/
}
}
}
}
Output
Enter the number of points in the system:2
Enter the X and Y coordinates of the points-
Enter the X coordinate of point 1: 5
Enter the Y coordinate of point 1: 6
Enter the X coordinate of point 2: 3
Enter the Y coordinate of point 2: 4
Points entered are-
1- (5.00,6.00)
2- (3.00,4.00)
Enter the X coordinate of point from which distance is to be calculated:0
Enter the Y coordinate of point from which distance is to be calculated:0
Distance- 7.81 5.00
There are multiple problems in the code:
you do not pass p to the sort function.
in this sort function, sizeof(d) / sizeof(float) does not evaluate to the number of entries in the array pointed to by d because d is just a pointer. You must pass the length of the arrays n as an extra argument.
#include <math.h>
#include <stdio.h>
struct point {
float x, y;
};
void sort(float *d, struct point *p, int n) {
for (int i = 1; i < n; i++) {
for (int j = 0; j < n - i; j++) {
if (d[i] > d[i + 1]) {
float temp = d[i];
d[i] = d[i + 1];
d[i + 1] = temp;
struct point temp1 = p[i];
p[i] = p[i + 1];
p[i + 1] = temp1;
}
}
}
}
int main() {
int n;
printf("Enter the number of points in the system:");
if (scanf("%d", &n) != 1 || n < 1)
return 1;
float d[n], xi, yi;
struct point p[n];
printf("\nEnter the X and Y coordinates of the points-\n");
for (int i = 0; i < n; i++) {
printf("Enter the X coordinate of point %d: ", i + 1);
if (scanf("%f", &p[i].x) != 1)
return 1;
printf("Enter the Y coordinate of point %d: ", i + 1);
if (scanf("%f", &p[i].y) != 1)
return 1;
}
printf("\nPoints entered are-\n");
for (int i = 0; i < n; i++) {
printf("%d- (%0.2f,%0.2f)\n", i + 1, p[i].x, p[i].y);
}
printf("\nEnter the X coordinate of point from which distance is to be calculated:");
if (scanf("%f", &xi) != 1)
return 1;
printf("Enter the Y coordinate of point from which distance is to be calculated:");
if (scanf("%f", &yi) != 1)
return 1;
for (int i = 0; i < n; i++) {
// use hypot() to compute the distance between 2 points
// it has better behavior than sqrt(dx2 + dy2) in corner cases.
d[i] = hypot(p[i].x - xi, p[i].y - yi);
}
printf("\n");
printf("Distance- ");
for (int i = 0; i < n; i++) {
printf("%0.2f ", d[i]);
}
printf("\n");
sort(d, p, n);
printf("\n\nSorted distance- ");
for (int i = 0; i < n; i++) {
printf("%0.2f ", d[i]);
}
printf("\n\n");
for (int i = 0; i < n; i++) {
printf("%d- (%0.2f,%0.2f)\n", i + 1, p[i].x, p[i].y);
}
return 0;
}
Declare your function with all input parameters:
void sort(float *d,struct point *p);
And use both parameters when you call it:
sort(d, p);
Afterwards it seems to work fine, test here.
Also, as Konrad Rudolph correctly pointed out, you need to pass the length of your array to the function, to use the correct length on your for-loops. They are also better readable afterwards.
void sort(float *d, struct point *p, int n);
and
for(int i=0; i<n; i++)
{
for(int j=1; j<n-i; j++)
"Could someone help?"
Why do you have, and try to maintain, two "parallel" arrays?
One for x,y and one for a calculated distance.
Then try to keep their elements together when sorting and printing.
struct point {
float x, y;
float d;
};
Wouldn't that solve a lot of your problems?
You might even be able to pass the array full of these things to the standard library function qsort() to have it do the heavy lifting. (You'd have to comment out or remove your own sort() function, of course.)
Why make life harder than it already is?
EDIT:
Here are some fragments of code (and pseudocode) that you might find useful.
typedef struct {
float x, y; // rect co-ord's
float d; // calc'd distance from user co-ord
} xyd_t; // x,y and distance type
int cmpDist( const void *a1, const void *a2 ) { return ((xyd_t*)a)->d - ((xyd_t*)b)->d; }
xyd_t arr[ 20 ]; // 20 only as example
memset( arr, 0, sizeof arr ); // initialise all to zero
for( int i = 0; i < n; i++ ) {
arr[ i ].x = /* value */
arr[ i ].y = /* value */
}
xyd_t user = { 37.5, 53.2, /* don't care */ };
calcDist( user, arr );
qsort( arr, n, sizeof arr[0], cmpDist );
for( int i = 0; i < n; i++ )
print i, arr[i].d; // distance
EDIT2:
It's bothersome that some SO answers are accepted even though they are flawed, while others are pretty much overlooked for whatever reason.
I've implemented the recommendations above and extended the OP code somewhat (as a toy project). Here, one 'reference point' is "entered" followed by 4 other x,y coordinates. These are set up in the source to avoid the hassle of re-typing or arcane input redirections. Easy to revert to a user interface.
Additions to the code extend its capability. Most importantly, the main body is abbreviated, a reliable sort routine is used, and... well... just some plain fun with 'bearings' from the reference point. It's a "code dump" because learning comes from figuring things out for oneself. This code points the way. (Thank you to #Chqrlie for some better trig math.)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define tau 6.283185307179586476925286766559
typedef struct { double x, y, m; int a; } xyd_t;
int nrml( int deg ) {
while( deg < 0 ) deg += 360;
while( deg >= 360 ) deg -= 360;
return deg;
}
char *compassRose( int deg, char *buf ) {
char *pts =
"N\0\0\0\0NNNE\0NNE\0\0ENNE\0NE\0\0\0NENE\0ENE\0\0EENE\0"
"E\0\0\0\0EESE\0ESE\0\0SESE\0SE\0\0\0ESSE\0SSE\0\0SSSE\0"
"S\0\0\0\0SSSW\0SSW\0\0WSSW\0SW\0\0\0WWSW\0WSW\0\0WWSW\0"
"W\0\0\0\0WWNW\0WNW\0\0NWNW\0NW\0\0\0WNNW\0NNW\0\0NNNW\0"
"N\0\0\0\0";
int ind = int( (nrml( deg ) + (360.0/32.0)/2.0)*(32.0/360.0) );
return (char*)memcpy( buf, pts + ind*5, 5 );
}
int nearToFar( const void *a1, const void *a2 ) { return ((xyd_t*)a1)->m > ((xyd_t*)a2)->m; }
int farToNear( const void *a1, const void *a2 ) { return ((xyd_t*)a2)->m > ((xyd_t*)a1)->m; }
int ccw( const void *a1, const void *a2 ) { return nrml(((xyd_t*)a2)->a) > nrml(((xyd_t*)a1)->a); }
void show( char *title, xyd_t *p, int n ) {
char buf[ 4 + 1 ];
puts( title );
for( int i = 0; i < n; i++, p++ )
printf( "(%0.2lf,%0.2lf) %0.2lf # %d deg %s\n", p->x, p->y, p->m, p->a, compassRose(p->a, buf) );
}
void main() {
int i, n;
// printf( "Number of points including ref point: " );
// scanf( "%d", &n );
/* omitting test for success */
// xyd_t pt[ n ];
n = 5;
xyd_t pt[ 1 + 4 ] = {
{ 12, 12, },
{ 15, 15, },
{ 7, 17, },
{ 6, 6, },
{ 16, 8, },
};
puts( "\nX and Y coordinates of the points, Ref Pt first-" );
for( i = 0; i < n; i++ ) {
printf( "\n#%d - X (space) Y coordinates: ", i );
// scanf( "%lf%lf", &pt[i].x, &pt[i].y );
/* omitting test for success */
if( i ) {
double deltaX = pt[i].x - pt[0].x;
double deltaY = pt[i].y - pt[0].y;
pt[i].m = hypot( deltaX, deltaY );
pt[i].a = (int)(atan2( deltaX, deltaY )*360/tau)%360;
}
}
show( "\n As entered:", pt, n );
qsort( pt, n, sizeof xyd_t, nearToFar );
show( "\n Sorted near to far:", pt, n );
qsort( pt, n, sizeof xyd_t, farToNear );
show( "\n Sorted far to near:", pt, n );
qsort( pt, n, sizeof xyd_t, ccw );
show( "\n Sorted counter-clockwise from North:", pt, n );
}
X and Y coordinates of the points, Ref Pt first-
#0 - X (space) Y coordinates: // prompts appear, but input data hardwired
#1 - X (space) Y coordinates:
#2 - X (space) Y coordinates:
#3 - X (space) Y coordinates:
#4 - X (space) Y coordinates:
As entered:
(12.00,12.00) 0.00 # 0 deg N
(15.00,15.00) 4.24 # 45 deg NE
(7.00,17.00) 7.07 # -45 deg NW
(6.00,6.00) 8.49 # -135 deg SW
(16.00,8.00) 5.66 # 135 deg SE
Sorted near to far:
(12.00,12.00) 0.00 # 0 deg N
(15.00,15.00) 4.24 # 45 deg NE
(16.00,8.00) 5.66 # 135 deg SE
(7.00,17.00) 7.07 # -45 deg NW
(6.00,6.00) 8.49 # -135 deg SW
Sorted far to near:
(6.00,6.00) 8.49 # -135 deg SW
(7.00,17.00) 7.07 # -45 deg NW
(16.00,8.00) 5.66 # 135 deg SE
(15.00,15.00) 4.24 # 45 deg NE
(12.00,12.00) 0.00 # 0 deg N
Sorted counter-clockwise from North:
(7.00,17.00) 7.07 # -45 deg NW
(6.00,6.00) 8.49 # -135 deg SW
(16.00,8.00) 5.66 # 135 deg SE
(15.00,15.00) 4.24 # 45 deg NE
(12.00,12.00) 0.00 # 0 deg N
In line 10 I cannot find out where my problem is at first. I place int a[100][100]={0} but the cpu speed is stuck.
Then, I try to change it into a[n][n] but no output is shown.
Last, I try to change it again as if it resembles the original ones.
However, nothing works instead of a new question.
#include<stdio.h>
int main() {
int n;
while (scanf("%d", &n)) {
n *= 2;
int x = 0, y = 0, num = 1;
int a[n][n] = {0};
a[x][y] = num++;
while (n * n >= num) //定義陣列
{
while (y + 1 < n && !a[x][y + 1]) //向右
a[x][++y] = num++;
while (x + 1 < n && !a[x + 1][y]) //向下
a[++x][y] = num++;
while (y - 1 >= 0 && !a[x][y - 1]) //向左
a[x][--y] = num++;
while (x - 1 >= 0 && !a[x - 1][y]) //向上
a[--x][y] = num++;
}
for (x = 0; x < n; x++) //print 陣列
{
for (y = 0; y < n; y++) {
if (y != n - 1) {
printf("%d ", a[x][y]);
} else {
printf("%d", a[x][y]);
}
}
printf("\n");
}
break;
}
return 0;
}
At least this problem:
Variable Length Arrays (VLA) cannot be initialized via the C standard.
Alternate, assign via memset() after defining a.
// int a[n][n]={0};
int a[n][n];
memset(a, 0, sizeof a);
I want to make an input system that will allow the user to choose a number and it will return the position of choice.
for example:
| 0 1 2
--+----------
0 | 1 2 3
1 | 4 5 6
2 | 7 8 9
in this matrix, if the user input is 5 it should return the position {1, 1} and if the input is 8 it should return {2, 1}.
I wrote a piece of code to try and do that but it doesn't work well for every scenario:
here is the code I wrote in C language:
VectorPos RequestInput(char arr[][3])
{
char input;
int converted;
VectorPos loc;
while (1)
{
printf("Enter number between 1-9: ");
scanf(" %c", &input);
if (input < '1' || input > '9')
printf("Invalid board Location.\n\n");
else
break;
}
converted = atoi(&input);
int count = 1;
int i, k;
i = k = 0;
for (k = 0; k < 3 && count++ < converted; k++)
{
for (i = 0; i < 3 && count++ < converted; i++);
}
loc.col = k;
loc.row = i;
return loc;
}
*VectorPos is just a struct to return a row and col in one variable.
I would like to ask if you know of any good more effective way of doing this.
thanks:)
For a rectangular grid like that, all you need is division and modulo:
// pos = position in grid from 1..
// w = grid width
// x = output x variable (range 0..w-1)
// y = output y variable (range 0..infinity)
// usage: pos_to_xy(4, 3, &x, &y);
void pos_to_xy(int pos, int w, int *x, int *y) {
pos -= 1; // Bring range 1.. to 0..
*y = pos / w;
*x = pos % w;
}
Example:
int main() {
for(int i = 1; i <= 9; i++) {
int x, y;
pos_to_xy(i, 3, &x, &y);
printf("%d: (x %d, y %d)\n", i, x, y);
}
return 0;
}
Output:
1: (x 0, y 0)
2: (x 1, y 0)
3: (x 2, y 0)
4: (x 0, y 1)
5: (x 1, y 1)
6: (x 2, y 1)
7: (x 0, y 2)
8: (x 1, y 2)
9: (x 2, y 2)
What I am trying to do in the code below is to to make the input a four-digit number (if it's not already) and then sort the digits in the number in an ascending and descending order. x is ascending, y is descending. Then I want to subtract x and y until I get the result 6174 of the subtraction.
#include <stdio.h>
int main() {
int number, count = 0, digit, pow = 0, result = 1, counter, temp,
x = 0, y = 0, i, j, substract = 0, count1 = 0;
scanf("%d", &number);
while (substract != 6174 && substract >= 0) {
substract = 0;
if (count1 > 0) {
temp = substract;
} else {
temp = number;
}
while (temp > 0) {
digit = temp % 10;
temp = temp / 10;
count++;
}
if (count < 4) {
pow = 4 - count;
/* Calculate base^exponent */
for (counter = 0; counter < pow; counter++) {
result = result * 10;
}
number = number * result;
}
for (i = 9, j = 0; i >= 0 && j <= 9; i--, j++) {
int tmpNumber = number;
while (tmpNumber > 0) {
int digit = tmpNumber % 10;
if (digit == i) {
x *= 10;
x += digit;
} else
if (digit == j) {
y *= 10;
y += digit;
}
tmpNumber /= 10;
}
}
substract = x - y;
count++;
printf("\n x %d", x);
printf("\n y %d", y);
printf("\n substract %d", x - y);
}
return 0;
}
When I input 3542 What I expect as an output is this
input:
3524
output:
x 5432
y 2345
subtract 3087
x 8730
y 0378
subtract 8352
x 8532
y 2358
subtract 6174
But what I get is actually this:
input:
3524
output:
x 5432
y 2345
subtract 3087
x 54325432
y 23452345
subtract 30873087
I think the problem is something with the x and y. I have to reset them to zero at some point. But I don't know where. I've tried every single place in the code. If anyone knows where I do wrong I will really appreciate the help.
The program fails for multiple reasons:
You do not reset x and y to 0 for each iteration
result should also be reset to 1
The initial phase of the loop is too complicated: you should test if substract is 0 or 6174 to stop the loop and store substract to number at the end of the loop.
Here is a simpler version that does not need to make number have 4 digits:
#include <stdio.h>
int main(void) {
int number;
if (scanf("%d", &number) == 1 && number >= 0 && number < 10000) {
for (;;) {
int x = 0, y = 0, substract;
for (int i = 9, j = 0; i >= 0 && j <= 9; i--, j++) {
for (int tmp = number, n = 0; n < 4; n++) {
int digit = tmp % 10;
if (digit == i) {
x *= 10;
x += digit;
} else
if (digit == j) {
y *= 10;
y += digit;
}
tmp /= 10;
}
}
substract = x - y;
printf("x %d\n", x);
printf("y %d\n", y);
printf("substract %d\n", substract);
if (substract == 0 || substract == 6174)
break;
number = substract;
}
}
return 0;
}
I'm trying to pass a recursive function that populates my 2D array of structs. My memory allocation is working fine, but when I try to do a recursion, I get the error: Segmentation fault (core dumped).
Any idea why this must be happening? I think I wrote my code so that no index out of bound occurs. I still don't know why this is happening. Any help is going to be appreciated. Thanks!
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
typedef struct {
char val;
bool filled;
} elements;
void assign(elements ** elements, int row, int column, int x, int y, int limit);
int main(int argc, char** argv)
{
int row = 0;
int column = 0;
int x = 0;
int y = 0;
int limit = 0;
sscanf(argv[1], "%d", &row);
sscanf(argv[2], "%d", &column);
sscanf(argv[3], "%d", &x);
sscanf(argv[4], "%d", &y);
sscanf(argv[5], "%d", &limit);
elements **foo;
foo = (elements **)malloc(sizeof(elements *) * row);
for (int i = 0; i < column; i++)
foo[i] = (elements *)malloc( sizeof(elements) * row);
foo[y][x].val = 'C';
// printf("%c\n", foo[y][x].val);
assign(foo, row, column, x, y, limit);
for(int i = 0; i < row; i++)
{
for(int j = 0; j < column; j++)
{
// foo[i][j].val = '.';
printf("%d\t ", foo[i][j].filled);
}
printf("\n");
}
}
void assign(elements ** elements, int row, int column, int x, int y, int limit)
{
int tempX = x;
int tempY = y;
if(elements[y][x].filled != 0 )
{
//printf("reached.");
return;
}
else if(limit < 0)
{
//printf("reached.");
return;
}
else
{
if(elements[y][x].val != 'C')
elements[y][x].val = limit + '0';
elements[y][x].filled = true;
tempX = x - 1;
tempY = y;
if (!( x < 0 || y < 0 || x > column - 1 || y > row -1 ))
assign(elements, row, column, tempX, tempY, limit - 1); // go up
tempX = x;
tempY = y + 1;
if (!( x < 0 || y < 0 || x > column - 1 || y > row -1 ))
assign(elements, row, column, tempX, tempY, limit - 1); // go right
tempX = x + 1;
tempY = y;
if (!( x < 0 || y < 0 || x > column - 1 || y > row -1 ))
assign(elements, row, column, tempX, tempY, limit - 1); // go down
tempX = x;
tempY = y - 1;
if (!( x < 0 || y < 0 || x > column - 1 || y > row -1 ))
assign(elements, row, column, tempX, tempY, limit - 1); // go left
}
}
each of the if() code blocks in the last half of assign() are beginning with the same basic parameter values, except the limit changes.
so the total number of recursions (which the code seems to be limiting the the value in 'limit' is not actually limited,
because when limit is 0, it is not necessarily the last call to be made to assign() and once limit is <0 the code will recurse about 16 gig more times. (at least) This is probably why the program crashes
Suggest decrementing limit within assign() before any of the recursive calls to assign()