web-dev-qa-db-fra.com

Pourquoi 'fopen' renvoie-t-il un pointeur NULL?

Je travaille sur un programme simple de fractionnement/fusion de fichiers dans le langage de programmation C. Le problème est que, pour une raison quelconque, fopen renvoie la valeur NULL et, à cause de cela, mon programme se bloque à l’affichage fwrite . Comment puis-je réparer ça?

Voici le fichier 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;
}
12
k787

La bonne chose à faire est de vérifier errno lorsque fopen renvoie NULL.

Je vais deviner que votre problème est que vous essayez d'écrire sur un système de fichiers qui n'autorise pas \n dans les noms de fichiers, mais il pourrait aussi s'agir d'un problème d'autorisations.

10
Gabe

fopen peut retourner NULL pour plusieurs raisons, notamment (sans toutefois s'y limiter):

  • Le fichier n'existe pas 
  • Le fichier est ouvert dans un mode qui ne permet pas d'autres accès
  • Le réseau est en panne
  • Le fichier existe, mais vous n'avez pas les permissions
  • Un fichier existe avec le nom que vous avez donné, mais le répertoire actuel du processus ne correspond pas à ce que vous attendiez et le chemin correspondant ne parvient pas à trouver et à ouvrir le fichier.

Pour savoir qui est responsable, il faut creuser dans le code errno

Cependant, ce n'est pas parce que vous résolvez cette erreur que vous pouvez assumer que fopen ne retournera jamais NULL. Lorsqu'il s'agit d'opérations d'E/S, votre code doit simplement s'attendre à une défaillance. Il n'est pas possible de prédire le succès des opérations d'E/S et elles peuvent toujours échouer.

5
JaredPar

Cela signifie que le fichier peut ne pas exister ou qu'une erreur d'autorisation s'est produite lors de l'accès à un fichier tel que "Lecture seule" ou "Protégé en écriture". Dans ces cas, fopen renverra 0 (un pointeur NULL). En cas de succès, il retournera un pointeur de fichier en tant que gestionnaire.

fp=fopen("c:\\ABC.txt", "r"); ne peut pas être identique à fp=fopen("c:\\abc.txt", "r");.

Utilisez // au lieu de \\ dans un environnement Linux.

P.S .: Sous Linux et les systèmes d'exploitation de type Unix, les noms de fichier sont respectent la casse .

1
Sohail xIN3N

Comme Gabe l'a dit, votre problème est newline dans le nom du fichier, ce qui est illégal dans Windows.

Mais pourquoi ne pas simplement utiliser la scission de GNU Core Utilities. Installé par défaut sous Unices/Linux, peut être téléchargé pour Windows à partir du projet GnuWin32 .

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

Sous Unix, pour fopen (), il n’ya aucune raison de rajouter ./ à un nom de fichier transmis à fopen ().

0
Vinoj John Hosan

Est-ce que fopen pour write renvoie NULL lors de la première exécution?

J'ai remarqué que pendant ce temps, vous gardez les fichiers ouverts pour l'écriture mais ne les fermez pas.

Essayez d’ajouter fclose (outFile) après fwrite:

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

Il est possible que vous ouvriez plus de fichiers que votre système d'exploitation ne le permet.

0
Amir

Dans mon cas, je lisais le même fichier à nouveau en boucle et oubliai de le fermer.

J'ai utilisé une fonction pour lire le fichier et trouver une correspondance et la fonction avait une instruction return; qui a mis fin à la fonction avant de faire fclose(fp): D

0
Riki137

Le chemin indiqué pour le fichier est vérifié depuis l'emplacement de l'exécutable. Dans mon cas, j'ouvrais le fichier texte dans le fichier c alors que les deux étaient présents au même endroit. Cela donnait continuellement l'erreur du fichier introuvable. Le fichier était placé dans le dossier de l'exécutable et il commençait à fonctionner. 

0
Sanya Tayal