Obsługa plików w C - jak otwierać, zamykać i zapisywać w plikach

Jeśli wcześniej pisałeś helloworldprogram w C , znasz już podstawowe pliki I / O w C:

/* A simple hello world in C. */ #include  // Import IO functions. #include  int main() { // This printf is where all the file IO magic happens! // How exciting! printf("Hello, world!\n"); return EXIT_SUCCESS; }

Obsługa plików jest jedną z najważniejszych części programowania. W C używamy wskaźnika struktury typu pliku do zadeklarowania pliku:

FILE *fp;

C zapewnia szereg wbudowanych funkcji do wykonywania podstawowych operacji na plikach:

  • fopen() - utwórz nowy plik lub otwórz istniejący plik
  • fclose() - zamknij plik
  • getc() - czyta znak z pliku
  • putc() - zapisuje znak do pliku
  • fscanf() - odczytuje zestaw danych z pliku
  • fprintf() - zapisuje zestaw danych do pliku
  • getw() - odczytuje liczbę całkowitą z pliku
  • putw() - zapisuje liczbę całkowitą do pliku
  • fseek() - ustaw pozycję na pożądany punkt
  • ftell() - podaje aktualną pozycję w pliku
  • rewind() - ustawić pozycję do punktu początkowego

Otwieranie pliku

fopen()Funkcja służy do utworzenia pliku lub otworzyć istniejący plik:

fp = fopen(const char filename,const char mode);

Istnieje wiele trybów otwierania pliku:

  • r - otwórz plik w trybie do odczytu
  • w - otwiera lub tworzy plik tekstowy w trybie zapisu
  • a - otwiera plik w trybie dopisywania
  • r+ - otwiera plik w trybie do odczytu i zapisu
  • a+ - otwiera plik w trybie do odczytu i zapisu
  • w+ - otwiera plik w trybie do odczytu i zapisu

Oto przykład odczytu danych z pliku i zapisania do niego:

#include #include main() { FILE *fp; char ch; fp = fopen("hello.txt", "w"); printf("Enter data"); while( (ch = getchar()) != EOF) { putc(ch,fp); } fclose(fp); fp = fopen("hello.txt", "r"); while( (ch = getc(fp)! = EOF) printf("%c",ch); fclose(fp); }

Teraz możesz pomyśleć: „To po prostu drukuje tekst na ekranie. Jak wygląda ten plik IO?”

Odpowiedź nie jest na początku oczywista i wymaga pewnego zrozumienia systemu UNIX. W systemie UNIX wszystko jest traktowane jako plik, co oznacza, że ​​można z niego czytać i zapisywać.

Oznacza to, że twoja drukarka może być wyodrębniona jako plik, ponieważ wszystko, co robisz na drukarce, to pisanie na niej. Przydatne jest również myślenie o tych plikach jako o strumieniach, ponieważ jak zobaczysz później, możesz przekierować je za pomocą powłoki.

Jak to się ma do helloworldi pliku IO?

Kiedy dzwonisz printf, tak naprawdę piszesz do specjalnego pliku o nazwie stdout, który jest skrótem od standardowego wyjścia . stdoutreprezentuje standardowe wyjście określone przez twoją powłokę, którą zazwyczaj jest terminal. To wyjaśnia, dlaczego został wydrukowany na ekranie.

Istnieją dwa inne strumienie (tj. Pliki), które są dostępne z wysiłkiem, stdini stderr. stdinreprezentuje standardowe wejście , które Twoja powłoka zwykle podłącza do klawiatury. stderrreprezentuje standardowe wyjście błędów , które Twoja powłoka zwykle dołącza do terminala.

Podstawowy plik we / wy, czyli jak nauczyłem się układać rury

Dość teorii, przejdźmy do rzeczy, pisząc kod! Najprostszym sposobem, aby zapisać do pliku jest przekierowanie strumienia wyjściowego za pomocą narzędzia przekierowania wyjściowy >.

Jeśli chcesz dołączyć, możesz użyć >>:

# This will output to the screen... ./helloworld # ...but this will write to a file! ./helloworld > hello.txt

Treść hello.txtwoli, nic dziwnego, będzie

Hello, world!

Powiedzmy, że mamy inny program o nazwie greet, podobny do helloworld, który wita Cię następującym name:

#include  #include  int main() { // Initialize an array to hold the name. char name[20]; // Read a string and save it to name. scanf("%s", name); // Print the greeting. printf("Hello, %s!", name); return EXIT_SUCCESS; }

Zamiast czytać z klawiatury, możemy przekierować stdindo odczytu z pliku za pomocą <narzędzia:

# Write a file containing a name. echo Kamala > name.txt # This will read the name from the file and print out the greeting to the screen. ./greet  Hello, Kamala! # If you wanted to also write the greeting to a file, you could do so using ">".

Uwaga: te operatory przekierowania znajdują się w bashpowłokach i podobnych.

Prawdziwa okazja

Powyższe metody działały tylko w najbardziej podstawowych przypadkach. Jeśli chciałbyś robić większe i lepsze rzeczy, prawdopodobnie będziesz chciał pracować z plikami w C zamiast przez powłokę.

Aby to osiągnąć, użyjesz funkcji o nazwie fopen. Ta funkcja przyjmuje dwa parametry łańcuchowe, pierwszy to nazwa pliku, a drugi to tryb.

Tryb to w zasadzie uprawnienia rdo odczytu, wdo zapisu, ado dołączania. Możesz je również łączyć, co rwoznaczałoby, że możesz czytać i zapisywać w pliku. Jest więcej trybów, ale te są najczęściej używane.

Gdy masz FILEwskaźnik, możesz używać w zasadzie tych samych poleceń IO, których używałbyś, z wyjątkiem tego, że musisz poprzedzić je przedrostkiem, fa pierwszym argumentem będzie wskaźnik pliku. Na przykład printfwersja pliku to fprintf.

Oto program o nazwie, greetingsktóry czyta a z pliku zawierającego listę nazwisk i zapisuje pozdrowienia w innym pliku:

#include  #include  int main() { // Create file pointers. FILE *names = fopen("names.txt", "r"); FILE *greet = fopen("greet.txt", "w"); // Check that everything is OK. if (!names || !greet) { fprintf(stderr, "File opening failed!\n"); return EXIT_FAILURE; } // Greetings time! char name[20]; // Basically keep on reading untill there's nothing left. while (fscanf(names, "%s\n", name) > 0) { fprintf(greet, "Hello, %s!\n", name); } // When reached the end, print a message to the terminal to inform the user. if (feof(names)) { printf("Greetings are done!\n"); } return EXIT_SUCCESS; }

Załóżmy, że names.txtzawiera następujące elementy:

Kamala Logan Carol

Następnie po uruchomieniu greetingsplik greet.txtbędzie zawierał:

Hello, Kamala! Hello, Logan! Hello, Carol!