Dlaczego tryb dostępu w funkcji fopen jest podawany w postaci tekstowej?

1

Jak wiadomo, tryb dostępu do otwieranego pliku jest przekazywany do funkcji fopen jako łańcuch znaków z literami-przełącznikami. Czemu nie są np. zdefiniowane makra

#define FOPEN_READ 1
#define FOPEN_WRITE 2
#define FOPEN_APPEND 3
#define FOPEN_BINARY 4
#define FOPEN_PLUS 8 /* Tu przydała by się jakaś lepsza nazwa, ale to już inna kwestia. */

i przy otwarciu pliku należało by podać odpowiednią kombinację, np. fopen ("plik.dat", FOPEN_READ | FOPEN_BINARY) zamiast opcji w formie tekstowej, jak w jakimś JS. I właśnie zastanawiam się, dlaczego nie zostało to zrealizowane w taki sposób. Macie jakieś pomysły?

0

Nie wiem dlaczego, ale na przykład open jest definiowane z flagami. Wiem, że to nie biblioteka standardowa C, ale może warto używać innych bibliotek; ja tak robię.

5

Niektóre z implementacji fopen()fancy - np. z/OS pozwala za pomocą argumentu mode przekazać dodatkowe informacje w stylu hasła (patrz Keyword Parameters for File Mode).

Gdyby fopen() przyjmowało bitset, takie platform-specific detale trzeba by wrzucić w inne, potencjalnie bardziej niezręczne miejsce.

1

Z tego co pamiętam to w Linuxie fopen() jest glibc-owym mocno upraszczając "wrapperem" na syscall-a o nazwie open() ale to musiałbym potwierdzić. Zobacz sobie manuala do open(). Tam masz to co chcesz - czyli flagi bitowe. Możesz więc używać po prostu open() zamiast fopen().
Czyli bardzo upraszczając - open() jest niskopoziomową funkcją bliższą kernelowi.

0

Ale chyba mimo wszystko lepiej używać biblioteki standardowej - ten sam kod źródłowy skompiluje się na Windows, Unix i podobne, DOS oraz inne systemy.

0

To o czym poniżej jest napisane - nie jestem w 100% pewien:
Coś mi się wydaje, że fopen() z glibc ma dodatkowy feature w postaci buforowania a nie zawsze to buforowanie jest pożyteczne.

Nie wiem czy wszystkie operacje dostępne dla open() są też bezpośrednio dostępne dla fopen(). Zwróć uwagę, że open() zwraca deskryptor a fopen() FILE *. Jakby co to przy pomocy fileno() możesz uzyskać z FILE * numer deskryptora.

No tak - np. ioctl() na FILE * nie wykonasz, trzeba pobrać numer deskryptora pliku.

0

Moge postawić dwa domniemania

io.h nie jest w pełni przenośne.W praktyce jest dość nieźle przenośne, ale to też dlatego, ze wiele platform z 197x wymarło. Ale w latach tworzenia sie języka to było bardzo zróżnicowane, od mainframów które nawet nie miały koncepcji literek ASCII, a pliki takie-se, ta grupa funkcji to wyrażała w języku C. na dziś mocno nieprzenośna jest wyłącznie funkcja ioctl()
Integerowy handler niemal bez wyjątku jest handlerem z systemu operacyjnego (a przynajmniej klasy Unix i nowszego)
Skoro tak, nikt nie chciał nieprzenośnych flag bitowych io.h propagować na ładnie przenośne stdio.h

stdio.h zamierzone były (mi się wydaje) na różne fikuśne abstrakcje, drukowanie nie do rzeczywistego pliku itd ... To za bardzo się nie rozwinęło (widziałem to raz, demo do któregoś kompilatora, spód był nieprzenoścny, górny interfejs tak), dopiero w obiektówce C++/Java wszelkie StringPrintery itd
Ta myśl/domniemanie jest trochę zbieżna/e w tym, co pisze @Patryk27

0
Manna5 napisał(a):

Ale chyba mimo wszystko lepiej używać biblioteki standardowej - ten sam kod źródłowy skompiluje się na Windows, Unix i podobne, DOS oraz inne systemy.

  1. We mnie jest bunt, że open() wyłączasz z biblioteki standardowej, mi to nie lezy, ale nie mam ochoty grzebać w (historycznych) detalach. Wg mnie to JEST biblioteka standardowa C, choć jako nieco inna część (o czym obok)
  2. Kod nawet ioctl() sie SKOMPILUJE na innych systemach, tyle że .,. nawet wielka nadzieja na przenośność to nadal są sytuacje wymagające delikatności, choćby małe/wielkie litery, spacje w nazwach, slashe / backslashe itd ...

Widziałem wiele zaawansowanych kodów, gdzie używa się open(), read(), write() a nie fopen(), fread(), fwrite() w silnikach bazodanowych itd... dla mniejszego narzutu, i pełnej kontroli (niech w bazie danych libka i/o by buforowała po swojemu, niezgodnie i inencją twórców bazy, brrr, horror ). Tablica FILE[] z której pobiera fopen() jest ograniczona w kompilacji biblioteki (w czasach DOS dośc nisko, hardkorowcy niekiedy rekompilowali) - open() działa do limitów systemu (w DOS - ustawionych config.sys)

1 użytkowników online, w tym zalogowanych: 0, gości: 1