c - 程序多次进入最后一行

时间:2015-12-15 04:21:08

标签: c arrays struct malloc

我的程序的目的是通过io重定向接收用户输入,对其进行排序,并输出没有重复记录。所有这些都使用动态分配的结构指针数组。我对输出有点麻烦。它重复最后一行,最有可能是更多的结构。提前致谢。

函数文件

#include "lab67h.h"


void getinput(address *temp[], int *s)
{
    char c[25];

    gets(c);
    while (c[0] != '\0' && *s < size)
        {
        temp[*s] = (address *) malloc(sizeof(address));

        strcpy(temp[*s]->name, c);
        gets(c);
        strcpy(temp[*s]->street, c);
        gets(c);
        strcpy(temp[*s]->city, c); 
        gets(c);
        strcpy(temp[*s]->zipcode, c); 

        (*s)++;
        gets(c); 
        }
}
void sort(address *temp[], int s)
{
    address *tempi;

    for (int a = 0; a <= s; a++)
        {
        for (int b = 0; b < (s - 1); b++)
            {
            if (convert(temp, b) > convert(temp, b + 1))
                {
                tempi = temp[b];
                temp[b] = temp[b + 1];
                temp[b + 1] = tempi;
                }
            }
        }
}
int convert(address *tempp[], int c)
{
    int i = -1, num = 0;
    char str[10];
    strcpy(str, &tempp[c]->zipcode);
    while (str[++i] != '\0')
        num = num * 10 + (str[i] - '0');
    return num;
}
void output(address *temp[], int s)
{
    for (int i = 0; i < s; i++)
    {
        puts(temp[i]->name);
        puts(temp[i]->street);
        puts(temp[i]->city);
        puts(temp[i]->zipcode);

        while (temp[i]->name == temp[i + 1]->name && temp[i]->street == temp[i + 1]->street && temp[i]->city == temp[i + 1]->city && temp[i]->zipcode == temp[i + 1]->zipcode)
        {
            free(temp[i]);
            i++;
        }
        free(temp[i]);
        i++;

    }
}

主档

#include "lab67h.h"

int  main(void)
{
    int a = 0;
    address *p[size];

    getinput(p, &a);
    sort(p, a);
    output(p, a);

    system("pause");
    return 0;
}

头文件

#ifndef LAB67H_H_INCLUDED
#define LAB67H_H_INCLUDED
#define size 50
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

typedef struct
{
    char name[25];
    char street[25];
    char city[25];
    char zipcode[25];

} address;

void getinput(address*[], int*);
void sort(address*[], int);
int convert(address*[], int);
void output(address*[], int);

#endif

输入文件

A1, A2
20294 Lorenzana Dr
Woodland Hills, CA
91364
B1, B2
19831 Henshaw St
Culver City, CA
94023
C1, C2
5142 Dumont Pl
Azusa, CA
91112
D1, D2 
20636 De Forest St
Woodland Hills, CA
91364
A1, A2
20294 Lorenzana Dr
Woodland Hills, CA
91364
E1, E2
4851 Poe Ave
Woodland Hills, CA
91364
F1, F2
20225 Lorenzana Dr
Los Angeles, CA
91111
G1, G2
20253 Lorenzana Dr
Los Angeles, CA
90005
H1, H2
5241 Del Moreno Dr
Los Angeles, CA
91110
I1, I2
5332 Felice Pl
Stevenson Ranch, CA
94135
J1, J2
5135 Quakertown Ave
Thousand Oaks, CA
91362
K1, K2
720 Eucalyptus Ave 105
Inglewood, CA
89030
L1, L2
5021 Dumont Pl
Woodland Hills, CA
91364
M1, M2
4819 Quedo Pl
Westlake Village, CA
91362
I1, I2
5332 Felice Pl
Stevenson Ranch, CA
94135
I1, I2
5332 Felice Pl
Stevenson Ranch, CA
94135
N1, N2
20044 Wells Dr
Beverly Hills, CA
90210
O1, O2
7659 Mckinley Ave 
Los Angeles, CA
90001

输出我正在

Press any key to continue . . . 
K1, K2
720 Eucalyptus Ave 105 
Inglewood, CA
89030
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
90001
G1, G2
20253 Lorenzana Dr
Los Angeles, CA
90005  
H1, H2
5241 Del Moreno Dr
Los Angeles, CA
91110
C1, C2
5142 Dumont Pl
Azusa, CA
91112
M1, M2
4819 Quedo Pl
Westlake Village, CA
913 62
D1, D2
20636 De Forest St
Woodland Hills, CA
91364
E1, E2
4851 Poe Ave
Woodland Hills, CA
91364
B1, B2
19831 Henshaw St
Culver City, CA
94023
I1, I2
5332 Felice Pl
Stevenson Ranch, CA
94135

2 个答案:

答案 0 :(得分:1)

您的代码循环,因为您不测试代码是否已达到EOF。

有关为何不应使用gets()的讨论,请参阅Why the gets() function is so dangerous it should never be used?

你需要更像的东西:

char c[25];

while (fgets(c, sizeof(c), stdin) != NULL && c[0] != '\0' && *s < size)
{
}

您还需要在循环体中使用并测试fgets()的结果。 fgets()在检测到EOF或错误时返回NULL。 (另请参阅while (!feof(file)) is always wrong,了解代码不使用或需要使用feof()的原因。)通过直接读取结构元素,可以避免额外的复制操作。您需要决定如何删除fgets()保留的换行符,而gets()则不会。如果一条线太长,你还需要考虑该怎么办 - 也许放弃多余的线。通过在循环中调用的函数可以更好地处理。

答案 1 :(得分:0)

您的输入代码运行size次,使用上次读取值(90001)填充剩余的结构。找到一种在输入数据用完时停止while循环的方法。