Почему fopen ("any_path_name", 'r') не выдает NULL в качестве возврата? - PullRequest
2 голосов
/ 06 декабря 2011

При отладке некоторого кода я получил что-то вроде следующего:

#include<stdio.h>

int main()
{
    FILE *fb = fopen("/home/jeegar/","r");
    if(NULL == fb)
        printf("it is null");
    else
        printf("working");
}

Здесь, в fopen, я дал несколько верный путь, но не имя файла.Не должен ли fopen вернуть NULL?Но он не возвращает ноль!

Редактировать:

Если я задаю path of valid directory в fopen, то он напечатает working:

Если я дам path of invalid directory в fopen, то он напечатает it is null

Редактировать: Спецификация говорит

Upon successful completion, fopen() shall return a pointer to the object 
controlling the stream. Otherwise, a null pointer shall be returned.

, так что здесь ли код ошибкиустановлен или нет, он ДОЛЖЕН возвращать NULL

И установка кода ошибки является расширением до стандарта ISO C.

ОШИБКА ТАКЖЕ НЕ УСТАНАВЛИВАЕТСЯ ЗДЕСЬ

#include<stdio.h>
#include <errno.h>

int main()
{
errno = 0;
FILE *fb = fopen("/home/jeegar/","r");
if(fb==NULL)
    printf("its null");
else
    printf("working");


printf("Error %d \n", errno);


}

ВЫХОД IS

workingError 0 

Ответы [ 4 ]

3 голосов
/ 06 декабря 2011

Я думаю, что в Unix все (включая каталоги) считается файловым, поэтому fopen должен с ними работать.

1 голос
/ 06 декабря 2011

Как вы, наверное, очень хорошо знаете, что почти все в системе Linux - это файл, если не файл, то это процесс (исправления и замечания приветствуются :)) Каталог обрабатывается как файл, в котором перечислены другие файлы ( Справка из TLDP );поэтому открытие для чтения каталога как файла является допустимой операцией, и поэтому вы не получите никакой ошибки.Хотя попытка записи в него недопустима, поэтому, если вы откроете каталог в режиме записи или добавления, операция fopen завершится неудачно (об этом хорошо упоминались другие ответы и ссылки на документацию fopen).Большинство файловых операций, таких как операции чтения и записи в этом файловом потоке, завершатся с ошибкой, указывающей, что это каталог.Единственное использование, которое можно было найти, - это поиск размера файла (в данном случае каталога) с использованием fseek до SEEK_END & ftell (что, скорее всего, даст результат 4096).
Относительно использования errno для получения значимых сообщений вы можете использовать perror, который находится в stdio.h, и пропустить сообщение, которое будет добавлено перед сообщением об ошибке, или strerror, который находится в string.h & pass errno который находится в errno.h
Надеюсь, это поможет!

1 голос
/ 06 декабря 2011

Страница man posix man 3p fopen сообщает, в разделе ОШИБКИ :

Функция fopen () не будет работать, если:

[...]

EISDIR Именованный файл является каталогом, и для режима требуется доступ на запись .

(выделено мной).Поскольку вы не запрашиваете доступ для записи, и есть вероятность, что используемый вами путь является каталогом, функция не завершится с ошибкой.

О том, что вы можете использовать с FILE*, который ссылается на каталог, у меня естьбез понятия.

0 голосов
/ 06 декабря 2011

Как проверить, что errno?

Вы можете проверить errno, например:

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
   FILE *fp;
   errno = 0;
   fp = fopen("file.txt", "r");
   if ( errno != 0 ) 
   {
     // Here you can check your error types:
     perror("Error %d \n", errno);
     exit(1);
   }
}

Типы ошибок вы можете найти на http://pubs.opengroup.org/onlinepubs/009695399/functions/fopen.html Ошибка раздела.

...