Почему 'fopen' возвращает нулевой указатель?

Я работаю над простой программой разделения/слияния файлов на языке программирования C. Проблема в том, почему-то fopen возвращает NULL, и из-за этого моя программа сбой в fwrite заявление. Как это исправить?

вот файл C:

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 namedn", 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%04lun", "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;
}

7 ответов


правильная вещь, чтобы сделать, это проверить errno, когда fopen возвращает NULL.

Я собираюсь догадаться, что ваша проблема в том, что вы пытаетесь написать в файловую систему, которая не позволяет \n в именах файлов, но это может быть проблема с разрешениями, а также.


есть много причин fopen может возвратить NULL в том числе (но не ограничиваясь):

  • файл не существует
  • файл открыт в режиме, который не допускает других обращений
  • в сети
  • файл существует, но у вас нет разрешений
  • файл существует с именем, которое вы дали, но текущий каталог процесса не то, что вы ожидали, поэтому относительный путь не удается найти и открыть файл.

способ узнать, кто несет ответственность, - это копаться в errno код.

однако только потому, что вы разрешаете эту конкретную ошибку, не означает, что вы можете предположить fopen никогда не вернется NULL. При работе с операциями ввода-вывода ваш код просто должен ожидать сбоя. Невозможно предсказать успех операций ввода-вывода, и они всегда могут потерпеть неудачу.


Как сказал Гейб, ваша проблема-это новая строка в имени файла, которая является незаконной в Windows.

но почему бы вам просто не использовать split из GNU Core Utilities. Установленный по умолчанию на Unices / Linux, можно загрузить для Windows из проект GnuWin32.

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

это означает, что файл может не существовать или произошла ошибка разрешения при доступе к файлу, например "только для чтения" или "защищен от записи", поэтому в этих случаях fopen вернет 0 (нулевой указатель). При успешном выполнении он вернет указатель файла в качестве обработчика.

fp=fopen("c:\ABC.txt", "r"); не может быть таким же, как fp=fopen("c:\abc.txt", "r");.

использовать // вместо \ в среде Linux.

П. С.: в Linux и Unix-подобных операционных системах имена файлов регистр.


является ли fopen для write возвращаемым NULL в первом запуске?

Я заметил, что в то время как вы продолжаете открывать файлы для записи, но не закрывая их.

попробуйте добавить fclose (outFile) после fwrite:

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

возможно, вы открываете больше файлов, чем позволяет ваша ОС.


в Unix для fopen () нет причин добавлять ./ к имени файла, переданному в fopen ().


в моем случае я читал один и тот же файл снова и снова в цикле while и забыл закрыть его.

я использовал функцию для чтения файла и поиска совпадения, и функция имела return; оператор, который завершил функцию перед выполнением fclose(fp): D