2013-01-31 109 views
0
// Struct for Country Data 
typedef struct 
{ 
    char name[50];   // Country name 
    char code[3];   // Country code 
    int population;   // Country Population 
    double lifeExp;   // Country Life expectancy 

} CountryData; 

// Struct for Dir File 
typedef struct 
{ 
    char code[50]; 
    int offSet; 

} DirData; 

// Function Declarations 
void fillCountryStructs(CountryData **dataPtr, int nLines, int fd); 
void fillDirectoryStructs(CountryData **dataPtr, DirData **director, int nLines,int fd2); 
void sortStructs(DirData **director, int nLines); 
int verifyString(char *s1, char *s2); 

// Main Function 
// - This function starts the program, get the number of lines as a 
// parameter, fills the structs and writes the data to the Country 
// File and the Directory file. 
int main(int argc, char *argv[])  // Always remember to pass an argument while executing 
{ 
    // Some variables 
    int nLines;    // The number of lines 
    char *pEnd;    // For String functions 
    FILE *Fin,*Fout;  // File pointers 
    int fd; 
    int fd2; 
    nLines = strtod(argv[1], &pEnd); 
    CountryData **countryDataPtr; // Array of structs 
    CountryData **tempStruct; 
    DirData **director; 
    char buffer[15];  

    // Allocate memory for the struct pointers 
    countryDataPtr = calloc(nLines, sizeof(CountryData*)); 
    director = calloc(nLines, sizeof(DirData*)); 
    // File Stream for "AllCountries.dat" 
    if((fd = open("AllCountries.dat", O_RDWR|O_CREAT)) ==-1) 
     err_sys("File not found...\n"); 
    // File Stream for "RandomStruct.bin" 
    if ((fd2 = open("RandomStruct.bin",O_RDWR|O_CREAT)) == -1) 
     err_sys("Failed to open binary\n"); 

    // Filling the Country stucts 
    fillCountryStructs(countryDataPtr, nLines, fd); 

    close (fd); 
    //fclose(Fin);          // Closing the file "AllCountries.dat" 
    // Writing Binary File 
    write(fd2, (countryDataPtr[0]->name[0]), sizeof(CountryData)); 

    int c=0; 
    int n=0; 
    int counter=0; 
    int tempn=0; 
    for (c=0;c<nLines;c++) 
    {  
    write(fd2, (countryDataPtr[c]->name),50); 

    write(fd2, (countryDataPtr[c]->code),4); 


    sprintf(buffer, "%d", countryDataPtr[c]->population); // Function from String.h 
    n = strlen(buffer); 
    write(fd2, buffer, n); 

    if (n<15) 
    { 
    for (counter=0;counter<(15-n);counter++) 
    { 
    write(fd2," ",1); 
    } 
    } 
    //printf("n: %i n-15: %i\n",n,(15-n)); 

    //sprintf(buffer, "%0.1f", countryDataPtr[c]->lifeExp); // Function from String.h 
    //n=((int)(countryDataPtr[c]->lifeExp)); 

    tempn=((int)(countryDataPtr[c]->lifeExp)); 

    sprintf(buffer, "%d", tempn); // Function from String.h 
    n = strlen(buffer); 
    write(fd2, buffer,n); 
    write(fd2,"\n",1); 
} 
    close (fd2); 

     printf("prueba\n"); 
    //fclose(Fout); 
    printf("RandomStruct.bin written Sucessfully\n"); 

    // Filling the Directory File 
    // File Stream for "RandomStructDir.dir" 

    if ((fd2 = open("RandomStructDir.dir",O_RDWR|O_TRUNC)) != -1) 
     err_sys("Failed to open binary\n"); 
    printf("holla0\n"); 


    fillDirectoryStructs(countryDataPtr, director, nLines, fd2); 


    printf("holla\n"); 
    sortStructs(director, nLines);         // Sorting the structs 
    printf("holla2\n"); 
    // Write the number of lines in the FIRST LINE 
    // of the Directory File 
    write(fd2, &nLines, sizeof nLines); 
    // Writing Directory File after the number of lines was written 

    //write(fd2,(director[0]->code[0]), sizeof(DirData)); 

    for (c=0;c<nLines;c++) 
    {  
     write(fd2, (director[c]->code),4); 
    } 

    close (fd2); 
    //fclose(Fout); 
    printf("RandomStructDir.dir written Sucessfully\n\n"); 

    exit(0); 
} 

// Filling the Country structs 
// - This function extracts the data from the file using strtok 
// and fills all the structs with their corresponding values. 
void fillCountryStructs(CountryData **dataPtr, int nLines, int fd) 
{ 
    int curLine = 0;  // Current line 
    int index = 0;   // The index 
    char buf[BUFSIZE];  // The Buffer with the size of BUFSIZE 
    char *tok;    // Token 
    char *pEnd;    // For the String functions 
     char ch = 'a'; // The temp character 
    int temPop; 
    double temLifeExp; 
    int num=0; 

    for(curLine = 0; curLine < nLines; curLine++) 
    { 
     // Reading each line 
    dataPtr[curLine] = (CountryData *)calloc(1, sizeof(CountryData)); 
    index = 0; 
    do 
    { 
    read(fd, &ch, 1); 
    buf[index++] = ch; 
    } 
    while(ch != '\n'); 

     // Strtoking... 
     tok = strtok(buf, ",\n"); 

     index = 1; 
     while(tok != NULL) 
     { 
      tok = strtok(NULL, ",\n"); 

      // Get the Country Code 
      if(index == 1) 
      { 
       strcpy(dataPtr[curLine]->code, tok);  // Copying code to the struct 
      //write(fd2, (tok), sizeof(CountryData[0])); 
      } 
      // Get the Country Name 
      if(index == 2) 
      { 
       strcpy(dataPtr[curLine]->name, tok);  // Copying name to the struct 
      //write(fd2, (tok), sizeof(CountryData)); 
      } 
      // Get the Country Population 
      if(index == 7) 
      { 
       temPop = (int)strtol(tok, &pEnd, 10); 
       dataPtr[curLine]->population = temPop;  // Copying population to the struct 
      } 
      // Get the Country Life expectancy 
      if(index == 8) 
      { 
      num=countchar(tok); 
      printf ("The number of characters entered is %d\n", num); 
      printf ("The character entered is %s\n",tok); 
       temLifeExp = strtod(tok, &pEnd); 
       dataPtr[curLine]->lifeExp = temLifeExp;  // Copying life expectancy to the struct 
      } 
      index++; 
     } 
    } 
} 


int countchar (char list[]) 
{ 
     int i, count = 0; 
     for (i = 0; list[i] != '\0'; i++) 
     count++; 
     return (count); 
} 



// Filling the Directory Structs 
// - This function fills the directory with the offset 
void fillDirectoryStructs(CountryData **dataPtr, DirData **director, int nLines, int fd2) 
{ 

    int i = 0; 
    for(i = 0; i < nLines; i++) 
    { 
     strcpy(director[i]->code, dataPtr[i]->code);  //It crashes in this Line 
     director[i]->offSet = 72 * (i);  
    } 

} 

// Sorting the Dir Structs 
// - This function sorts the Directory Structs. 
void sortStructs(DirData **director, int nLines) 
{ 

    int maxNumber; 
    int i; 
    DirData **temp; 
    temp = calloc(1, sizeof(DirData*)); 

    // Sorting the array of pointers! 
    for(maxNumber = nLines - 1; maxNumber > 0; maxNumber--) 
    { 
     for(i = 0; i < maxNumber; i++) 
     { 
      if((verifyString(director[i]->code, director[i+1]->code)) == 1) 
      { 
       temp[0] = director[i]; 
       director[i] = director[i+1]; 
       director[i+1] = temp[0]; 
      }   
     }   
    } 
} 

// Veryfying the strings 
// - This function compares two strings and return a specific value 
// accordingly. 
int verifyString(char *s1, char *s2) 
{ 
    int i; 
    if(strcmp(s1,s2) == 0) 
     return(0);   // They are equal 

    for(i = 0; s1[i] != 0; i++) 
    { 
     if(s1[i] > s2[i]) 
      return(1);    // s1 is greater 
     else if(s1[i] < s2[i]) 
      return(2);    // s2 is greater 
    } 

    return (2); // s2 is greater 
} 

所以這是我出於某種原因代碼,當我把這種方法,它崩潰:C指針分割故障墜毀

void fillDirectoryStructs(CountryData **dataPtr, DirData **director, int nLines, int fd2) ...

它崩潰的確切行:

strcpy(director[i]->code, dataPtr[i]->code); <-here 

它必須是關於指針的東西,或者我不知道,我試圖將右側的內容複製到左側的結構中。我打印dataPtr[0]->code並顯示正確的值。

+0

'do { read(fd,&ch,1); buf [index ++] = ch; } while(ch!='\ n');在這個循環之後,buff不會被終止。 – wildplasser

回答

1
strcpy(director[i]->code, dataPtr[i]->code);  //It crashes in this Line   

在這一點上,director[i]不指向任何東西。您需要一個director[i] = calloc(...行,就像fillCountryStructs一樣。