2012-07-12 5 views
2

이 코드는 디렉토리를 열고 파일 안의 모든 데이터 라인을 반복하고 파싱하여 계산을 수행하고 결과 데이터를 새 파일로 출력합니다 .C : 열려있는 파일이 너무 많습니다.

문제는 최대 약 1021 개의 파일 만 출력 할 수 있다는 것입니다. 모든 데이터를 출력 한 후 fopens을 닫으므로 내가 잘못하고 있는지 확실하지 않습니다.

fclose() 열려있는 파일을 닫지 않아야하나요? 같은

int main(int argc, char *argv[]) 
{ 

//sample data values 
    double lat; 
    double lon; 
    double convergence; 
    double pt_scale;   
    int zone = 54;    
    double major_axis = 6378137.0000;   
    double flattening = (1/298.2572);   
    double zoneWidth = 6;   
    double centMeridian = -177;  
    double falseEast = FALSE_EASTING;   
    double falseNorth = FALSE_NORTHING; 
    double scale = SCALE_FACTOR; 

    int max_size = 128; 
    int current_size = max_size; 
    char *pathStr = malloc(max_size); 
    char *outPathStr = malloc(max_size); 
    char coData[100]; //max length of line; 
    long firstTerm, secondTerm; //terms we will split the line into, lat, lon, elevation. 
    int counter = 0; //pos counter 
    int d = EOF; //end of file ASCII 
    char strIn[200]; 
    char* elevation; 
    char strOut[200]; 
    char dirOut[200]; //sprintf must use a actual defined buffer otherwise there will be a buffer overflow. 
    char* cchr; 
    int j; 
    _setmaxstdio(2048); 
    printf("Please enter the path of the files: \n"); 
    getUserInput(pathStr, current_size, max_size); 
    printf("Please enter the output path of the files: \n"); 
    getUserInput(outPathStr, current_size, max_size); 
    //loop through each file in the directory. Open the file, convert, then close it. 
    //we will use dirent.h as it is cross platform so we wont have to worry about sharing issues 
    DIR *dir; //new directory 
    struct dirent *ent; 
    dir = opendir(pathStr); //allcate it a path 
    if(opendir(pathStr) == NULL) 
    { printf("Error: %d (%s)\n", errno, strerror(errno));} 
    int k; 

    if(dir != NULL) 
    { 

     while((ent = readdir(dir)) != NULL) //loop through each file in the directory. 
     { 
        //open the file and loop through each line converting it then outputing it into a new file 
       if((!strcmp(ent->d_name,"..") || !strcmp(ent->d_name,".")) == 1) 
       { 
         //dont want these directories 
         continue; 
       } 
       else 
       { 
       sprintf(strIn,"%s%s",pathStr,ent->d_name); //get the file n 
       FILE *fp = fopen(strIn, "r"); 
       if(fopen(strIn, "r") == NULL) //for inputting file 
       { printf("Error: %d (%s)\n", errno, strerror(errno)); 
           getchar(); 
            break; } 

       sprintf(dirOut,"%s%d%s",outPathStr,counter,".geo"); 
       printf("%s \n",dirOut); 
       FILE *fp2 = fopen(dirOut, "w"); //for outputting file 
       if(fopen(dirOut, "w") == NULL) 
        { printf("Error: %d (%s)\n", errno, strerror(errno)); 
         getchar(); 
         break; } 


        while(fgets(coData, 100, fp) != NULL)//loop through line by line, allocate into 2 doubles and a string, pass the two coordinates and convert 
        { 
         //extract terms from coData     
         char * pch; //pointer to array pos 
         char * pend;       
         pch = strtok(coData," ");       
         j = 0; 

          while(j <= 2) //We only want to split the first three parameters. 
          { 
            //convert char array to double for co-oridinate conversion 

            if(j == 0) 
            { 
            firstTerm = atof(pch);   //latitude;   
            j++; 
            continue; 
            } 
            if(j == 1) 
            { 
            pch = strtok(NULL, " "); 
            secondTerm = atof(pch); //longitude 
            j++; 
            continue; 
            } 
            if(j == 2) 
            { 
            pch = strtok(NULL," "); 
            elevation = pch; //elevation doesnt need to be converted because it isnt used in the coordinate conversion. 
            break; 
            }                
          } 
         grid2spheroid(&lat,&lon,&convergence,&pt_scale,firstTerm,secondTerm,zone,0, major_axis,flattening,zoneWidth,centMeridian,falseEast,falseNorth,scale);            
         sprintf(strOut,"%f %f %s",lat,lon,elevation); 
         //printf("%d %d", lat, lon);       
         fputs(strOut,fp2); 


        }  //end of while   

         fclose(fp2); 
         fclose(fp); 
         counter++; 
       } 

       } 
       closedir(dir); 
    } 
    free(pathStr); //finished using the path string so we can finish the 
    free(outPathStr); 
    getchar(); 
    return 0; 

} 

    void getUserInput(char *pathStr, int current_size, int max_size) 
{ 
unsigned int i = 0; 
if(pathStr != NULL) 
    { 
       int c = EOF; 

       //get the user input and reallocate the memory size if the input it too large. 
       while((c = getchar()) != '\n' && c != EOF) //WHILE NOT END OF FILE OR NEW LINE (USER PRESSED ENTER) 
       { 
        pathStr[i++] = (char)c; 

        if(i == current_size) 
        { 
         current_size = i+max_size; 
         pathStr = realloc(pathStr, current_size); 
        }  
       } 
    } 
} 

답변

3

당신은 폐쇄되지 않은 모든 파일 ;-)

FILE *fp = fopen(strIn, "r"); 
if(fopen(strIn, "r") == NULL) //for inputting file 

은 출력에 적용됩니다. 아니,

FILE *fp = fopen(strIn, "r"); 
if(fp == NULL) //for inputting file 
{ 
    // error handling. 
+0

도움 주셔서 감사합니다. 내 멍청한 실수. 나는 이것에서 확실히 배울 것이다! – Jackter

1

번호 :

난 당신이 더 같은 것을 의미 생각! 모든 파일을 여는 중입니다 두 번 (한 번만 닫습니다)!

/* Bad! */ 
    dir = opendir(pathStr); //allcate it a path 
    if(opendir(pathStr) == NULL) 
    { printf("Error: %d (%s)\n", errno, strerror(errno));} 
    int k; 

    /* Correct */ 
    dir = opendir(pathStr); //allocate it a path 
    if(!dir) { 
    printf("Error: %d (%s)\n", errno, strerror(errno)); 
    return; 
    } 

fopen()에서도 동일한 작업을 수행하고 있습니다. 두 곳에서 :

포인터를 확인하십시오.; 두 번째로 "fopen()"을 호출하지 마십시오. 두 번이나 "opendir()"를 호출하지 마십시오!

기타 : 개폐기와 같은 줄에 코드를 넣지 마십시오. 승인?

0
dir = opendir(pathStr); //allcate it a path 
if(opendir(pathStr) == NULL) 

(...) 

FILE *fp2 = fopen(dirOut, "w"); //for outputting file 
if(fopen(dirOut, "w") == NULL) 

(...) 

FILE *fp = fopen(strIn, "r"); 
if(fopen(strIn, "r") == NULL) //for inputting file 

여기에서는 파일을 두 번만 열어 포인터를 한 번만 저장합니다. 다음과 같이 변경하십시오.

FILE *fp = fopen(strIn, "r"); 
if(fp == NULL) //for inputting file 

및 다른 하나는 같은 방식으로 변경하십시오.

관련 문제