2013-12-12 2 views
0

Эта программа предназначена для чтения в именах файлов и их отображения, но у меня есть ошибка сегментации. Я попытался изменить многие вещи в коде, чтобы заставить его работать, но кажется, что массив для записей с именем NameRecords [150000] - моя проблема. Если я изменю значение до 74000, код будет работать, но если я увеличусь до 150000, то число, которое мне нужно, оно не будет работать. Вот мой код:У меня ошибка сегментации с моим кодом

#include <stdio.h> 
#include <stdlib.h> 
#include <ctype.h> 
#include <string.h> 
#include <math.h> 

//structure for storing names in the files 
struct NameRecord { 
    char name[31]; 
    int year; 
    int frequency; 
}; 

void allCaps(char a[]); //capitalizes all of the characters of s 
int getRawData(FILE* fp, struct NameRecord records[], int currSize);//reads in files of the two csv files 
void setYearTotals(struct NameRecord records[], int size, int yearRangeTotal[]);//calclulates the total population between the 4 year gap 
void setNameYearTotals(char theName[], struct NameRecord records[], int size, int nameTotal[]); //stores the frequency for the names in a 4 year difference 
void getPerHundredThousand(int nameTotal[], int yearRangeTotal[], double perHundredThousand[]);//gets the name frequency per hundred births for a given year range 
void printData(double perHundredThousand[]);//print the frequency of the name per years 
void graphPerHundredThousand(double perHundredThousand[]);//display the frequency in a graph like way 

main() { 
    //declarations to be used to get data from user and run functions 
    int this=0,me,size; 
    int yearTotal[1000]; 
    int range[150]; 
    int nameTotal[150]; 
    struct NameRecord records[150000]; 
    char name[30]; 
    char theName[150]; 
    char answer; 
    double thousand[150]; 
    FILE* fp; 
    do { 
     printf("Enter a name: "); 
     scanf("%[^\n]",name); 
     allCaps(name); 
     me = getRawData(fp,records,this); 
     setYearTotals(records,me,yearTotal); 
     setNameYearTotals(theName,records,me,nameTotal); 
     getPerHundredThousand(nameTotal,range,thousand); 
     printData(thousand); 
     graphPerHundredThousand(thousand); 
     printf("Do you wish to check another name (Y/N): "); 
     scanf(" %c",&answer); 
    } while(answer!='n' && answer !='N'); 
} 


void allCaps(char a[]) { 
//uses toupper function in order to capitalize the entered string 
    int i; 
    for (i = 0; i < strlen(a); i++) { 
     a[i] = toupper(a[i]); 
    } 
} 

int getRawData(FILE* fp, struct NameRecord records[], int currSize) { 
    //reads the file names from both male and female records 
    int i, run =0,temp,j; 
    currSize=0; 
    do { 
     if (run==0) { 
      fp = fopen("malebabynames.csv", "r"); 
      if(fp == NULL) 
       printf("File not found:\"malebabynames.csv!\""); 
      else { 
       while(fscanf(fp,"%d,%[^,],%d", &records[currSize].year, records[currSize].name, &records[currSize].frequency)!= -1) { //condition to continue reading until end of file is reached 
        currSize++; 
       } 
       fclose(fp); 
      } 
      run++; 
     } else if(run==1) { 
      fp = fopen("femalebabynames.csv", "r");//change to csv 
      if(fp == NULL) 
       printf("File not found:\"femalebabynames.csv!\""); 
      else { 
       while(fscanf(fp,"%d,%[^,],%d", &records[currSize].year, records[currSize].name, &records[currSize].frequency)!= -1) { 
        currSize++; 
       } 
       fclose(fp); 
      } 
     } 
    } while(run == 1); //continues till both files are read 
    //array to sort the file based on year 
    for(i=0; i < currSize; i++) { 
     for(j=0; j < currSize; j++) { 
      if (records[i].year > records[j].year) { 
       temp = records[i].year; 
       records[i].year = records[j].year; 
       records[j].year = temp; 
      } 
     } 
    } 
     return currSize; 

} 

void setYearTotals(struct NameRecord records[], int size, int yearRangeTotal[] ) { 
    //yearRangeTotal[0] holds the total population between 1921-1925. 4 year gap 
    int k,i,population=0,counter=0; 
    //loop to hold the frequency 
    for(k=0; k<size; k++){ 
     for(i=0; i < 4; i++) { 
      population += records[counter].frequency; //equal to population every 4 years 
      counter++; 
     } 
     yearRangeTotal[k] = population; 
     population=0; 
    } 

} 

void setNameYearTotals(char theName[], struct NameRecord records[], int size, int nameTotal[]) { 
    // nameTotal[0]. stores the frequency for theName for a 4 year difference 
    int i,j,counter=0; 
    //checks for the name, stores in counter and continues checking 
    for(i = 0; i < size; i++) { 
     theName[i] = &records[i].name; 
     for(j = 0; j < 4; j++) { 
      if(theName[i] == &records[j].name) 
       counter++; 
     } 
     nameTotal[i] = counter; 
     counter=0; 
    } 
} 

void getPerHundredThousand(int nameTotal[], int yearRangeTotal[], double perHundredThousand[]) { 
    int i,j,k; 
    double keep; 
    //gets the name for the frequency of births for a given year period 
    for(i=0; i < 50; i++) { 
     keep = 10000* (nameTotal[i]/yearRangeTotal[i]); 
     perHundredThousand[i] = keep; 
    } 
    printData(perHundredThousand); 
    graphPerHundredThousand(perHundredThousand); 
} 

void printData(double perHundredThousand[]) { 
    //print the data starting from 1921 till 2010 
    int year = 1921,i; 
    printf("Frequency Per Hundred Thousand Births\n"); 
    printf("=====================================\n"); 
    for(i=0; i != '\0'; i++) { 
     printf("%d - %d: %lf\n",year,year+4,perHundredThousand[i]); 
     year+=4; 
    } 
} 

void graphPerHundredThousand(double perHundredThousand[]) { 
    int i,j,temp=0,year=2010; 
    double stars,k; 
    double base; 
    //sorts the array from 2010 to 1921 to get the smallest non-zero value 
    for(i=0; i != '\0'; i++) { 
     for(j=0; j < '\0'; j++) { 
      if (perHundredThousand[i] > perHundredThousand[j]) { 
       temp = perHundredThousand[i]; 
       perHundredThousand[i] = perHundredThousand[j]; 
       perHundredThousand[j] = temp; 
      } 
     } 
    } 
    base = perHundredThousand[0]; 
    printf("    Graph\n"); 
    printf("=====================================\n"); 
    //calculates the stars needed in each year based on calculation of the smallest non-zero value calculated from upabove 
    for(i=0; i != '\0'; i++) { 
     printf("%d - %d: %lf\n",year,year-4); 
     stars=perHundredThousand[i]/base; 
     k = ceil(stars); 
     for(i=0; i < k; i++) { 
      if (k == 0) 
       break; 
      else { 
       printf("*"); 
      } 
     } 
     year-=4; 
    } 

} 
+0

Это может помочь: http://www.google.com/search?q=gdb+debugger+tutorial –

ответ

0

Вы почти наверняка переполнением стека. Сделав массив «records» предварительно определенной частью функции main(), вы помещаете в стек минимум 5850000 байт данных, что почти наверняка превышает размер стека по умолчанию, используемый вашим компилятором/компоновщиком/OS выделяет. У вас есть три варианта: 1) сделать массив «records» глобальным (который помещает его в гораздо большую кучу), 2) распределить массив «записи» во время выполнения, используя соответствующую функцию распределения памяти, или 3) выяснить как заставить ваш компилятор сделать стек больше.

+0

Простите за поздний ответ, у меня было несколько экзаменов. Я попробовал это, но теперь моя программа зависает и не переходит после ввода имени, когда я делаю записи глобальным массивом. – user3093859

+0

. Вы действительно должны использовать отладчик для этого: поиск сбоев легко, когда отладчик показывает вам точную строку кода которые разбились, и бесконечные петли легко обнаружить, когда вы можете приостановить выполнение программы в середине цикла. Если по какой-то причине вы не можете использовать отладчик, посмотрите «отладка отпечатка», чтобы найти альтернативный способ следующего потока программы. – Mark

+0

Хорошо, я попробую отладчик. Спасибо за помощь – user3093859

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