Hey guys this is my first post here and i was wondering if any of you can help me figure out how to sort array of pointers to structures. Here's my code and here's my assignment if anyone is interested http://i.imgur.com/yBKnZTx.png.
嘿伙计这是我在这里的第一篇文章,我想知道你们中是否有人可以帮我弄清楚如何对结构的指针排序。这是我的代码,如果有人对http://i.imgur.com/yBKnZTx.png感兴趣,这是我的任务。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#define MAX 50
struct address
{
char name[50];
char street[50];
char citystate[50];
char zip[20];
};
int main()
{
struct address *ptr[50];
struct address tptr;
char buffer[80];
int count = 0;
for (int i = 0; i <MAX; i++)
{
ptr[i] = malloc(sizeof(struct address));
if (gets(buffer)== NULL)
{
break;
}
else
{
strcpy((*ptr[i]).name, buffer);
gets((*ptr[i]).street);
gets((*ptr[i]).citystate);
gets((*ptr[i]).zip);
free(ptr[i]);
count++;
}
}
for (int x = 0; x<count; x++)
{
for (int y = 0; y<count - 1; y++)
{
if ((*ptr[y]).zip>(*ptr[y + 1]).zip)
{
tptr = ptr[y + 1];
ptr[y + 1] = ptr[y];
ptr[y] = tptr;
}
}
}
for (int i = 0; i < count; i++)
{
puts((*ptr[i]).name);
puts((*ptr[i]).street);
puts((*ptr[i]).citystate);
puts((*ptr[i]).zip);
}
}
3 个解决方案
#1
2
Problems I see in your code:
我在你的代码中看到的问题:
-
You are using
gets
. See another SO post that addresses the poblem of usinggets
. Usefgets
instead.你正在使用获取。请参阅另一篇SO帖子,解决使用gets的问题。请改用fgets。
if (fgets(buffer, sizeof(buffer), stdin)== NULL) fgets((*ptr[i]).street, sizeof((*ptr[i]).street), stdin); fgets((*ptr[i]).citystate, sizeof((*ptr[i]).citystate), stdin); fgets((*ptr[i]).zip, sizeof((*ptr[i]).zip), stdin);
-
You are calling
free
on a pointer in the following line您在以下行中的指针上*调用
free(ptr[i]);
and continue to use it later in the code. Remove that line. Add the code to free the allocated memory at the end of the function.
并继续在代码中使用它。删除该行。添加代码以释放函数末尾的已分配内存。
for (int i = 0; i < count; i++) { free(ptr[i]); }
-
You are assigning a
struct address*
to a variable of typestruct address
in the following line:您将结构地址*分配给以下行中的struct address类型的变量:
tptr = ptr[y + 1];
and you are assigning a
struct address
to a variable of typestruct address*
in the following line:并且您将结构地址分配给以下行中的struct address *类型的变量:
ptr[y] = tptr;
both of them can be fixed by changing the type of
tptr
tostruct address*
.可以通过将tptr的类型更改为struct address *来修复它们。
struct address *tptr;
-
The following code is not appropriate for comparing two strings:
以下代码不适合比较两个字符串:
if ((*ptr[y]).zip>(*ptr[y + 1]).zip)
it only compares two pointer values. Use
它只比较两个指针值。使用
if (strcmp((*ptr[y]).zip,(*ptr[y + 1]).zip) > 0)
#2
0
- Why do you want to
free()
the allocated memory once you fetch the data from the user? - 一旦从用户那里获取数据,为什么要释放()分配的内存?
- You should
free()
the allocated memory at the end of the program, once after the printing is done. - 在打印完成后,您应该在程序结束时释放()已分配的内存。
-
struct address tptr;
should be of typestruct address *tptr;
as you are assigning the value of the pointer. - struct address tptr;应该是struct address * tptr类型;因为您正在分配指针的值。
Below are the changes: 1.
以下是变化:1。
for (int i = 0; i <MAX; i++)
{
ptr[i] = malloc(sizeof(struct address));
if (gets(buffer)== NULL)
{
free(ptr[i]); /* free the memory if data not read */
break;
}
else
{
strcpy((*ptr[i]).name, buffer);
gets((*ptr[i]).street);
gets((*ptr[i]).citystate);
gets((*ptr[i]).zip);
/* Do not free the mem here as you are bound to lose the data */
count++;
}
}
2.
2。
for (int i = 0; i < count; i++)
{
puts((*ptr[i]).name);
puts((*ptr[i]).street);
puts((*ptr[i]).citystate);
puts((*ptr[i]).zip);
free(ptr[i]); /* free the memory here */
}
PS : Using gets()
is not a good idea. Check this Do not use gets for more info
PS:使用gets()不是一个好主意。检查这个不要使用获取更多信息
#3
0
First, when dealing with pointer to structs, proper member access is with the ->
operator (e.g. ptr[i]->street
). As others have pointed out, do NOT use gets
. It is no longer part of the C library and was deprecated because it was insecure. Use fgets
or getline
instead.
首先,在处理指向结构的指针时,正确的成员访问是使用 - >运算符(例如ptr [i] - > street)。正如其他人所指出的那样,不要使用获取。它不再是C库的一部分,因为它不安全而被弃用。请改用fgets或getline。
Next, (and this is a matter of form) avoid hardcoded numbers in your code. Use #define
to set your values. This allows easy adjustment in a single place if values change.
接下来,(这是形式问题)避免代码中的硬编码数字。使用#define设置值。如果值发生变化,这可以在一个地方轻松调整。
With that, you were not far off with your code. Making only those changes, deleting the unnecessary math.h
and adding strcmp
for your sort, you can sort your structures in ascending order by zip
as follows:
有了这个,你的代码就不远了。只进行那些更改,删除不必要的math.h并为您的排序添加strcmp,您可以按zip按升序对结构进行排序,如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 50
#define MAXL 80
#define MAXZ 20
struct address {
char name[MAX];
char street[MAX];
char citystate[MAX];
char zip[MAXZ];
};
int main ()
{
struct address *ptr[MAX];
struct address *tptr;
char buffer[MAXL];
int count = 0;
for (int i = 0; i < MAX; i++) {
ptr[i] = malloc (sizeof (struct address));
if (fgets (buffer, MAXL, stdin) == NULL) {
break;
} else {
strncpy (ptr[i]->name, buffer, MAXL);
ptr[i]->name[MAX - 1] = 0;
fgets (ptr[i]->street, MAX, stdin);
fgets (ptr[i]->citystate, MAX, stdin);
fgets (ptr[i]->zip, MAXZ, stdin);
count++;
}
}
for (int x = 0; x < count; x++) {
for (int y = 0; y < (count - 1); y++) {
if (strcmp (ptr[y]->zip, ptr[y + 1]->zip) > 0) {
tptr = ptr[y + 1];
ptr[y + 1] = ptr[y];
ptr[y] = tptr;
}
}
}
for (int i = 0; i < count; i++) {
printf ("\n%s", ptr[i]->name);
printf ("%s", ptr[i]->street);
printf ("%s", ptr[i]->citystate);
printf ("%s", ptr[i]->zip);
}
}
Input
输入
$ cat dat/sortaddress.txt
some name
my street
my city, my state
55512
another name
another street
another city, another state
44412
Use/Output
使用/输出
$ ./bin/struct_address_sort <dat/sortaddress.txt
another name
another street
another city, another state
44412
some name
my street
my city, my state
55512
note: reading with fgets
or getline
will read the trailing newline
and include that in the buffer. It is a good idea to strip the newline from your strings so you don't have miscellaneous newlines at the end of your data. There are many examples on *.
注意:使用fgets或getline读取将读取尾随换行符并将其包含在缓冲区中。从字符串中删除换行符是个好主意,这样您的数据末尾就不会有其他换行符。 *上有很多例子。
#1
2
Problems I see in your code:
我在你的代码中看到的问题:
-
You are using
gets
. See another SO post that addresses the poblem of usinggets
. Usefgets
instead.你正在使用获取。请参阅另一篇SO帖子,解决使用gets的问题。请改用fgets。
if (fgets(buffer, sizeof(buffer), stdin)== NULL) fgets((*ptr[i]).street, sizeof((*ptr[i]).street), stdin); fgets((*ptr[i]).citystate, sizeof((*ptr[i]).citystate), stdin); fgets((*ptr[i]).zip, sizeof((*ptr[i]).zip), stdin);
-
You are calling
free
on a pointer in the following line您在以下行中的指针上*调用
free(ptr[i]);
and continue to use it later in the code. Remove that line. Add the code to free the allocated memory at the end of the function.
并继续在代码中使用它。删除该行。添加代码以释放函数末尾的已分配内存。
for (int i = 0; i < count; i++) { free(ptr[i]); }
-
You are assigning a
struct address*
to a variable of typestruct address
in the following line:您将结构地址*分配给以下行中的struct address类型的变量:
tptr = ptr[y + 1];
and you are assigning a
struct address
to a variable of typestruct address*
in the following line:并且您将结构地址分配给以下行中的struct address *类型的变量:
ptr[y] = tptr;
both of them can be fixed by changing the type of
tptr
tostruct address*
.可以通过将tptr的类型更改为struct address *来修复它们。
struct address *tptr;
-
The following code is not appropriate for comparing two strings:
以下代码不适合比较两个字符串:
if ((*ptr[y]).zip>(*ptr[y + 1]).zip)
it only compares two pointer values. Use
它只比较两个指针值。使用
if (strcmp((*ptr[y]).zip,(*ptr[y + 1]).zip) > 0)
#2
0
- Why do you want to
free()
the allocated memory once you fetch the data from the user? - 一旦从用户那里获取数据,为什么要释放()分配的内存?
- You should
free()
the allocated memory at the end of the program, once after the printing is done. - 在打印完成后,您应该在程序结束时释放()已分配的内存。
-
struct address tptr;
should be of typestruct address *tptr;
as you are assigning the value of the pointer. - struct address tptr;应该是struct address * tptr类型;因为您正在分配指针的值。
Below are the changes: 1.
以下是变化:1。
for (int i = 0; i <MAX; i++)
{
ptr[i] = malloc(sizeof(struct address));
if (gets(buffer)== NULL)
{
free(ptr[i]); /* free the memory if data not read */
break;
}
else
{
strcpy((*ptr[i]).name, buffer);
gets((*ptr[i]).street);
gets((*ptr[i]).citystate);
gets((*ptr[i]).zip);
/* Do not free the mem here as you are bound to lose the data */
count++;
}
}
2.
2。
for (int i = 0; i < count; i++)
{
puts((*ptr[i]).name);
puts((*ptr[i]).street);
puts((*ptr[i]).citystate);
puts((*ptr[i]).zip);
free(ptr[i]); /* free the memory here */
}
PS : Using gets()
is not a good idea. Check this Do not use gets for more info
PS:使用gets()不是一个好主意。检查这个不要使用获取更多信息
#3
0
First, when dealing with pointer to structs, proper member access is with the ->
operator (e.g. ptr[i]->street
). As others have pointed out, do NOT use gets
. It is no longer part of the C library and was deprecated because it was insecure. Use fgets
or getline
instead.
首先,在处理指向结构的指针时,正确的成员访问是使用 - >运算符(例如ptr [i] - > street)。正如其他人所指出的那样,不要使用获取。它不再是C库的一部分,因为它不安全而被弃用。请改用fgets或getline。
Next, (and this is a matter of form) avoid hardcoded numbers in your code. Use #define
to set your values. This allows easy adjustment in a single place if values change.
接下来,(这是形式问题)避免代码中的硬编码数字。使用#define设置值。如果值发生变化,这可以在一个地方轻松调整。
With that, you were not far off with your code. Making only those changes, deleting the unnecessary math.h
and adding strcmp
for your sort, you can sort your structures in ascending order by zip
as follows:
有了这个,你的代码就不远了。只进行那些更改,删除不必要的math.h并为您的排序添加strcmp,您可以按zip按升序对结构进行排序,如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 50
#define MAXL 80
#define MAXZ 20
struct address {
char name[MAX];
char street[MAX];
char citystate[MAX];
char zip[MAXZ];
};
int main ()
{
struct address *ptr[MAX];
struct address *tptr;
char buffer[MAXL];
int count = 0;
for (int i = 0; i < MAX; i++) {
ptr[i] = malloc (sizeof (struct address));
if (fgets (buffer, MAXL, stdin) == NULL) {
break;
} else {
strncpy (ptr[i]->name, buffer, MAXL);
ptr[i]->name[MAX - 1] = 0;
fgets (ptr[i]->street, MAX, stdin);
fgets (ptr[i]->citystate, MAX, stdin);
fgets (ptr[i]->zip, MAXZ, stdin);
count++;
}
}
for (int x = 0; x < count; x++) {
for (int y = 0; y < (count - 1); y++) {
if (strcmp (ptr[y]->zip, ptr[y + 1]->zip) > 0) {
tptr = ptr[y + 1];
ptr[y + 1] = ptr[y];
ptr[y] = tptr;
}
}
}
for (int i = 0; i < count; i++) {
printf ("\n%s", ptr[i]->name);
printf ("%s", ptr[i]->street);
printf ("%s", ptr[i]->citystate);
printf ("%s", ptr[i]->zip);
}
}
Input
输入
$ cat dat/sortaddress.txt
some name
my street
my city, my state
55512
another name
another street
another city, another state
44412
Use/Output
使用/输出
$ ./bin/struct_address_sort <dat/sortaddress.txt
another name
another street
another city, another state
44412
some name
my street
my city, my state
55512
note: reading with fgets
or getline
will read the trailing newline
and include that in the buffer. It is a good idea to strip the newline from your strings so you don't have miscellaneous newlines at the end of your data. There are many examples on *.
注意:使用fgets或getline读取将读取尾随换行符并将其包含在缓冲区中。从字符串中删除换行符是个好主意,这样您的数据末尾就不会有其他换行符。 *上有很多例子。