web-dev-qa-db-ja.com

'fopen'がNULLポインターを返すのはなぜですか?

私は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 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;
}
15
k787

適切なことは、errnofopenを返したときに NULL をチェックすることです。

あなたの問題は、ファイル名に\nを許可しないファイルシステムに書き込もうとしていることですが、アクセス権の問題である可能性もあります。

13
Gabe

fopenNULLを返すことができる理由はたくさんあります(もちろん、これらに限定されません)。

  • ファイルは存在しません
  • ファイルは他のアクセスを許可しないモードで開かれています
  • ネットワークがダウンしています
  • ファイルは存在しますが、権限がありません
  • 指定した名前のファイルが存在しますが、プロセスの現在のディレクトリが予期したものではないため、相対パス名でファイルを見つけて開くことができません。

責任のあるものを見つける方法は、errnoコードを掘り下げることです。

ただし、この特定のエラーを解決したからといって、fopenNULLを返さないと仮定できるわけではありません。 I/O操作を処理する場合、コードは単に失敗を予期する必要があります。 I/O操作の成功を予測することは不可能であり、常に失敗する可能性があります。

8
JaredPar

これは、ファイルが存在しないか、「読み取り専用」や「書き込み保護」などのファイルへのアクセス中にアクセス権エラーが発生した可能性があるため、fopenは0(NULLポインター)を返します。成功すると、ハンドラとしてファイルポインタを返します。

fp=fopen("c:\\ABC.txt", "r");fp=fopen("c:\\abc.txt", "r");と同じにすることはできません。

使用する // の代わりに \\ Linux環境で。

P.S.: LinuxおよびUnixのようなオペレーティングシステムでは、ファイル名はcase-sensitiveです。

1
Sohail xIN3N

Unixでは、fopen()の場合、fopen()に渡されたファイル名に./を付加する必要はありません。

0

私の場合、それは存在しないディレクトリにファイルを作成しようとしたためです。

0
tuket

Fopen for writeは最初の実行でNULLを返しますか?

あなたが書き込み用にファイルを開いたままにしているが、閉じていないことに気づきました。

Fwriteの後にfclose(outFile)を追加してみます。

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

OSが許可するよりも多くのファイルを開くことができます。

0
Amir

私の場合、whileループで同じファイルを何度も読んでいて、閉じるのを忘れていました。

私はファイルを読み取り、一致を見つけるために関数を使用し、関数にはfclose(fp)を実行する前に関数を終了するreturn;ステートメントがありました:D

0
Riki137

ファイルに指定されたパスは、実行可能ファイルが存在する場所からチェックされます。私の場合、両方が同じ場所にあるときにcファイルでテキストファイルを開いていました。見つからないファイルのエラーを出し続けていました。実行可能ファイルのフォルダにファイルを配置し、動作を開始しました。

0
Sanya Tayal

Gabeが言ったように、あなたの問題はWindowsでは違法であるファイル名の改行です。

しかし、なぜGNUコアユーティリティのスプリットを使用しないのですか?デフォルトでUnices/Linuxにインストールされ、Windowsの場合は GnuWin32プロジェクトからダウンロードできます

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