Home > Back-end >  How can I create multiple structs with different Strings using a Loop in C?
How can I create multiple structs with different Strings using a Loop in C?

Time:10-06

I'm doing an assignment where I have to create a program that has the user input coordinates and a name to create points. The program must find the points closest to each other and print out their names. I have the algorithm figured out, but I'm struggling to be able to print the names of the points themselves.

I have the points as a struct that takes a char array and I have a loop that iterates a user-specified amount that creates the points and puts them in a dynamic array. In that loop, I have variables for the coordinates and the name and use them to initialize the struct and I think that's where the problem lies. When I pass the string into the struct, I think I'm passing a reference to the pointer, so when the loop iterates and the variable changes, the name of previous points changes. I tried ways to go around this for hours, messing with pointers and strcopy, but it either doesn't compile or the result the names are all the same.

I'm sure I'm going about this wrong, so if I could have any insight to a better way of doing this I'd really appreciate it.

Here's the code

#include <stdio.h>
#include <float.h>
#include <string.h>
#include <stdlib.h>

typedef struct{
  float xCoor;
  float yCoor;
  char name[10];
} Point;

int main()
{
  int size = 0;

  printf("How many points?\n");
  scanf("%d", &size);

  //not enough points case
  if( size < 2){
    printf("Not enough points\n");
    return 1;
  }

  //create point arrays
  Point *points;
  points = malloc(size * sizeof(Point));

  //get each point
  for(int i = 0; i < size; i  ){
    float pointX;
    float pointY;
    char pointName[10];
    printf("Please provide point's x coordinate\n");
    scanf("%f", &pointX);
    printf("Please provide point's y coordinate\n");
    scanf("%f", &pointY);
    printf("Please provide point's name\n");
    scanf("%s", *pointName);
    Point point = {pointX, pointY, ""};
    //strncat(point.name, pointName, 10);
    //I don't know how to get names to work, so I'm giving up
    *point.name = *pointName;
    points[i] = point;
    
    
    printf("The point's name is %s\n", points[i].name);
    
  }

  float shortestDistance = FLT_MAX;
  char shortestPointName1[10];
  char shortestPointName2[10];
  int pointIndex1 = 0;
  int pointIndex2 = 0;

  //get shortest distance
   for (int i = 0; i < size; i  )
    {
      for(int j = i 1; j< size; j  )
        {
          float distance = (points[i].xCoor - points[j].xCoor) * (points[i].xCoor - points[j].xCoor)
              (points[i].yCoor - points[j].yCoor) * (points[i].yCoor - points[j].yCoor);

          if (distance < shortestDistance)
            {
              shortestDistance = distance;
              strcpy(shortestPointName1, points[i].name);
              strcpy(shortestPointName1, points[j].name);
              pointIndex1 = i;
              pointIndex2 = j;
            }
        }
    }

  printf("The two closest points are %s with index %d and %s with index %d\n",
    shortestPointName1, pointIndex1,  shortestPointName2, pointIndex2);
  return 0;
}

And for reference when I run it currently it looks like this

How many points?
2
Please provide point's x coordinate
0
Please provide point's y coordinate
0
Please provide point's name
bobby
The point's name is b
Please provide point's x coordinate
1
Please provide point's y coordinate
1
Please provide point's name
samantha
The point's name is s
The two closest points are s with index 0 and samantha with index 1

CodePudding user response:

Here is what you can do. Instead of getting a char array as input in the struct you can put a char *

typedef struct{
  float xCoor;
  float yCoor;
  char *name;
} Point;

Then, instead of storing the name input somewhere else just initialize name with malloc and directly pass it as a parameter to scanf.

float pointX;
float pointY;
points[i].name = malloc(sizeof(char)*10);

printf("Please provide point's x coordinate\n");
scanf("%f", &pointX);

printf("Please provide point's y coordinate\n");
scanf("%f", &pointY);

printf("Please provide point's name\n");
scanf("%s", points[i].name);

points[i].xCoor = pointX;
points[i].yCoor = pointY;
    
printf("The point's name is %s\n", points[i].name);

You can also do it with an array with the following code

typedef struct{
  float xCoor;
  float yCoor;
  char name[10];
} Point;

and

float pointX;
float pointY;

printf("Please provide point's x coordinate\n");
scanf("%f", &pointX);

printf("Please provide point's y coordinate\n");
scanf("%f", &pointY);

printf("Please provide point's name\n");
scanf("%s", points[i].name);

points[i].xCoor = pointX;
points[i].yCoor = pointY;
    
printf("The point's name is %s\n", points[i].name);

You can test this and confirm it works using the code:

printf("%s\n", points[0].name);
printf("%s\n", points[1].name);

This way you can print the names. Note that your code is also faulty at some other point about actually getting the closest points since it doesn't show the name if you run the code as is. That is why I put the testing code above.

Edit: Ok I found why your code isn't printing the second name when you run it without the test code. You duplicated this

if (distance < shortestDistance)
{
    shortestDistance = distance;
    strcpy(shortestPointName1, points[i].name);
    strcpy(shortestPointName1, points[j].name); // shortestPointName1 is duplicated
    pointIndex1 = i;
    pointIndex2 = j;
}

it should be:

if (distance < shortestDistance)
{
    shortestDistance = distance;
    strcpy(shortestPointName1, points[i].name);
    strcpy(shortestPointName2, points[j].name); // should be shortestPointName2
    pointIndex1 = i;
    pointIndex2 = j;
}
  • Related