2013-12-12 41 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個字節的數據 - 這幾乎可以肯定比您的編譯器/鏈接器/操作系統正在分配。你有三種選擇:1)使「records」數組成爲全局的(把它放在更大的堆上); 2)在運行時使用適當的內存分配函數分配「records」數組;或者3)如何讓你的編譯器使堆棧更大。

+0

對於遲到的回覆,我已經參加了幾次考試。我試過這個,但是現在我的程序掛起了,並且當我將記錄全局數組時,不會輸入名稱 – user3093859

+0

您確實應該使用調試器來實現這一點:調試器向您顯示確切的代碼行時,發現崩潰很容易崩潰了,當你可以在循環中間暫停程序執行時,無限循環很容易被發現。如果由於某種原因您無法使用調試器,請查看「printf調試」以查找跟隨程序流的備用方式。 – Mark

+0

好吧我會嘗試一個調試器。謝謝您的幫助 – user3093859