2016-12-18 12 views
1

Я создаю программу о резервировании мест. Меня попросили использовать 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]; 
+1

Я думаю, 'main()' является неполным. Кроме того, вы знаете, что массив 'пассажир' в функции' readfile() 'и' main() 'абсолютно не имеет отношения, не так ли? –

+0

Да, я подозреваю, что это проблема. Но как я могу инициализировать пассажирский массив внутри функции, заполнить данные из файла txt и затем сохранить один и тот же массив пассажиров в основном корпусе? – baskon1

ответ

1

Проблема заключается в том, что вы объявляете локальный массив в функции readfile(), и когда эта функция завершается, она теряется. Вы должны иметь возможность вернуть изменения в main(). Для этого у вас есть несколько вариантов. Во-первых, вы можете объявить массив в main() и изменить свою функцию на void readfile(PASSENGERS passenger[]). В этом случае, вы будете делать что-то вроде этого:

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

Вам будет в основном передается указатель на ячейку памяти элементов, хранящихся в массиве, локальный для main(), а функция будет заполнить массив, эффективно возвращая изменения.

Другой вариант - динамически выделять массив (с семейством 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

переменная называется 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 

но вы использовать его в основной:

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 так это делается, прежде чем объявить массив.

+0

Нет, это моя главная проблема. Мы не знаем количество мест, пока мы не прочитаем информацию из файла bus.txt, которая появляется после объявления passeners [numberofseats] .. Поэтому я изменил свою проблему к вашим предложениям, но все еще есть проблемы, возможно, из-за этой проблемы. – baskon1

+0

@ baskon1 - см. обновление – 4386427

0

Хорошо, так что я сделал, прежде чем приступить к работе над динамическим распределением, укажите максимальное количество мест в начале основного, и оттуда я закончил свой код следующим образом. У меня есть 2 предупреждения, хотя в строках 43, 109, которые, похоже, не могут быть исправлены.

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


    } 

 Смежные вопросы

  • Нет связанных вопросов^_^