2011-05-13 3 views
10

저는 C 프로그래밍 언어로 된 간단한 파일 분할기/합병 프로그램을 만들고 있습니다. 문제는 어떤 이유로 인해 fopen이 NULL을 반환하기 때문에 내 프로그램이 fwrite 문에서 충돌합니다. 이 문제를 어떻게 해결할 수 있습니까? 할'fopen'이 NULL 포인터를 반환하는 이유는 무엇입니까?

int SplitFile(char* filename, char* output, size_t size) 
{ 
    char current_file_name[256]; 
    int file_count = 0, i = 0; 
    FILE *file = fopen(filename, "rb"); 
    printf("split %s into chunks of %d named\n", filename, size); 

    if (!file) 
     return E_BAD_SOURCE; 
    else 
    { 
     output = (char *) malloc(size * sizeof(char)); 
     if (output == NULL) 
      return E_NO_MEMORY; 
     else 
     { 
      int bytes_read = 0; 
      FILE *outFile; 
      do 
      { 
       bytes_read = fread(output, sizeof(char), size, file); 
       sprintf(current_file_name, "%s%04lu\n", "part", file_count++); 
       outFile = fopen (current_file_name, "wb"); // THIS RETURNS NULL 
       fwrite(output, sizeof(char), bytes_read, outFile); //CRASHES ON THIS LINE 
      } 
      while (bytes_read > 0) 
       ; 

      //fclose(outFile); 
     } 
    } 
    fclose(file); 
    printf("...\n"); 
    return 0; 
} 
+1

Snarky - 당신이 그것을에 기록하기 전에 열린 파일을 확인하십시오. 진짜 대답은 아마도 파일 시스템 권한이 없거나 존재하지 않는 폴더 경로에있는 것입니다. – EnabrenTane

+9

'errno'에 어떤 오류가 저장되어 있습니까? 'if (! outFile) perror ("fopen");를 추가하고 라이브러리가 실패한 이유를 알려주도록하십시오. :) – sarnold

+0

in errno 내가 fopen : 잘못된 인수 – k787

답변

9

적절한 것은 errno을 확인할 때 fopen 반환 NULL : 여기

은 C 파일입니다.

파일 시스템에 \n을 허용하지 않는 파일 시스템에 쓰기를 시도하고 있지만 사용 권한 문제 일 수 있다고 생각합니다.

+1

fopen이 NULL을 반환하면 errno를 확인하는 것이 더 적절합니다. 아마도 fwrite 대신에 fopen을 의미했을 것입니다. –

+0

내가 sprintf를 주석 처리하고 이것을 할 때; outFile = fopen ("part000", "wb"); 그것은 잘 작동합니다. – k787

+0

@Windows : 죄송합니다! 감사. – Gabe

0

는 첫 번째 실행에 쓰기 반환 NULL에 대한 fopen의 있나요?

나는 잠시 동안 파일을 열어 두지 만 닫지는 않은 것으로 나타났습니다. 에 fwrite 후 FCLOSE (OUTFILE)를 추가 할 수

봅니다 :

outFile = fopen (current_file_name , "wb");  
fwrite(output, sizeof(char), bytes_read, outFile); 
fclose(outFile) 

당신의 OS가 허용하는 것보다 더 많은 파일을 열 수 있습니다.

+0

그래, 나는 똑같은 줄 알았는데 파일을 닫았지만 작동하지 않았다. – k787

1

Gabe가 말한 것처럼 파일 이름에 개행 문자가 들어있어 Windows에서 불법입니다.

하지만 GNU 코어 유틸리티에서 split을 사용하지 마십시오. Units/Linux에 기본적으로 설치되며 GnuWin32 project에서 Windows 용으로 다운로드 할 수 있습니다.

split --suffix-length=4 --numeric-suffixes --bytes=1M - part < filename 
5

많은 이유가 있습니다 fopenNULL을 포함하여 (그러나 확실히 제한되지 않음) 반환 할 수 있습니다

  • 파일이 파일은하지 않는 모드로 열립니다
  • 존재하지 않습니다 다른 액세스 허용
  • 네트워크가 다운되었습니다.
  • 파일이 있지만 권한이 없습니다.
  • 지정한 이름의 파일이 있지만 프로세스의 현재 디렉토리가 예상 한 경로가 아니므로 상대 경로 이름이 파일을 찾아 열지 못합니다.

어떤 책임이 있는지 알아내는 방법은 errno 코드를 파헤치는 것입니다.

그러나이 특정한 오류를 해결했다고해서 fopen이 결코 NULL을 반환하지 않는다고 가정 할 수있는 것은 아닙니다. I/O 작업을 처리 할 때 코드는 단순히 실패를 예상해야합니다. I/O 작업의 성공 여부는 예측할 수 없으며 항상 실패 할 수 있습니다.

+0

공간이 부족하다면 어떨까요? 그게 NULL을 반환하게하지 않을까요? (내 질문에 수사학이 아닌 "제한되지 않는다"고 알고 있습니다.) – Nande

+0

@Nande : 새 파일을 만드는'fopen()'은 전체 디스크에서 성공할 수도 있고 성공하지 못할 수도 있습니다. 디렉토리가 확장 될 필요가 없다면 (그리고 inode가 없다면) 성공할 수 있지만 다음'fwrite()'(** 또는 **'fclose()'!)가 실패합니다. –

1

"읽기 전용"또는 "쓰기 보호 된 파일"과 같은 파일에 액세스하는 동안 파일이 없거나 일부 사용 권한 오류가 발생했기 때문에 fopen은 0 (NULL 포인터)을 반환합니다. 성공하면 파일 포인터를 핸들러로 반환합니다.

fp=fopen("c:\\ABC.txt", "r");fp=fopen("c:\\abc.txt", "r");과 같을 수 없습니다.

Linux 환경에서 \\ 대신 //을 사용하십시오.

P.S : 리눅스 및 유닉스 운영 체제 파일 이름에서대소 문자를 구분합니다.

0

유닉스에서 fopen()의 경우 fopen()에 전달 된 파일 이름 앞에 ./를 추가 할 이유가 없습니다.

0

필자의 경우 필자는 같은 파일을 while 루프에서 다시 읽었으며 닫는 것을 잊었습니다.

나는 파일을 읽고 일치를 찾는 기능을 사용하는 기능은 fclose(fp)을하기 전에 기능을 종료 return; 문을했다 : D

관련 문제