使用 C 中的结构将数据存储到动态数组中
Storing data into a dynamic array with structs in C
我在将文件中的数据存储到我的动态数组时遇到问题。我知道我现在所拥有的是不正确的,但它只是暂时存在。我有一个文件,它的第一行基本上包含了数据行的数量。下面几行有两个并排的整数来表示一个有序对。我想将这两个整数存储到一个结构 point
中,它表示一个有序对。此外,还有一个数组,其结构位于另一个结构 list
内部,其中包含数组的大小,或当前存储在数组中的数据量以及容量,即总量数组中的 space 个。
我想将这两个整数存储到 int
类型的变量中,然后将它们存储到我的 list
结构中数组内的 point
中。
我对拥有两个结构感到非常困惑,并且不确定这是否是正确的方法。欢迎任何反馈。
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
typedef struct
{
int x;
int y;
} point;
typedef struct
{
int size;
int capacity;
point *A;
} list;
// Compute the polar angle in radians formed
// by the line segment that runs from p0 to p
double polarAngle(point p, point p0)
{
return atan2(p.y - p0.y, p.x - p0.x);
}
// Determine the turn direction around the corner
// formed by the points a, b, and c. Return a
// positive number for a left turn and negative
// for a right turn.
double direction(point a, point b, point c)
{
return (b.x - a.x)*(c.y - a.y) - (c.x - a.x)*(b.y - a.y);
}
int whereSmallest(point A[], int begin, int end, point p0)
{
point min = A[begin];
int where = begin;
int n;
for (n = begin + 1; n < end; n++)
if (polarAngle(A[n], p0) < polarAngle(min, p0))
{
min = A[n];
where = n;
}
return where;
}
void selectionSort(point A[], int N, point p0)
{
int n, s;
point temp;
for (n = 0; n < N; n++)
{
s = whereSmallest(A, n, N, p0);
temp = A[n];
A[n] = A[s];
A[s] = temp;
}
}
// Remove the last item from the list
void popBack(list *p)
{
int x;
x = p->size - 1;
p->A[x] = p->A[x + 1];
}
// Return the last item from the list
point getLast(list *p)
{
point value;
value = p->A[p->size];
return value;
}
// Return the next to the last item
point getNextToLast(list *p)
{
point value;
value = p->A[p->size - 1];
return value;
}
int main(int argc, const char *argv[])
{
point p0, P;
FILE *input;
list *p;
int N, n, x, y;
/*Assuming that the first piece of data in the array indicates the amount of numbers in the array then we record this number as a reference.*/
N = 0;
input = fopen("points.txt", "r");
fscanf(input, "%d", &N);
/*Now that we have an exact size requirement for our array we can use that information to create a dynamic array.*/
p = (point*)malloc(N*sizeof(point));
if (p == NULL)//As a safety precaution we want to terminate the program in case the dynamic array could not be successfully created.
return -1;
/*Now we want to collect all of the data from our file and store it in our array.*/
for (n = 0; n < N; n++)
{
fscanf(input, "%d %d", &P.x, &P.y);
p->A[n] = P.x;
p->A[n] = P.y;
}
fclose(input);
free(p);
return 0;
}
首先,你的代码无法编译,因为这个
p->A[n] = P.x;
p->A[n] = P.y;
错了,应该是
p->A[n].x = P.x;
p->A[n].y = P.y;
因为 A
的类型为 point
,您应该访问结构的成员以便为它们赋值。
但这只是问题的开始,您没有为 A
指针分配 space,所以这不会起作用。
您需要为类型list
的实例分配space,这是这样完成的
p = malloc(sizeof(*p));
然后需要初始化p
的成员,为此
p->values = malloc(N * sizeof(point));
p->capacity = N;
p->size = 0;
如您所见,space 已分配给 values
成员。
检查 fscanf()
以确保数据完整性并避免未定义的行为,如果 fscanf()
失败,您永远不会知道您的代码,并且您可能会访问导致未定义行为的未初始化变量.
在两个int
变量中捕获从文件中扫描的值,并且仅当where成功读取时才将它们复制到数组中
for (n = 0 ; ((n < N) && (fscanf(input, "%d%d", &x, &y) == 2)) ; n++)
/* check that the values were read from the file _______^ */
{
/* store them in the array */
p->values[n].x = x;
p->values[n].y = y;
p->size += 1;
}
检查文件是否打开。
我建议使用以下代码
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
typedef struct
{
int x;
int y;
} point;
typedef struct
{
int size;
int capacity;
point *values;
} list;
// Compute the polar angle in radians formed
// by the line segment that runs from p0 to p
double polarAngle(point p, point p0)
{
return atan2(p.y - p0.y, p.x - p0.x);
}
// Determine the turn direction around the corner
// formed by the points a, b, and c. Return a
// positive number for a left turn and negative
// for a right turn.
double direction(point a, point b, point c)
{
return (b.x - a.x)*(c.y - a.y) - (c.x - a.x)*(b.y - a.y);
}
int whereSmallest(point values[], int begin, int end, point p0)
{
point min = values[begin];
int where = begin;
int n;
for (n = begin + 1; n < end; n++)
if (polarAngle(values[n], p0) < polarAngle(min, p0))
{
min = values[n];
where = n;
}
return where;
}
void selectionSort(point values[], int N, point p0)
{
int n, s;
point temp;
for (n = 0; n < N; n++)
{
s = whereSmallest(values, n, N, p0);
temp = values[n];
values[n] = values[s];
values[s] = temp;
}
}
// Remove the last item from the list
void popBack(list *p)
{
int x;
x = p->size - 1;
p->values[x] = p->values[x + 1];
}
// Return the last item from the list
point getLast(list *p)
{
point value;
value = p->values[p->size];
return value;
}
// Return the next to the last item
point getNextToLast(list *p)
{
point value;
value = p->values[p->size - 1];
return value;
}
int main(int argc, const char *argv[])
{
FILE *input;
list *p;
int N, n, x, y;
/*Assuming that the first piece of data in the array indicates the amount of numbers in the array then we record this number as a reference.*/
N = 0;
input = fopen("points.txt", "r");
if (input == NULL)
return -1;
if (fscanf(input, "%d", &N) != 1)
{
fclose(input);
return -1;
}
p = malloc(sizeof(*p));
if (p == NULL)
return -1;
/*Now that we have an exact size requirement for our array we can use that information to create a dynamic array.*/
p->values = malloc(N * sizeof(point));
p->capacity = N;
p->size = 0;
if (p->values == NULL)//As a safety precaution we want to terminate the program in case the dynamic array could not be successfully created.
{
free(p);
fclose(input);
return -1;
}
/*Now we want to collect all of the data from our file and store it in our array.*/
for (n = 0 ; ((n < N) && (fscanf(input, "%d%d", &x, &y) == 2)) ; n++)
{
p->values[n].x = x;
p->values[n].y = y;
p->size += 1;
}
fclose(input);
free(p->values);
free(p);
return 0;
}
如您所见,您可以对代码进行另一项改进,它不是太重要,但可以避免使用不必要的 N
和 n
变量。
注意:在使用一个函数之前,尽量通读它的文档,这将防止各种意想不到的结果,例如fscanf()
,将帮助您理解我的修复更多。
变量p
应该是list p
。
积分数组分配为p.A = (point*)malloc(N*sizeof(point));
在填充循环中,由于 A[n] 是一个点,因此您不能将其分配给 int P.x 或 P.y。您可以直接将值放入 A[n] 点:
for (n = 0; n < N; n++)
{
fscanf(input, "%d %d", &(p.A[n].x), &(p.A[N].y));
}
应该初始化列表的大小和容量:p.capacity = N;
在成功分配内存之后 p.capacity = n;
在填充数组之后
最后你应该调用 free(p.A)
而不是 free(p)
。
我在将文件中的数据存储到我的动态数组时遇到问题。我知道我现在所拥有的是不正确的,但它只是暂时存在。我有一个文件,它的第一行基本上包含了数据行的数量。下面几行有两个并排的整数来表示一个有序对。我想将这两个整数存储到一个结构 point
中,它表示一个有序对。此外,还有一个数组,其结构位于另一个结构 list
内部,其中包含数组的大小,或当前存储在数组中的数据量以及容量,即总量数组中的 space 个。
我想将这两个整数存储到 int
类型的变量中,然后将它们存储到我的 list
结构中数组内的 point
中。
我对拥有两个结构感到非常困惑,并且不确定这是否是正确的方法。欢迎任何反馈。
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
typedef struct
{
int x;
int y;
} point;
typedef struct
{
int size;
int capacity;
point *A;
} list;
// Compute the polar angle in radians formed
// by the line segment that runs from p0 to p
double polarAngle(point p, point p0)
{
return atan2(p.y - p0.y, p.x - p0.x);
}
// Determine the turn direction around the corner
// formed by the points a, b, and c. Return a
// positive number for a left turn and negative
// for a right turn.
double direction(point a, point b, point c)
{
return (b.x - a.x)*(c.y - a.y) - (c.x - a.x)*(b.y - a.y);
}
int whereSmallest(point A[], int begin, int end, point p0)
{
point min = A[begin];
int where = begin;
int n;
for (n = begin + 1; n < end; n++)
if (polarAngle(A[n], p0) < polarAngle(min, p0))
{
min = A[n];
where = n;
}
return where;
}
void selectionSort(point A[], int N, point p0)
{
int n, s;
point temp;
for (n = 0; n < N; n++)
{
s = whereSmallest(A, n, N, p0);
temp = A[n];
A[n] = A[s];
A[s] = temp;
}
}
// Remove the last item from the list
void popBack(list *p)
{
int x;
x = p->size - 1;
p->A[x] = p->A[x + 1];
}
// Return the last item from the list
point getLast(list *p)
{
point value;
value = p->A[p->size];
return value;
}
// Return the next to the last item
point getNextToLast(list *p)
{
point value;
value = p->A[p->size - 1];
return value;
}
int main(int argc, const char *argv[])
{
point p0, P;
FILE *input;
list *p;
int N, n, x, y;
/*Assuming that the first piece of data in the array indicates the amount of numbers in the array then we record this number as a reference.*/
N = 0;
input = fopen("points.txt", "r");
fscanf(input, "%d", &N);
/*Now that we have an exact size requirement for our array we can use that information to create a dynamic array.*/
p = (point*)malloc(N*sizeof(point));
if (p == NULL)//As a safety precaution we want to terminate the program in case the dynamic array could not be successfully created.
return -1;
/*Now we want to collect all of the data from our file and store it in our array.*/
for (n = 0; n < N; n++)
{
fscanf(input, "%d %d", &P.x, &P.y);
p->A[n] = P.x;
p->A[n] = P.y;
}
fclose(input);
free(p);
return 0;
}
首先,你的代码无法编译,因为这个
p->A[n] = P.x;
p->A[n] = P.y;
错了,应该是
p->A[n].x = P.x;
p->A[n].y = P.y;
因为 A
的类型为 point
,您应该访问结构的成员以便为它们赋值。
但这只是问题的开始,您没有为 A
指针分配 space,所以这不会起作用。
您需要为类型
list
的实例分配space,这是这样完成的p = malloc(sizeof(*p));
然后需要初始化
p
的成员,为此p->values = malloc(N * sizeof(point)); p->capacity = N; p->size = 0;
如您所见,space 已分配给
values
成员。检查
fscanf()
以确保数据完整性并避免未定义的行为,如果fscanf()
失败,您永远不会知道您的代码,并且您可能会访问导致未定义行为的未初始化变量.在两个
int
变量中捕获从文件中扫描的值,并且仅当where成功读取时才将它们复制到数组中for (n = 0 ; ((n < N) && (fscanf(input, "%d%d", &x, &y) == 2)) ; n++) /* check that the values were read from the file _______^ */ { /* store them in the array */ p->values[n].x = x; p->values[n].y = y; p->size += 1; }
检查文件是否打开。
我建议使用以下代码
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
typedef struct
{
int x;
int y;
} point;
typedef struct
{
int size;
int capacity;
point *values;
} list;
// Compute the polar angle in radians formed
// by the line segment that runs from p0 to p
double polarAngle(point p, point p0)
{
return atan2(p.y - p0.y, p.x - p0.x);
}
// Determine the turn direction around the corner
// formed by the points a, b, and c. Return a
// positive number for a left turn and negative
// for a right turn.
double direction(point a, point b, point c)
{
return (b.x - a.x)*(c.y - a.y) - (c.x - a.x)*(b.y - a.y);
}
int whereSmallest(point values[], int begin, int end, point p0)
{
point min = values[begin];
int where = begin;
int n;
for (n = begin + 1; n < end; n++)
if (polarAngle(values[n], p0) < polarAngle(min, p0))
{
min = values[n];
where = n;
}
return where;
}
void selectionSort(point values[], int N, point p0)
{
int n, s;
point temp;
for (n = 0; n < N; n++)
{
s = whereSmallest(values, n, N, p0);
temp = values[n];
values[n] = values[s];
values[s] = temp;
}
}
// Remove the last item from the list
void popBack(list *p)
{
int x;
x = p->size - 1;
p->values[x] = p->values[x + 1];
}
// Return the last item from the list
point getLast(list *p)
{
point value;
value = p->values[p->size];
return value;
}
// Return the next to the last item
point getNextToLast(list *p)
{
point value;
value = p->values[p->size - 1];
return value;
}
int main(int argc, const char *argv[])
{
FILE *input;
list *p;
int N, n, x, y;
/*Assuming that the first piece of data in the array indicates the amount of numbers in the array then we record this number as a reference.*/
N = 0;
input = fopen("points.txt", "r");
if (input == NULL)
return -1;
if (fscanf(input, "%d", &N) != 1)
{
fclose(input);
return -1;
}
p = malloc(sizeof(*p));
if (p == NULL)
return -1;
/*Now that we have an exact size requirement for our array we can use that information to create a dynamic array.*/
p->values = malloc(N * sizeof(point));
p->capacity = N;
p->size = 0;
if (p->values == NULL)//As a safety precaution we want to terminate the program in case the dynamic array could not be successfully created.
{
free(p);
fclose(input);
return -1;
}
/*Now we want to collect all of the data from our file and store it in our array.*/
for (n = 0 ; ((n < N) && (fscanf(input, "%d%d", &x, &y) == 2)) ; n++)
{
p->values[n].x = x;
p->values[n].y = y;
p->size += 1;
}
fclose(input);
free(p->values);
free(p);
return 0;
}
如您所见,您可以对代码进行另一项改进,它不是太重要,但可以避免使用不必要的 N
和 n
变量。
注意:在使用一个函数之前,尽量通读它的文档,这将防止各种意想不到的结果,例如fscanf()
,将帮助您理解我的修复更多。
变量p
应该是list p
。
积分数组分配为p.A = (point*)malloc(N*sizeof(point));
在填充循环中,由于 A[n] 是一个点,因此您不能将其分配给 int P.x 或 P.y。您可以直接将值放入 A[n] 点:
for (n = 0; n < N; n++)
{
fscanf(input, "%d %d", &(p.A[n].x), &(p.A[N].y));
}
应该初始化列表的大小和容量:p.capacity = N;
在成功分配内存之后 p.capacity = n;
在填充数组之后
最后你应该调用 free(p.A)
而不是 free(p)
。