通过函数+结构

时间:2016-12-17 20:01:12

标签: c structure

我有一个结构,一个我想要阅读的txt文件以及下面的代码可以正常工作。 我试图使函数包含大多数读取文件函数,但似乎有局部变量等问题。

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

int i,j,numberofseats,temp;
char platenr[8],selection,buff[60];
char firstname[20];
char lastname[20];
char phone[11];
char *p;
typedef struct
    {
    char fullname[40];
    unsigned short phonenr[10];
    unsigned int seatnr;
    }PASSENGERS;
int main(void)
{


FILE *businfo;                                          
businfo = fopen ("bus.txt","r");                        
if (businfo == NULL)                                                                        
{
    printf("Error Opening File, check if file bus.txt is present");
    exit(1);
}
fscanf(businfo,"%s %d",platenr, &numberofseats);
printf("Bus Licence plate Nr is: %s and number of seats is: %d", platenr, numberofseats);
PASSENGERS passenger[numberofseats];
for (j=0;j<numberofseats;j++)
    {passenger[j].seatnr=j+1;
    strcpy(passenger[j].fullname,"\0");
    }

while (fgets(buff,sizeof(buff),businfo))    
{sscanf(buff, "%s %s %d %s", firstname, lastname, &temp,phone);
strcpy(passenger[temp-1].fullname,firstname);
    strcat (passenger[temp-1].fullname, " ");
    strcat(passenger[temp-1].fullname,lastname);
    i=0;
    for (p=phone;*p!='\0';p++)       
        {
        (passenger[temp-1].phonenr[i])=*p -'0';  
        i++;
        }
}

所以在有效的代码之后,这是我创建的函数,

应定义目标,以更新结构

但*目标尚未知道,因为它位于将被函数读取的txt文件(临时变量)中。

这让我疯了!

void readfile( PASSENGERS *target, FILE *businfo){
while (fgets(buff,sizeof(buff),businfo))    
{sscanf(buff, "%s %s %d %s", firstname, lastname, &temp,phone);
strcpy(target->fullname,firstname);
    strcat (target->fullname, " ");
    strcat(target->fullname,lastname);
    i=0;
    for (p=phone;*p!='\0';p++)         
        {
        (target->phonenr[i])=*p -'0';  
        i++;
        }
}}

3 个答案:

答案 0 :(得分:0)

查看您创建的readfile函数与main函数中的纯代码之间的区别。问题是您通过索引主函数中的每个元素(passenger [temp-1])来正确填充数组乘客,但readfile函数在每次执行while循环时仅填充数组的第一个元素。

有两种解决方案:

第一个解决方案:一旦执行该函数,指针目标指向相同的元素(第一个)(使用(target + temp-1)填充每个元素 - &gt;)

void readfile( PASSENGERS *target, FILE *businfo)
{
    while (fgets(buff,sizeof(buff),businfo))    
    {
        sscanf(buff, "%s %s %d %s", firstname, lastname, &temp,phone);
        strcpy((target+temp-1)->fullname,firstname);
        strcat ((target+temp-1)->fullname, " ");
        strcat((target+temp-1)->fullname,lastname);
        i=0;
        for (p=phone;*p!='\0';p++)         
        {
           ((target+temp-1)->phonenr[i])=*p -'0';  
           i++;
        }
     }
}

第二个解决方案:一旦执行该函数,指针目标指向数组中的最后一个非null元素(在while循环结束时递增指针)

void readfile( PASSENGERS *target, FILE *businfo)
{
    while (fgets(buff,sizeof(buff),businfo))    
    {
        sscanf(buff, "%s %s %d %s", firstname, lastname, &temp,phone);
        strcpy(target->fullname,firstname);
        strcat (target->fullname, " ");
        strcat(target->fullname,lastname);
        i=0;
        for (p=phone;*p!='\0';p++)         
        {
           (target->phonenr[i])=*p -'0';  
           i++;
        }

        target = target + temp - 1;

     }
}

答案 1 :(得分:0)

感谢大家的建议!我将变量设置为全局变量,因为我将在程序中进一步使用它们。 我所做的是将大部分文件读取代码转移到我设置为没有输入和输出的函数。 我也通过将\ 0放入乘客姓名,以及从1到numberofseats的座位nr来对结构进行初始化。 我想为txt文件的每一行程序读取temp ,然后在结构PASSENGERS中更改值乘客[temp] 问题是,此时一切都被破坏了,当它运行时,混乱出现了奇怪的值..我已经包含了整个代码以防你想要运行它,但问题只是在开始..

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

int i,j,numberofseats,temp;
char platenr[8],selection,buff[60];
char firstname[20];
char lastname[20];
char phone[11];
char *p;
typedef struct
    {
    char fullname[40];
    unsigned short phonenr[10];
    unsigned int seatnr;
    }PASSENGERS;

void readfile( void)
{
    FILE *businfo;
    businfo = fopen ("bus.txt","r");
    if (businfo == NULL)
        {
        printf("Error Opening File, check if file bus.txt is present");
        exit(1);}
    else
        {
        fscanf(businfo,"%s %d",platenr, &numberofseats);
        printf("Bus Licence plate Nr is: %s and number of seats is: %d", platenr, numberofseats);
        PASSENGERS passenger[numberofseats];
        for (j=0;j<numberofseats;j++)
            {passenger[j].seatnr=j+1;
            strcpy(passenger[j].fullname,"\0");
            }
        while (fgets(buff,sizeof(buff),businfo))
            {sscanf(buff, "%s %s %d %s", firstname, lastname, &temp,phone);
            strcpy(passenger[temp-1].fullname,firstname);
            strcat (passenger[temp-1].fullname, " ");
            strcat(passenger[temp-1].fullname,lastname);
            i=0;
            for (p=phone;*p!='\0';p++)
                {
                (passenger[temp-1].phonenr[i])=*p -'0';
                i++;
                }
            }
           }
}


int main(void)
{
readfile();
PASSENGERS passenger[numberofseats];
   do{
    printf("\n\nNeo Sistima katagrafis thesewn leoforeiou\n");
    printf("Please make a selection:\n\n");
    printf("0. Exit\n");
    printf("1. Empty Seats \n");
    printf("2. Book Specific Seat \n");
    printf("3. Advanced Search of booked Seats\n");
    printf("4. Cancel Seat Booking\n");
    printf("5. Show List of booked Seats\n");
    scanf(" %c",&selection);

    if (selection=='1')
        {int freeseats = 0;
        for (j=0; j<numberofseats; j++)
            {
            strcmp(passenger[j].fullname,"\0")==0 ? freeseats = freeseats + 1 : freeseats ;}
            printf ("There are %d free seats in this bus \n", freeseats);
            printf("Seats that are available are:\n");

        for (j=0; j<numberofseats; j++)
            {if (strcmp(passenger[j].fullname,"\0")==0)
                printf ("%u\n", passenger[j].seatnr);
            }
        freeseats = 0;
        }

    else if (selection=='2')
        {
        printf("Please give seat nr (between 1 and %d) that you want to book:\n", numberofseats);
        scanf("%d",&temp);
        if (temp >numberofseats || temp <= 0)
            {printf("Error: Seat nr should be between 1 and %d", numberofseats);}
         else if (strcmp(passenger[temp-1].fullname,"\0")!=0)
            printf("Error: Seat is already booked");

        else
        changeData(&passenger[temp-1]);

        }

 else if (selection=='3')
        {
        char tempsel,tmpfirst[20],tmplast[20];
        unsigned short tempphone[10];
        int counter, checkphone;
        unsigned int tempseat;
        printf("Do you want to search with Name (1) or Phone Nr (2)?\n");
        scanf(" %c",&tempsel);

        if (tempsel == '1')
        {   printf("Enter passenger first name:");
            scanf("%s",tmpfirst);
            printf("Enter passenger last name:");
            scanf("%s",tmplast);
            strcat (tmpfirst, " ");
            strcat(tmpfirst,tmplast);
            for (j=0;j<numberofseats;j++)
            if (strcmp(passenger[j].fullname,tmpfirst)==0)
                printf ("passenger %s has seat nr #: %u\n",tmpfirst,passenger[j].seatnr);
        }
        else if (tempsel == '2')
        {   checkphone=0;
            printf("Enter passenger phonenr:");
            for (i=0;i<10;i++)
            scanf("%hu",&tempphone[i]);
            for (j=0;j<numberofseats;j++)
                {
                counter=0;
                for(i=0;i<10;i++)
                    {
                if (passenger[j].phonenr[i]==tempphone[i])
                    counter=counter+1;
                    if (counter ==10)
                    {checkphone=1;
                    tempseat=passenger[j].seatnr;
                    }}
                }
                if (checkphone==1)
                {printf ("passenger has seat #: %u\n",tempseat);
                checkphone=0;}

        }
        }



    else if (selection=='4')
        {
        printf("Please give seat nr (between 1 and %d) that you want to cancel booking:\n", numberofseats);
        scanf("%d",&temp);
        if (temp >numberofseats || temp <= 0)
            {printf("Error: Seat nr should be between 1 and %d", numberofseats);}
         else if (strcmp(passenger[temp-1].fullname,"\0")==0)
            printf("Error: Seat is already free");

        else
        cancelSeat(&passenger[temp-1]);

        }

    else if (selection=='5')                                                            /*Menu 6 - Emfanisi listas kratimenon thesewn taksinomimenon kata ayksonta arithmo*/
        {
        printf("The following seats are booked: \n Name, PhoneNr, SeatNr\n\n");                                    /*Emfanisi minimatos*/
        for (i=0; i<numberofseats; i++)
            if (strcmp(passenger[i].fullname,"\0")!=0)
            {
                printf("%s, ",passenger[i].fullname);
                for (j=0;j<10;j++)
                {printf("%hu",passenger[i].phonenr[j]);}

                printf(", %u\n",passenger[i].seatnr);
            }

        }



    } while (selection!='0');









}

答案 2 :(得分:0)

(您应该在问题中添加程序的第二个版本,而不是将其发布为答案。)

  

我所做的是将大多数文件读取代码传输到我设置为没有输入和输出的功能。   问题在于,这时一切都被破坏了,运行时一切都变得混乱,并带有奇怪的值。

这是因为在函数readfile()中,数据被读入本地数组passenger,该数组在块退出时被释放,此后程序使用同名的另一个数组,该数组未初始化。要解决此问题,请在readfile()中分配数组,以便可以从函数中返回它的(地址),并使用返回的内存。所需的更改:

void readfile( void)
{
    …
        PASSENGERS passenger[numberofseats];
        …
            {sscanf(buff, "%s %s %d %s", firstname, lastname, &temp,phone);
            …
            }
           }
}

…
readfile();
PASSENGERS passenger[numberofseats];

PASSENGERS *readfile(void)
{
    PASSENGERS *passenger;
    …
        passenger = malloc(numberofseats * sizeof *passenger);
        if (!passenger) exit(!!numberofseats);  // 0: no seats, 1: no memory
        …
        {   if (sscanf(buff, "%s %s %d %s",
                              firstname, lastname, &temp, phone) < 4) continue;
            …
        }
    }
    return passenger;
}

…
    PASSENGERS *passenger = readfile();

请注意,我们必须检查sscanf()的返回值-这很重要,因为在fscanf(businfo,"%s %d",platenr, &numberofseats)之后,第一个\n保留在输入流缓冲区中,因此第一个{ {1}}读空行。

还请注意,正如Weather Vane所写,您仍然必须处理电话号码存储。