我正在创建一个关于座位预订的程序。我被要求对一些变量使用unsigned short和unsigned int,这就是为什么它们被设置为这样的原因。 我有一个工作正常的程序。但是当我在函数内部传递所有内容时,一切似乎都可以正常工作,但在我的结构中奇怪的值开始在整个地方保存 .. 我只想保存文件的值(从第2行 - >文件结尾)。 因为我有一个要初始化的结构,我首先要读取txt文件和numberofseats,我已经声明了这个变量(乘客)2次..在函数(local var)和主体中。 也许这会导致问题? 如果我不使用函数,一切正常!
所以有问题的代码:
#include <stdio.h>
#include <stdlib.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)!=0)
{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);
printf("%s",passenger[temp-1].fullname);
i=0;
for (p=phone;*p!='\0';p++)
{
(passenger[temp-1].phonenr[i])=*p -'0';
i++;
}
}
}
}
int main(void)
{
readfile();
PASSENGERS passenger[numberofseats];
答案 0 :(得分:1)
问题是你在函数readChar()
中声明了一个本地数组,一旦这个函数终止,它就会丢失。您需要能够将更改返回到readfile()
。为此你有一些选择。一个是您可以在main()
中声明数组,并将您的函数更改为main()
。在这种情况下,您将执行以下操作:
void readfile(PASSENGERS passenger[])
您基本上会将指针传递给存储在数组中的元素的内存位置,本地为int main()
{
PASSENGERS passenger[numberofseats];
readfile(passenger);
// more code
,函数将填充数组,从而有效地返回更改。
另一种选择是在函数中动态分配一个数组(带有main()
族),并使它返回一个像malloc()
这样的指针。如果在编译时不知道席位数,则此选项可能更合适,因此您需要在必要时动态增大或缩小阵列。但是,此选项使您无需手动管理内存,例如PASSENGERS *readfile(void)
完成后分配的内存。
由于您说您将从文件中读取free()
,后者将是更好的主意,因此您的代码将如下所示:
numberofseats
答案 1 :(得分:1)
函数x
中名为foo
的变量与函数y
中名为bar
的变量无关。换句话说:passenger
中的main
和passenger
中的readfile
是不同的变量。改变一个不会影响另一个。
你想要的可能更像是这样:
int main(void)
{
PASSENGERS passenger[numberofseats];
readfile(passenger);
^^^^^^^^^
Pass array as a pointer
....
}
和
void readfile(PASSENGERS* passenger)
{
....
// REMOVE THIS: PASSENGERS passenger[numberofseats];
}
除了那个通知:
// Global variables gets zero initialized
int i,j,numberofseats,temp;
^^^^^^^^^^^^
Becomes zero at start up
但你仍然在main中使用它:
PASSENGERS passenger[numberofseats];
这可能不是你真正想要的。
由于您尝试读取函数中的席位数,因此您确实希望使用动态内存分配。像:
PASSENGERS* readfile()
{
.....
.....
PASSENGERS* p = malloc(numberofseats * sizeof(PASSENGERS));
.....
.....
return p;
}
int main(void)
{
PASSENGERS* passenger = readfile();
.....
.....
free(passenger);
return 0;
}
如果您不想动态分配,则必须将numberofseats
的输入移动到main
,以便在声明数组之前完成。
答案 2 :(得分:0)
好的,所以我在开始进行动态分配之前所做的是指定main开头的最大座位数,然后从那里我完成了我的代码如下。我在第43,109行中有2条警告信息似乎无法修复。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int i,j,numberofseats,temp;
char platenr[8],selection;
char firstname[20],lastname[20];
char phone[11];
char *p;
typedef struct
{
char fullname[40];
unsigned short phonenr[10];
unsigned int seatnr;
}PASSENGERS;
void readfile(PASSENGERS passenger[])
{ char buff[60];
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);
for (j=0;j<numberofseats;j++)
{passenger[j].seatnr=j+1;
strcpy(passenger[j].fullname,"\0");
}
while (fgets(buff,sizeof(buff),businfo)!=0)
{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++;
}
}
}
}
void countfreeseats(PASSENGERS passenger[]){
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;
}
void changeData(PASSENGERS *target){
unsigned short tempdigit;
printf("Enter Passenger's first name:");
scanf("%s",firstname);
printf("Enter Passenger's last name:");
scanf("%s",lastname);
strcpy(target->fullname,firstname);
strcat (target->fullname, " ");
strcat(target->fullname,lastname);
printf("Enter Passenger's phone Nr:");
scanf("%s",phone);
i=0;
for (p=phone;*p!='\0';p++)
{
(target->phonenr[i])=*p -'0';
i++;
}
}
void searchpassenger(PASSENGERS passenger[], char selection)
{ char tempsel,tmpfirst[20],tmplast[20];
unsigned short tempphone[10];
if (selection == '1')
{ printf("Enter Passenger's first name:");
scanf("%s",tmpfirst);
printf("Enter Passenger's 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 (selection == '2')
{ printf("Enter Passenger's Phone Nr:");
scanf("%s",phone);
i=0;
for (p=phone;*p!='\0';p++)
{
(tempphone[i])=*p -'0';
i++;
}
for (j=0;j<numberofseats;j++)
{if (strcmp(tempphone,passenger[j].phonenr)==0)
printf("Passenger %s has Seat Nr %hd already Booked",passenger[j].fullname,passenger[j].seatnr);
}
}
}
void cancelSeat(PASSENGERS *target){
strcpy(target->fullname,"\0");
for (i=0;i<10;i++)
target->phonenr[i]=0;
printf("Seat Nr %d is now Free",temp);
}
void showList(PASSENGERS passenger[])
{
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);
}
}
void writeFile(PASSENGERS passenger[])
{
FILE * output; /* Dilosi onomatos arxeiou */
output = fopen("output.txt","w"); /*dimiourgia i eggrafi pano se iparxon arxeio me onoma output.txt, mesw tis parametrou w*/
fprintf(output,"%s %d \n",platenr,numberofseats); /* mesw tis fprintf eksagogi pinakidas kai epikefalidas "Diagramma leoforeiou" sto arxeio output.txt. Allagi grammis opou xreiazetai*/
for (i=0; i<numberofseats; i++)
{if (strcmp(passenger[i].fullname,"\0")!=0)
{
fprintf(output,"%s ",passenger[i].fullname);
fprintf(output,"%u ",passenger[i].seatnr);
for (j=0;j<10;j++)
fprintf(output,"%hu",passenger[i].phonenr[j]);
fprintf(output,"%s","\n");
}
}
fclose(output); /* Kleisimo arxeiou*/
printf("File Saved as Output.txt");
}
int main(void)
{
PASSENGERS passenger[53];
readfile(passenger);
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')
countfreeseats(passenger);
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;
printf("Do you want to search with Name (1) or Phone Nr (2)?\n");
scanf(" %c",&tempsel);
searchpassenger(passenger,tempsel);
}
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*/
{
showList(passenger);
}
} while (selection!='0');
{
writeFile(passenger);
}
}