I'm trying to plot coordinates to a map using a 2d Array. The data for the coordinates has been entered by the user and held in a structure. This is a snippet of code taken out of my main program.
#include <stdio.h>
#include <stdlib.h>
char map[5][10]={
"..........",
"..........",
"..........",
"..........",
".........."
};
struct coord{
int x;
int y;
};
int loop, n, i;
struct coord mg[3];
int main(){
for(loop=0;loop<3;loop++){
printf("\n\nEnter MAGENTA X coordinate 0:\n");
scanf("%d",&mg[loop].x);
printf("\nEnter MAGENTA Y coordinate:\n");
scanf("%d",&mg[loop].y);
}
printf("Struct contains:\n");
for(loop=0;loop<3;loop++){
printf("\tx %d,%d y\n",mg[loop].x,mg[loop].y);
}
/*AS SUGGESTED IN ANSWER BELOW (PAUL92),I HAVE DONE THIS BUT GET AN ERROR*/
n=3;
i=0;
for (i = 0; i < n; i++) {
map[mg.y][mg.x] = 'x';
}
getchar();
return(0);
}
The error I get is
testing.c:35:13: error: member reference base type 'struct coord [3]' is not a
structure or union map[mg.y][mg.x] = 'x';
~~^~
What I'm trying to achieve is getting the coordinates held in struct to then be assigned to the correct element in the array i.e. if the user enters 3(x),5(y) then the element map[4][2] will hold this an display and 'x'.
I am not sure I have understood exactly what you want, but if you want just to mark the points on the map with an 'x' for example, you can to iterate over the points:
for (int i = 0; i < n; i++) {
map[mg.y][mg.x] = 'x';
}
where n is the number of points.
Of course, this is after you initialize the map.
Related
I am new to programming in C so I have started making a simple project. I am having an issue with the below code, which seems to be something related to the way memory is managed in C but I'm not sure.
I have a 1280x720 array of Particles which I fill with zeros and with "none". Then I fill in a single entry at (1,1). Finally I print out all the 'particles' that are not "none". The strange behaviour comes from the fact that when I do this I get an output of:
721 0 sand 1 1 sand
Clearly the second value should be there, but the first should not. I have tried with different values of x,y and it always adds 720 to x, and subtracts 1 from y.
#include <stdio.h>
#include <string.h>
typedef struct {
char name[10];
int colour;
} Particle;
Particle particles[1280][720];
void main() {
//Fill in the 1280 x 720 array with 0's and None
for (int y=0; y<720; y++) {
for (int x=0; x<1280; x++) {
particles[y][x].colour = 0x000000;
strcpy(particles[y][x].name, "none");
}
}
//Copy in 1 pixel of sand
strcpy(particles[1][1].name, "sand");
particles[1][1].colour = 0xFFFF00;
//Print out all the pixels that are not none, which should
//just print out a single pixel at (1,1)
for (int y=0; y<720; y++) {
for (int x=0; x<1280; x++) {
if (strcmp("none",particles[y][x].name) != 0) {
printf("%d %d %s\n",x,y,particles[y][x].name);
}
}
}
}
Sorry if this is a simple question. Thanks in advance.
Each rows of the array particles have only 720 elements, so particles[y][x] is out-of-range when x >= 720. Accessing out-of-range element invokes undefined behavior.
Quote from N1570 J.2 Undefined behavior:
An array subscript is out of range, even if an object is apparently accessible with the
given subscript (as in the lvalue expression a[1][7] given the declaration int
a[4][5]) (6.5.6).
Allocate enough elements to avoid buffer overrun. It seems you should use
Particle particles[720][1280];
instead of
Particle particles[1280][720];
It is better to define the width and height as macro to avoid typo:
#include <stdio.h>
#include <string.h>
#define WIDTH 1280
#define HEIGHT 720
typedef struct {
char name[10];
int colour;
} Particle;
Particle particles[HEIGHT][WIDTH];
void main() {
//Fill in the WIDTH x HEIGHT array with 0's and None
for (int y=0; y<HEIGHT; y++) {
for (int x=0; x<WIDTH; x++) {
particles[y][x].colour = 0x000000;
strcpy(particles[y][x].name, "none");
}
}
//Copy in 1 pixel of sand
strcpy(particles[1][1].name, "sand");
particles[1][1].colour = 0xFFFF00;
//Print out all the pixels that are not none, which should
//just print out a single pixel at (1,1)
for (int y=0; y<HEIGHT; y++) {
for (int x=0; x<WIDTH; x++) {
if (strcmp("none",particles[y][x].name) != 0) {
printf("%d %d %s\n",x,y,particles[y][x].name);
}
}
}
}
I have a few problems with the following assignments:
a)
Define a new data type tpos for storing the position of a solid in the two dimensional plane in
single precision. Afterwards define another new data type tsolid that can store the weight of
a solid in double precision and its position in the two dimensional plane. Use tpos for defining
the position component of tsolid.
b)
Define an array of length two of type tsolid. The positions and weights of both solids (array
elements) shall now be read from the keyboard by using the scanf function. For checking
correctness of your program, display the array content on the screen.
So far i have:
#include <stdio.h>
#include <stdlib.h>
struct tpos
{
float xy
};
struct tsolid
{
struct tpos;
double m;
};
int main()
{
struct tsolid array[2];
return 0;
}
How do I Proceed now? Already tried a few things, but sadly they didnt work out. The text basically says i have to save 1 solid in 1 array element, right? But how can i save pos x , pos y, and the weight m all in 1 array element and then print them all at the same time? Do i have to use a pointer ?
First of all, if you need to store "two dimensional plane", you should use two elements inside struct.
Other thing is that you don't access struct elements by saying struct tpos; - you should use tpos xy.
Repaired code:
#include <stdio.h>
#include <stdlib.h>
struct tpos
{
float x;
float y;
};
struct tsolid
{
tpos xy;
double m;
};
int main()
{
tsolid array[2];
return 0;
}
When it comes to scanf and displaying content you need to decide yourself on the "output layout".
And you access certain parts of the "element" by using
array[i].m;
array[i].xy.x;
array[i].xy.y;
tpos needs two members, one for the each coordinate.
tsolid needs a name for the tpos member.
Then write a loop that asks for each value, puts them in the array, and another loop that prints the values from the array.
#include <stdio.h>
struct tpos
{
float x, y;
};
struct tsolid
{
struct tpos position;
double mass;
};
int main()
{
struct tsolid array[2];
for (int i = 0; i < 2; i++) {
printf("Enter x, y, and mass for object %d:\n", i+1);
scanf("%f %f %lf", &array[i].position.x, &array[i].position.y, &array[i].mass);
}
printf("You entered:\n");
for (int i = 0; i < 2; i++) {
scanf("x = %f, y = %f mass = %lf\n", array[i].position.x, array[i].position.y, array[i].mass);
}
return 0;
}
I have two identical arrays of struct , one in reverse order.
The problem is that i don't want duplicate the same data into the two arrays , i would a reversed array with elements pointing elements of the first array in a way that i can edit the members of struct of first array or from the reversed array taking effect in both.
you can view the source and run it online here https://onlinegdb.com/SJbepdWxS
#include <stdio.h>
typedef struct point{
int id;
float x,y,z;
} point;
void printPoints(point *pts,int len){
int i = 0;
while (pts !=NULL && i < len){
printf("id %d x %f y%f z %f\n",pts->id,pts->x,pts->y,pts->z);
pts++;
i++;
}
}
void translatePoints(point *pts,int len,float t){
int i = 0;
while (pts !=NULL && i < len){
pts->x = pts->x + t;
pts->y = pts->y + t;
pts->z = pts->z + t;
pts++;
i++;
}
}
void reversePoints(point *pts, int len, point *rev){
int i = 0;
int j = len;
while (i < len){
j=len-i-1;
rev[j]=pts[i];
i++;
}
}
int main()
{
int i;
int t1=200;
int t2=300;
int len=3;
point points[len];
point rev_points[len];
for(i=0; i<len ; i++){
points[i].id=i;
points[i].x=10+i;
points[i].y=20+i;
points[i].z=30+i;
}
//point * pts = points;
printf("\nprint points \n\n");
printPoints(points,len);
printf("\ntranslate points %d...\n\n",t1);
translatePoints(points,len,t1);
printf("\nprint points\n\n");
printf("\nreverse points to rev_points\n");
reversePoints(points,len,rev_points);
printf("\nprint rev_points \n\n");
printPoints(rev_points,len);
printf("\ntranslate rev_points %d...\n\n",t2);
translatePoints(rev_points,len,t2);
printf("\nprint rev_points\n\n");
printPoints(rev_points,len);
printf("\nprint points\n\n");
printPoints(points,len);
return 0;
}
I expect that struct values of both arrays change when i change value in one of the two array.
But changing values of struct in the first array , the second array not changes and the other way around.
One way to look at this is a set of points and two permutations on the set. This sets up a points array, which is used as a set, and forward_points and reverse_points as arrays of pointers to the point array that we are going to use as permutations.
#include <stdio.h>
struct Point {
int id;
float x,y,z;
};
/* Print a point. */
static void printPoint(struct Point *point) {
printf("id %d x %f y%f z %f\n",point->id,point->x,point->y,point->z);
}
/* These print out an array of pointers to point. */
static void printPointsRef(struct Point **ref, int len) {
struct Point **end = ref + len;
while(ref < end) printPoint(*(ref++));
}
/* This translates all the `pts` up to `len` by `(1,1,1)*t`. */
static void translatePoints(struct Point *pts, int len, float t) {
struct Point *end = pts + len;
while(pts < end) {
pts->x = pts->x + t;
pts->y = pts->y + t;
pts->z = pts->z + t;
pts++;
}
}
/* Helper function to `main`. */
static void printPoints(struct Point **forward_points,
struct Point **reverse_points, int len) {
printf("print points\nprint points forward:\n");
printPointsRef(forward_points,len);
printf("print points reverse:\n");
printPointsRef(reverse_points,len);
printf("\n");
}
int main(void)
{
const int len = 3;
/* This is the actual points structure. */
struct Point points[len];
/* These are arrays of pointers to points; they are
permutations of `points`. */
struct Point *forward_points[len], *reverse_points[len];
int i;
const int t1=200;
for(i=0; i<len; i++) {
/* Initialise element `i` of `points`. */
points[i].id=i;
points[i].x=10+i;
points[i].y=20+i;
points[i].z=30+i;
/* Initialise element `i` of `forward_points`
to point to `points[i]`, and `backward_points`
to point the other way (it doesn't matter that
the backwards points are uninitialised, they
will be.) */
forward_points[i] = &points[i];
reverse_points[i] = &points[len - 1 - i];
}
printPoints(forward_points, reverse_points, len);
/* Translation is a vector space operation and doesn't
care about order; we just do it on the original points. */
printf("translate points %d...\n\n",t1);
translatePoints(points,len,t1);
printPoints(forward_points, reverse_points, len);
return 0;
}
Of course, there is no integrity constraints on the pointers; nothing stopping one from pointing at anything, null, the same elements, or anything else.
I added an other struct with one element that is a pointer
typedef struct ptr_point{
point * p;
} ptr_point;
I edited the function reversePoints
void reversePoints(point *pts, int len, ptr_point *rev){
// This function is used only to test pointers
int i = 0;
int j = len;
while (i < len){
j=len-i-1;
rev[j].p = &pts[i];
i++;
}
}
and added another function to print ptr_points
void printPtrPoints(ptr_point *pts,int len){
int i = 0;
while (i < len){
printf("id %d x %f y%f z %f\n",pts->p->id,pts->p->x,pts->p->y,pts->p->z);
pts++;
i++;
}
}
and declaring the second array as ptr_point array
ptr_point rev_points[len];
In conclusion : now data in the second array are not replicated but pointing to element structure of the first array.
The need to not replicate data arise in presence of millions of coordinate points that if replicate more than one time , sorting it for example by x, y, z and so on , occupe much memory with the difficulty of managing .
This fix however forces me to use structures->type in order to change the access mode to read or set values.
I don't know if this is the best solution but it has solved the problem for not duplicate the data.
you can run the source with fixes here: https://onlinegdb.com/SknP_i-eS
Thank you all for the advice.
I'm trying to print my struct. I want it to show:
id: BBB-188
brand: BMW
pic: 1 2 3.
Right now the result is this:
id: BBB-188
name: BMW
Segmentation fault: 11.
Does anyone know what is wrong with my code?
#define MAX 10000
#define IDSIZE 11
#define BRANDSIZE 50
#define PICSIZE 10
typedef struct{
char id[IDSIZE+1];
char brand[BRANDSIZE+1];
int *pic;
} Car;
void printCar(Car *pCar,int carcount, int imagecount) {
printf("id: %s \n",pCar->id);
printf("brand: %s \n",pCar->brand);
for(int i=0; i< imagecount; i++){
printf("pic: %d \n",pCar->pic[i]);
}
}
Car initCar(char itsId[],char itsBrand[],int itsPic, int imagecount){
Car newCar;
strcpy(newCar.id, itsId);
strcpy(newCar.brand, itsBrand);
for (int i = 0; i < imagecount; i++){
newCar.pic = itsPic;
}
return newCar;
}
int main(void){
int carcount=0;
int imagecount=0;
int test[3]={1,2,3};
Car myCar = initCar("BBB-188","BMW", test, 3 );
carcount=1;
imagecount=3;
printCar(&myCar,carcount,imagecount);
return 0;
}
The handling of pic is broken and very confusing.
You seem to want to represent it as an array of integers, but you don't store the length. Thus it has to be always three, but then you can just use an array in the structure, i.e.:
int pic[3];
instead of
int *pic;
Also the assignment inside initCar() makes no sense, you're looping but simply assigning the same integer value (!) to the pointer imagecount times, no data is being copied.
If you want the length of the picture array to really be variable, you must store the length and allocate memory for holding the numbers. So in initCar() you must have:
newCar.pic = malloc(imagecount * sizeof *newCar.pic);
memcpy(newCar.pic, itsPic, imagecount * sizeof *newCar.pic);
but then itsPic must of course be of type const int *.
You need to pass itsPic as a pointer in initCar. If you're doing so, you don't need the for loop for the affectation.
Car initCar(char itsId[],char itsBrand[],int* itsPic, int imagecount){
Car newCar;
strcpy(newCar.id, itsId);
strcpy(newCar.brand, itsBrand);
//for (int i = 0; i < imagecount; i++){
newCar.pic = itsPic;
//}
return newCar;
}
Below is a part of an algorithm i was given to use for a project, but as it's my first time to use an algorithm i don't understand the following lines. Please will need your help.
For i=1 to n do
t[i] .mark <-- 0
t[i] .num <-- -1
End
This pseudo code can be translated to C
Use struct
struct cm{
int mark;
int num;
};
#define N 10
int main(void)
{
struct cm t[N];
for (int i=0;i<N;i++){
t[i].mark = 0;
t[i].num = -1;
}
//print your struct elements field
for (int i=0;i<N;i++){
printf("%d: %d, %d\n",i ,t[i].mark, t[i].num);
}
}
We have an array of struct because of we need each element of it have two field of data (i.e. mark,num).
struct cm t[N]; define a N length array of structure cm.
In loop we assign to each field of array elements proper values.
For more readability you can use typedef instead of using struct to define your desire data structure in this case.
typedef vs struct
Use typedef
typedef struct typecm{
int mark;
int num;
}typecm;
#define N 10
int main(void)
{
typecm s[N];
for (int i=0;i<N;i++){
s[i].mark = 0;
s[i].num = -1;
}
//print values
for (int i=0;i<N;i++){
printf("%d: %d, %d\n",i ,s[i].mark, s[i].num);
}
}
The "t" seems to be an array of objects, and "mark" and "num" are properties of the object.
This may help you:
From an array of objects, extract value of a property as array