2016-12-18 37 views
1

Ich erstelle ein Programm, über Sitzplatzreservierungen. Ich wurde gebeten, für einige der Variablen unsigned short und unsigned int zu verwenden, weshalb sie so eingestellt sind. Ich habe ein Programm, das funktioniert. Aber wenn ich alles innerhalb einer Funktion übertrage, scheint alles in Ordnung zu sein, aber innerhalb meiner Struktur beginnen merkwürdige Werte überall gespeichert zu werden .. Ich möchte nur die Werte der Datei speichern (von Zeile 2 -> das Ende der Datei). Da ich eine Struktur habe, die initialisiert werden soll, muss ich zuerst die TXT-Datei und die Anzahl der Plätze lesen, ich habe diese Variable (Passagier) 2 Mal ... innerhalb der Funktion (lokale Variable) und im Hauptteil. Vielleicht Dies verursacht das Problem? Wenn ich keine Funktion verwende funktioniert alles gut!Pufferüberlauf oder etwas anderes

So ist die problematische Code:

#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]; 
+1

Ich denke, 'main()' ist unvollständig. Sie wissen auch, dass das Array 'passagier' in der Funktion' readfile() 'und in' main() 'absolut keine Beziehung hat, richtig? –

+0

Ja, ich vermute, dass dies das Problem ist .. Aber wie kann ich Passagier-Array innerhalb der Funktion initialisieren, die Daten aus der TXT-Datei ausfüllen und dann das gleiche Passagier-Array im Hauptteil behalten? – baskon1

Antwort

1

Das Problem ist, dass Sie ein lokales Array in der Funktion readfile(), deklarieren und einmal mit dieser Funktion endet, ist es verloren. Sie müssen die Änderungen an main() zurückgeben können. Dafür haben Sie einige Möglichkeiten. Zum einen können Sie das Array unter main() deklarieren und Ihre Funktion in void readfile(PASSENGERS passenger[]) ändern. In diesem Fall werden Sie so etwas tun:

int main() 
{ 
PASSENGERS passenger[numberofseats]; 
readfile(passenger); 
// more code 

Sie werden im Grunde einen Zeiger auf die Speicherstelle der Elemente in dem Array, lokal für main() und die Funktion füllt das Array gespeichert werden vorbei, effektiv die Änderungen zurückgeben.

Eine andere Option besteht darin, ein Array (mit der malloc()-Familie) in der Funktion dynamisch zuzuordnen und einen Zeiger wie PASSENGERS *readfile(void) zurückgeben. Diese Option ist möglicherweise besser geeignet, wenn die Anzahl der Plätze zum Zeitpunkt der Kompilierung nicht bekannt ist. Sie müssen das Array bei Bedarf dynamisch vergrößern oder verkleinern. Mit dieser Option können Sie jedoch den Speicher manuell verwalten, wie z. B. free() den zugewiesenen Speicher, wenn Sie fertig sind.

Da Sie sagen, dass Sie numberofseats aus der Datei gelesen wird, würde dieser die bessere Idee sein, so dass Ihr Code etwas wie folgt aussehen:

PASSENGERS *readfile(void) 
{ 
    FILE *businfo; 
    PASSENGERS *passenger; 
    businfo = fopen ("bus.txt","r"); 
    // do the checks, read the numberofseats 
    passenger = malloc(numberofseats * sizeof *passenger); 
    // read the values, fill the array 
    fclose(businfo); // do not forget to close the file 
    return passenger; 
} 

int main() 
{ 
    PASSENGERS *passenger = readfile(); 
    // more code 
    free(passenger); 
    return 0; 
} 
1

Eine Variable namens x in Funktion foo hat nichts zu Machen Sie mit einer Variablen namens y in Funktion bar. Mit anderen Worten: passenger in main und passenger in readfile sind verschiedene Variablen. Das Ändern eines wird sich nicht auf das andere auswirken.

Was Sie wollen, ist wohl eher so:

int main(void) 
{ 
    PASSENGERS passenger[numberofseats]; 
    readfile(passenger); 
      ^^^^^^^^^ 
      Pass array as a pointer 
    .... 
} 

und

void readfile(PASSENGERS* passenger) 
{ 
    .... 

    // REMOVE THIS: PASSENGERS passenger[numberofseats]; 


} 

Neben dieser Mitteilung:

// Global variables gets zero initialized 
int i,j,numberofseats,temp; 
     ^^^^^^^^^^^^ 
     Becomes zero at start up 

aber immer noch verwenden Sie es in Haupt:

PASSENGERS passenger[numberofseats]; 

Das ist wahrscheinlich nicht das, was Sie wirklich wollen.

Da Sie versuchen, die Anzahl der Plätze in der Funktion zu lesen, scheint es, dass Sie wirklich dynamische Speicherzuweisung verwenden möchten. Wie:

PASSENGERS* readfile() 
{ 
    ..... 
    ..... 

    PASSENGERS* p = malloc(numberofseats * sizeof(PASSENGERS)); 

    ..... 
    ..... 
    return p; 
} 

int main(void) 
{ 
    PASSENGERS* passenger = readfile(); 
    ..... 
    ..... 
    free(passenger); 
    return 0; 
} 

Wenn Sie nicht dynamische Zuordnung wollen, müssen Sie die Eingabe von numberofseats in main bewegen, so wird es gemacht, bevor das Array zu deklarieren.

+0

Nein das ist mein Hauptproblem .. Dass wir die Anzahl der Plätze nicht kennen, bis wir die Info aus der bus.txt Datei gelesen haben, die nach der Erklärung der Passanten [Anzahl der Plätze] kommt. Also habe ich mein Problem geändert zu deinen Vorschlägen, aber immer noch Probleme, wahrscheinlich wegen dieses Problems .. – baskon1

+0

@ baskon1 - siehe Update – 4386427

0

Ok, also was ich getan habe, bevor ich mit der dynamischen Zuweisung anfange, gebe die maximale Anzahl der Plätze am Anfang von main an, und von dort habe ich meinen Code wie folgt beendet. Ich habe jedoch zwei Warnmeldungen in den Zeilen 43, 109, die nicht in der Lage zu beheben scheinen.

#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); 
    } 


    }