2016-12-18 6 views
1

私はプログラムを作成しています。私はいくつかの変数にunsigned shortとunsigned intを使用するように求められました。そのように設定されています。 私は問題なく動作するプログラムを持っています。しかし、私は関数内のすべてを転送すると、すべてが正常に動作するようだが、私の構造の中で奇妙な値は、すべての場所に保存され始める .. 私はファイルの値を保存したい(行2 - ファイルの終わり)。 私は初期化する構造体を持っているので、最初にtxtファイルとnumberofseatsを読み込みました。この変数(乗客)を2回宣言しています。関数(ローカル変数)と本体に.. おそらくこれは問題を引き起こしますか? 関数を使用しないと、すべて正常に動作します!バッファオーバーフローなど何か

だから、問題のあるコード:

#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

私は 'main()'が不完全だと思います。また、関数 'readfile()'と 'main()'の配列 'passenger'は絶対に関係がないことを知っていますよね? –

+0

はいこれは問題だと思われます。しかし、関数内で乗客配列を初期化し、txtファイルのデータを入力してから、同じ乗客配列を本体に保持するにはどうしたらいいですか? – baskon1

答えて

1

問題は、機能readfile()内のローカル配列を宣言しており、この関数が終了すると、それが失われることです。あなたはmain()に変更を返すことができる必要があります。そのためにいくつかの選択肢があります。 1つは、配列をmain()に宣言し、関数をvoid readfile(PASSENGERS passenger[])に変更することです。あなたは基本的にmain()にローカル配列に格納された要素のメモリ位置へのポインタを渡すされ、機能が効果的に、配列を記入します

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

:この場合、あなたはこのような何かをします変更を返します。

もう1つの方法は、関数内に配列(malloc()ファミリ)を動的に割り当て、PASSENGERS *readfile(void)のようなポインタを返すことです。このオプションは、コンパイル時に座席数がわからない場合に適しているため、必要に応じて動的に配列を拡大または縮小する必要があります。ただし、このオプションを使用すると、完了後に割り当てられたメモリをfree()のように手動で管理する負担が残ります。

あなたはあなたのコードは次のようになりますので、後者は、より良いアイデアだろう、ファイルからnumberofseatsを読み取ることを言うので:

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

機能fooxという変数がに何もしています関数baryという変数を使用します。換言すれば、passengermainおよびpassengerreadfileは異なる変数である。 1つを変更しても、他のものには影響しません。

何が欲しいのはもっとこのように、おそらくです:

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 

が、それでもあなたがメインでそれを使用する:

PASSENGERS passenger[numberofseats]; 

これはおそらくあなたが本当に望むものではありません。

関数内の座席数を読み込もうとすると、実際に動的メモリ割り当てを使用したいと思っています。同様に:あなたは、ダイナミックアロケーションを

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

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

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

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

たくない場合は、それが配列を宣言する前に行われるmainnumberofseatsの入力を移動する必要があります。

+0

いいえこれは私の主な問題です。客の番号を知らないのです。渡客の番号の後に来るbus.txtファイルから情報を読み込むまでです。[numberofseats] ..問題を修正しました。あなたの提案には、まだこの問題のために、まだ問題があります.. – baskon1

+0

@ baskon1 - 更新を参照してください – 4386427

0

私がしたことは、ダイナミックアロケーションで作業を始める前に、メインの開始位置に座席の最大数を指定することです。そこから、次のようにコードを完成させました。 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); 
    } 


    } 
関連する問題